把握linux内核设计思想(十二):内存管理之slab分配器

【版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途】

slab相关数据结构:

缓冲区数据结构使用kmem_cache结构来表示。

struct kmem_cache {/* 1) per-cpu data, touched during every alloc/free */struct array_cache *array[NR_CPUS];/* 2) Cache tunables. Protected by cache_chain_mutex */unsigned int batchcount;unsigned int limit;unsigned int shared;unsigned int buffer_size;u32 reciprocal_buffer_size;/* 3) touched by every alloc & free from the backend */unsigned int flags;/* constant flags */unsigned int num;/* # of objs per slab *//* 4) cache_grow/shrink *//* order of pgs per slab (2^n) */unsigned int gfporder;/* force GFP flags, e.g. GFP_DMA */gfp_t gfpflags;size_t colour;/* cache colouring range */unsigned int colour_off;/* colour offset */struct kmem_cache *slabp_cache;unsigned int slab_size;unsigned int dflags;/* dynamic flags *//* constructor func */void (*ctor)(void *obj);/* 5) cache creation/removal */const char *name;struct list_head next;/* 6) statistics */#ifdef CONFIG_DEBUG_SLABunsigned long num_active;unsigned long num_allocations;unsigned long high_mark;unsigned long grown;unsigned long reaped;unsigned long errors;unsigned long max_freeable;unsigned long node_allocs;unsigned long node_frees;unsigned long node_overflow;atomic_t allochit;atomic_t allocmiss;atomic_t freehit;atomic_t freemiss;/* * If debugging is enabled, then the allocator can add additional * fields and/or padding to every object. buffer_size contains the total * object size including these internal fields, the following two * variables contain the offset to the user object and its size. */int obj_offset;int obj_size;#endif /* CONFIG_DEBUG_SLAB *//* * We put nodelists[] at the end of kmem_cache, because we want to size * this array to nr_node_ids slots instead of MAX_NUMNODES * (see kmem_cache_init()) * We still use [MAX_NUMNODES] and not [1] or [0] because cache_cache * is statically defined, so we reserve the max number of nodes. */struct kmem_list3 *nodelists[MAX_NUMNODES];/* * Do not add fields after nodelists[] */};

/* * The slab lists for all objects. */struct kmem_list3 {struct list_head slabs_partial;/* partial list first, better asm code */struct list_head slabs_full;struct list_head slabs_free;unsigned long free_objects;unsigned int free_limit;unsigned int colour_next;/* Per-node cache coloring */spinlock_t list_lock;struct array_cache *shared;/* shared per node */struct array_cache **alien;/* on other nodes */unsigned long next_reap;/* updated without locking */int free_touched;/* updated without locking */};

,这些链表包含缓冲区所有slab,slab描述符struct slab用于描述每个slab:

/* * struct slab * * Manages the objs in a slab. Placed either at the beginning of mem allocated * for a slab, or allocated from an general cache. * Slabs are chained into three list: fully used, partial, fully free slabs. */struct slab {struct list_head list;unsigned long colouroff;void *s_mem;/* including colour offset */unsigned int inuse;/* num of objs active in slab */kmem_bufctl_t free;unsigned short nodeid;};

一个新的缓冲区使用如下函数创建:

struct kmem_cache *kmem_cache_create (const char *name, size_t size, size_t align, unsigned long flags, void (*ctor)(void *));

函数创建成功会返回一个指向所创建缓冲区的指针;撤销一个缓冲区调用如下函数:

<span style="font-family:Microsoft YaHei;">void kmem_cache_destroy(struct kmem_cache *cachep);</span>

上面两个函数都不能在中断上下文中使用,因为它可能睡眠。

在创建来缓冲区之后,可以通过下列函数获取对象:

/** * kmem_cache_alloc – Allocate an object * @cachep: The cache to allocate from. * @flags: See kmalloc(). * * Allocate an object from this cache. The flags are only relevant * if the cache has no available objects. */void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags){void *ret = __cache_alloc(cachep, flags, __builtin_return_address(0));trace_kmem_cache_alloc(_RET_IP_, ret,obj_size(cachep), cachep->buffer_size, flags);return ret;}

<span style="font-family:Microsoft YaHei;">static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid);</span>

释放对象使用如下函数:

/** * kmem_cache_free – Deallocate an object * @cachep: The cache the allocation was from. * @objp: The previously allocated object. * * Free an object which was previously allocated from this * cache. */void kmem_cache_free(struct kmem_cache *cachep, void *objp){unsigned long flags;local_irq_save(flags);debug_check_no_locks_freed(objp, obj_size(cachep));if (!(cachep->flags & SLAB_DEBUG_OBJECTS))debug_check_no_obj_freed(objp, obj_size(cachep));__cache_free(cachep, objp);local_irq_restore(flags);trace_kmem_cache_free(_RET_IP_, objp);}

如果你要频繁的创建很多相同类型的对象,就要当考虑使用slab高速缓存区。

想像力比知识更重要

把握linux内核设计思想(十二):内存管理之slab分配器

相关文章:

你感兴趣的文章:

标签云: