内核中有些地方的内存分配是不允许失败的, 为了确保这种情况下的成功分配, 内核开发者建立了一种称为内存池的抽象; 内存池其实就是某种形式的后备高速缓存, 它试图始终保存空闲的内存, 以便在紧急状态下使用;
mempool 会分配一些内存块, 空闲且不会真的得到使用; 因此, 使用 mempool 很容易浪费大量内存; 几乎在索欧情况下, 最好不使用 mempool 而是处理可能的分配失败; 而如果系统分配内存失败会导致对系统的一致性破坏, 为了应对这种情况, 则应该使用 mempool;
内存池对象的类型为 mempool_t, 在 < Linux/mempool.h > 中定义;
创建
函数 mempool_create 用于创建内存池对象;
- mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
- mempool_free_t *free_fn, void *pool_data)
min_nr 参数标识的是内存池应始终保持的已分配对象的最少数目; 对象的实际分配和释放由 alloc_fn 和 free_fn 函数处理, 原型如下:
- typedef void * (mempool_alloc_t)(gfp_t gfp_mask, void *pool_data);
- typedef void (mempool_free_t)(void *element, void *pool_data);
mempool_create 的最后一个参数, 即 pool_data, 被传入 alloc_fn 和 free_fn;
如有必要, 我们可以为 mempool 编写特定用途的函数来处理内存分配; 但是, 通常我们仅会让内核的 slab 分配器为我们处理这个任务; 内核中有两个函数 mempool_alloc_slab 和 mempool_free_slab 和 mempool_free_slab, 它们的原型和上述内存池分配的原型匹配, 并利用 kmeme_cache_alloc 和 kmem_cache_free 处理内存分配和释放;
构造内存池的代码通常如下:
- cache = kmem_cache_careate(...);
- pool = mempool_create(MY_POOL_MININUM,mempool_alloc_slab,mempool_free_slab,cache);
分配
在建立了内存池之后, 可使用下面函数分配对象:
1 void *mempool_alloc(mempool_t *pool, gfp_t gfp_mask)
在创建 mempool 时, 就会多次调用分配函数为预先分配的对象创建内存池; 之后, 对 mempool_alloc 的调用将首先通过分配函数获得该对象; 如果分配失败, 就会返回预先分配的对象 (如果存在的话);
释放
内存对象使用完毕之后, 使用下面的函数释放对象:
1 void mempool_free(void *element, mempool_t *pool)
如果使用 mempool_free 释放一个对象, 则如果预先分配的对象数目小于要求的最低数目, 就会将对象保留在内存池中; 否则, 该对象就会返回给系统;
调整大小
可以利用下面函数来调整 mempool 的大小:
1 int mempool_resize(mempool_t *pool, int new_min_nr)
该函数调用成功, 将把内存池的大小调整为至少有 new_min_nr 个预分配对象;
销毁
如果不再需要使用内存池, 可使用下面的函数将其返回给系统:
1 void mempool_destroy(mempool_t *pool);
在销毁 mempool 之前, 必须将所有已分配的对象返回到内存池中, 否则会导致内核 oops;
来源: http://www.bubuko.com/infodetail-3263979.html