vmalloc也有对应的vfree函数。
gfp_mask参数:
gfp_mask参数可以设置很多值,一下是各个取值的用处(直接引用至LKD):
GFP_ATOMIC The allocation is high priority and must not sleep. This is the flag to use in interrupt handlers, in bottom halves, while holding a spinlock, and in other situations where you cannot sleep.
GFP_NOWAIT Like GFP_ATOMIC, except that the call will not fallback on emergency memory pools. This increases the liklihood of the memory allocation failing.
GFP_NOIO This allocation can block, but must not initiate disk I/O. This is the flag to use in block I/O code when you cannot cause more disk I/O, which might lead to some unpleasant recursion.
GFP_NOFS This allocation can block and can initiate disk I/O, if it must, but it will not initiate a filesystem operation. This is the flag to use in filesystem code when you cannot start another filesystem operation.
GFP_KERNEL This is a normal allocation and might block. This is the flag to use in process context code when it is safe to sleep. The kernel will do whatever it has to do to obtain the memory requested by the caller. This flag should be your default choice.
GFP_USER This is a normal allocation and might block. This flag is used to allocate memory for user-space processes.
GFP_HIGHUSER This is an allocation from ZONE_HIGHMEM and might block. This flag is used to allocate memory for user-space processes.
GFP_DMA This is an allocation from ZONE_DMA. Device drivers that need DMA-able memory use this flag, usually in combination with one of the preceding flags.
使用SLAB缓存分配:
当需要频繁的针对特定数据结构分配和释放内存时,为了避免反复内存分配和释放的开销,Linux内核提供了强大的内存缓存分配策略,即SLAB缓存分配。(实际上kmalloc函数就是建立在slab分配器上的!)
每个slab包含一定数量的对象,即需要被缓存的数据结构,每个slab都有三个状态:full,partial,empty。当试图从slab中分配一个object时,内核优先从partial的slab中获取对象,不行则从empty slab中,如果全部是full则创建一个新的slab。内核中管理slab缓存的组成主要有cache,slab,object,他们的关系可以用下图描述。
cache在内核中使用 kmem_cache结构来描述,包含三个链表--—slabs_full, slabs_partial, 以及slabs_empty。这些list中就包含相应状态的slab,slab在内核中的描述如下:
struct slab {
struct list_head list; /* full, partial, or empty list */
unsigned long colouroff; /* offset for the slab coloring */
void *s_mem; /* first object in the slab */
unsigned int inuse; /* allocated objects in the slab */
kmem_bufctl_t free; /* first free object, if any */
};
下列函数可以创建一个新的cache:
struct kmem_cache * kmem_cache_create(const char *name, size_t size,
size_t align, unsigned long flags, void (*ctor)(void *));
各个参数说明如下:
const char *name:cache的名称。
size_t size:cache中需要缓存的object的大小。
size_t align:slab中第一个object的偏移,一般0即可,使用标准对齐方式。
unsigned long flags:可以为缓存分配执行一些附加操作,没有的话直接0即可。
void (*ctor)(void *):cache的构造函数,你可以赋值一个函数地址,当新的page加入cache后一定会执行该构造函数。可以复赋值为NULL。
销毁一个cache时使用
int kmem_cache_destroy(struct kmem_cache *cachep);
内核提供两个函数负责从指定的cache获取和交还内存:
void * kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags);
void kmem_cache_free(struct kmem_cache *cachep, void *objp);