内存分配(第八章)

1、kmalloc函数内幕
     函数原型:
     #include <linux/slab.h>
     void *kmalloc(size_t size, int flags);
(1)flags:
     GFP_ATOMIC:
     GFP_KERNEL:
     GFP_USER:
     GFP_HIGHUSER:
     GFP_NOIO:
     GFP_NOFS:
     上面列出的分配标志可以和下面的标志“或”起来:
     __GFP_DMA:
     __GFP_HIGHMEM:
     __GFP_COLD:
     __GFP_NOWARN:
     __GFP_HIGH:
     __GFP_REPEAT:
     __GFP_NOFAIL:
     __GFP_NORETRY:
2、后备高速缓存
(1)slab分配器实现高速缓存具有kmem_cache_t类型,可以通过调用kmem_cache_create创建:
     kmem_cache_t *kmem_cache_create(const char *name, size_t size
                                                           size_t offset, unsigned long flags,
                                                           void (*constructor) (void *, kmem_cache_t *,
                                                                                        unsigned long flags),
                                                            void (*destructor) (void *, kmem_cache_t *,
                                                                                        unsigned long flags));
     flags的取值:
      SLAB_NO_REAP:
     SLAB_HWCACHE_ALIGN:
     SLAB_CACHE_DMA:
(2)一旦某个对象的高速缓存被创建,就可以调用kmem_cache_alloc从中分配内存对象:
     void *kmem_cache_alloc(kmem_cache_t *cache, int flags);
(3)释放内存对象:
     void kmem_cache_free(kmem_cache_t *cache, const void *obj);
(4)释放高速缓存:
     int kmem_cache_destroy(kmem_cache_t *cache);
3、内存池(尽量避免使用)
     建立内存池对象:
     #include <linux/mempool.h>
     mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
                                                mempool_free_t *free_fn, void *pool_data);
     typedef void *(mempool_alloc_t) (int gfp_mask, void *pool_data);
     typedef void (mempool_free_t) (void * slement, void *pool_data);
     建立内存池之后,可用如下所示分配和释放对象:
     void *mempool_alloc(mempool_t *pool, int gfp_mask);
     void mempool_tree(void *element, mempool_t *pool);
     用下面的函数来调整mempool的大小:
     int mempool_resize(mempool_t *pool, int new_min_nr, int gfp_mask);
     如果不再需要内存池,可以用下面的函数将其返回给系统:
     void mempool_destroy(mempool_t *pool);
4、get_free_page和相关函数:
(1)分配页可以使用下面的函数:
     get_zerod_page(unsigned ing flags);//返回指向新页面的指针并将页面清零。
     __get_free_page(unsigned int flags);//类似于get_zerod_page,但不清零。
     __get_free_pages(unsigned int flags, unsigned int order);
     注:需要将其返回值转换为void *的形式
(2)当函数不再使用时,可以是用下面的函数之一释放它们:
     void free_page(unsigned long addr);
     void free_pages(unsigned long addr, unsigned long order);
(3)alloc_pages接口
     Linux页分配器的核心代码是alloc_pages_node函数:
     struct page *alloc_pages_node(int nid, usigned int flags, unsigned int order);
     其中nid为NUMA节点的ID号,表示要在其中分配内存。
     这个函数的两个变种:
     struct page *alloc_pages(unsigned int flags, unsigned int order);
     struct page *alloc_page(unsigned int flags);
     释放通过上述途径分配的页面:
     void __free_page(struct page *page);
     void __free_pages(struct page *page, unsigned int order);
     void free_hot_page(struct page *page);
     void free_cold_page(struct page *page);
5、vmalloc及其辅助函数
     #include <linux/vmalloc>
     
     void *vmalloc(unsigned long size);
     void vfree(void *addr);
     void *ioremap(unsigned long offset, unsigned long size);
     void iounmap(void *addr);
注: vmalloc与__get_free_pages返回的都是虚拟内存地址。vmalloc中调用了 kmalloc(GFP_KERNEL)来获取页表的存储空间。
6、per-CPU变量
(1)per-CPU变量的声明可见于<linux/percpu.h>中,要在编译期间创建一个per-CPU变量,可以使用下面的宏:
     DEFINE_PER_CPU(type, name);
     如果该变量是一个数组,需要在type中包含数组维数。例如:    
     DEFINE_PER_CPU(int[3], my_percpu_array);
(2)关于per-CPU的一些函数:
     get_cpu_var(socket_in_use)++;
     put_cpu_var(socket_in_use);
     访问其他处理器上的副本:
     per_cpu(variable, int cpu_id);
     动态分配per-CPU变量:
     void *alloc_percpu(type);
     void *__alloc_percpu(size_t size, size_t align);
     动态分配变量的访问:
     per_cpu_ptr(void per_cpu_var, int cpu_id);
(3)Per-CPU变量可以导出给模块,但是必须使用特殊版本的宏:
     EXPORT_PER_CPU_SYMBOL(per_cpu_var);
     EXPORT_PER_CPU_SYMBOL_GPL(per_cpu_var);
     要在模块中访问这么个变量则:
     DECLARE_PRE_CPU(type, name);
 7、获得大的缓冲区:
     #include <linux/bootmem.h>
     void *alloc_bootmem(unsigned long size);
     void *alloc_bootmem_low(unsigned long size);
     void *alloc_bootmem_pages(unsigned long size);
     void *alloc_bootmem_low_pages(unsigned long size);
     释放内存:
     void free_bootmem(unsigned long addr, unsigned long size);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值