Object caches

The slab allocator provides function interfaces for setting up slab caches, which can be owned by a kernel service or a subsystem. Such caches are considered private since they are local to kernel services (or a kernel subsystem) like device drivers, file systems, process scheduler, and so on. This facility is used by most kernel subsystems to set up object caches and pool intermittently needed data structures. Most data structures we've encountered so far (since Chapter 1, Comprehending Processes, Address Space, and Threads) including process descriptor, signal descriptor, page descriptor, and so on are maintained in such object pools. The pseudo file /proc/slabinfo shows the status of object caches:

# cat /proc/slabinfo 
slabinfo - version: 2.1
# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
sigqueue 100 100 160 25 1 : tunables 0 0 0 : slabdata 4 4 0
bdev_cache 76 76 832 19 4 : tunables 0 0 0 : slabdata 4 4 0
kernfs_node_cache 28594 28594 120 34 1 : tunables 0 0 0 : slabdata 841 841 0
mnt_cache 489 588 384 21 2 : tunables 0 0 0 : slabdata 28 28 0
inode_cache 15932 15932 568 28 4 : tunables 0 0 0 : slabdata 569 569 0
dentry 89541 89817 192 21 1 : tunables 0 0 0 : slabdata 4277 4277 0
iint_cache 0 0 72 56 1 : tunables 0 0 0 : slabdata 0 0 0
buffer_head 53079 53430 104 39 1 : tunables 0 0 0 : slabdata 1370 1370 0
vm_area_struct 41287 42400 200 20 1 : tunables 0 0 0 : slabdata 2120 2120 0
files_cache 207 207 704 23 4 : tunables 0 0 0 : slabdata 9 9 0
signal_cache 420 420 1088 30 8 : tunables 0 0 0 : slabdata 14 14 0
sighand_cache 289 315 2112 15 8 : tunables 0 0 0 : slabdata 21 21 0
task_struct 750 801 3584 9 8 : tunables 0 0 0 : slabdata 89 89 0

The kmem_cache_create() routine sets up a new cache as per the parameter passed. On success, it returns the address to the cache descriptor structure of type kmem_cache:

/*
* kmem_cache_create - Create a cache.
* @name: A string which is used in /proc/slabinfo to identify this cache.
* @size: The size of objects to be created in this cache.
* @align: The required alignment for the objects.
* @flags: SLAB flags
* @ctor: A constructor for the objects.
*
* Returns a ptr to the cache on success, NULL on failure.
* Cannot be called within a interrupt, but can be interrupted.
* The @ctor is run when new pages are allocated by the cache.
*
*/
struct kmem_cache * kmem_cache_create(const char *name, size_t size, size_t align,
unsigned long flags, void (*ctor)(void *))

The cache is created by allocating free page frames (from buddy system), and data objects of size specified (second argument) are populated. Though each cache starts by hosting a fixed number of data objects during creation, they can grow dynamically when required to accommodate more number of data objects. Data structures can be complicated (we have encountered a few), and can contain varied elements such as list headers, sub-objects, arrays, atomic counters, bit-fields, and so on. Setting up each object might require all its fields to be initialized to the default state; this can be achieved through an initializer routine assigned to a *ctor function pointer (last argument). The initializer is called for each new object allocated, both during cache creation and when it grows to add more free objects. However, for simple objects, a cache can be created without an initializer.

Following is a sample code snippet that shows the usage of kmem_cache_create():

/* net/core/skbuff.c */

struct kmem_cache *skbuff_head_cache;
skbuff_head_cache = kmem_cache_create("skbuff_head_cache",sizeof(struct sk_buff), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);

Flags are used to enable debug checks, and enhance the performance of access operations on cache by aligning objects with the hardware cache. The following flag constants are supported:

 SLAB_CONSISTENCY_CHECKS /* DEBUG: Perform (expensive) checks o alloc/free */
SLAB_RED_ZONE /* DEBUG: Red zone objs in a cache */
SLAB_POISON /* DEBUG: Poison objects */
SLAB_HWCACHE_ALIGN /* Align objs on cache lines */
SLAB_CACHE_DMA /* Use GFP_DMA memory */
SLAB_STORE_USER /* DEBUG: Store the last owner for bug hunting */
SLAB_PANIC /* Panic if kmem_cache_create() fails */

Subsequently, objects can be allocated and released through relevant functions. Upon release, objects are put back into the free list of the cache, making them available for reuse; this results in a possible performance boost, particularly when objects are cache hot:

/**
* kmem_cache_alloc - Allocate an object
* @cachep: The cache to allocate from.
* @flags: GFP mask.
*
* 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);

/**
* kmem_cache_alloc_node - Allocate an object on the specified node
* @cachep: The cache to allocate from.
* @flags: GFP mask.
* @nodeid: node number of the target node.
*
* Identical to kmem_cache_alloc but it will allocate memory on the given
* node, which can improve the performance for cpu bound structures.
*
* Fallback to other node is possible if __GFP_THISNODE is not set.
*/
void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid);

/**
* 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);

kmem caches can be destroyed when all hosted data objects are free (not in use), by calling kmem_cache_destroy().

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.189.177