Mastering the Linux kernel Design (12): Slab Allocator for memory management

Source: Internet
Author: User

"Copyright Notice: respect for the original, reproduced please retain the source: blog.csdn.net/shallnet, the article only for learning Exchange, do not use for commercial purposes"

The last section concludes that for small memory area requests, if the partner system is used to allocate, there will be a lot of free space in the page can not be used, Thus producing slab allocator to handle the small memory area (dozens of or hundreds of bytes) of the request. linux slab

The kernel often uses a memory area repeatedly. For example, whenever the kernel creates a new process, it allocates memory areas for the process-related data structures (task_struct, open file objects, and so on). When the process ends, the memory area is retracted. Because of the frequent creation and revocation of processes , Linux stores frequently used pages in the cache and re-uses them.

Slab Allocator is managed based on objects, and objects of the same type are grouped into one class ( such as a process descriptor is a class ), whenever you want to apply for such an object, The slab Allocator allocates a free object to go out, and when it is released, it is re-saved to the slab allocator instead of directly returning to the partner system. For frequently requested objects, create a dedicated object of the appropriate size to handle. For infrequent objects, it is handled with a series of objects of geometric distribution size (see Common objects).

The Slab allocation pattern places objects into buffers , which are closely related to the organization and management of the buffers and the hit rate of the hardware cache, so Slab buffers are not directly composed of individual objects, but rather by a series of "chunks" ( Slab ) ", and each chunk contains several objects of the same type, either assigned or idle. In fact, the buffer is an area of main memory, dividing the area into blocks, each of which is aSlab, eachSlabConsists of one or more pages, eachSlabThe object is stored in the.

Slab Related Data structures:

Buffer data structures are represented using the Kmem_cache structure.

struct Kmem_cache {/* 1) PER-CPU data, touched during every alloc/free */struct Array_cache *array[nr_cpus];/* 2) Cache Tu Nables. 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 Gfpord er;/* force GFP flags, e.g. GFP_DMA */gfp_t gfpflags;size_t colour;/* cache colouring range */unsigned int colour_off;/* c  Olour 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 and variables contain the of Fset 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 W Ant to Size * This array to nr_node_ids slots instead of Max_numnodes * (see Kmem_cache_init ()) * We still use [Max_numnod ES] and not [1] or [0] because Cache_cache * are statically defined, so we reserve the max number of nodes. */struct kmem_list3 *nodelists[max_numnodes];/* * Do not add fields after nodelists[] */};

which struct KMEM_LIST3 Structural Body links Slab, shared cache , which is defined as follows:

/* * 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;s Truct 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 nod Es */unsigned long next_reap;/* updated without locking */int free_touched;/* updated without locking *};

The structure consists of three linked lists: slabs_partial , Slabs_full, Slabs_free , these linked lists contain buffers for all Slab,slab descriptor struct slab used to describe each slab:

/* struct Slab * * Manages the OBJS in a slab. Placed either at the beginning of mem allocated * For a slab, or allocated from the general cache. * Slabs is 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;};

A new buffer is created using the following function:

The successful creation of the function returns a pointer to the buffer created, and the following function is called to undo a buffer:

<span style= "Font-family:microsoft Yahei;" >void Kmem_cache_destroy (struct kmem_cache *cachep);</span>

None of the above two functions can be used in an interrupt context because it may sleep.

After you create a buffer, you can get the object through the following functions:

/** * Kmem_cache_alloc-allocate An object * @cachep: The cache to Allocate from. * @flags: See Kmalloc (). * * Allocate An object from the this cache.  The flags is 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;}

the function from the given point buffer returns a pointer to an object in the Cachep. If there are no idle objects in all slab of the buffer, then the slab layer must obtain a new page through Kmem_getpages (), and the parameter flags is passed to _get_free_pages ().

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

Dispose of the object using the following function:

/** * Kmem_cache_free-deallocate An object * @cachep: The cache the allocation is from. * @objp: The previously allocated object. * * Free an object which is previously allocated from the This * cache. */void kmem_cache_free (struct kmem_cache *cachep, void *OBJP) {unsigned long flags;local_irq_save (flags);d Ebug_check_ No_locks_freed (OBJP, Obj_size (Cachep)); 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);}

If you want to create many objects of the same type frequently, consider using the slab cache area.

In fact, the Kmalloc () function in the previous section is also allocated using the slab allocator.

static __always_inline void *kmalloc (size_t size, gfp_t flags) {struct Kmem_cache *cachep;void *ret;if (__builtin_ Constant_p (size)) {int i = 0;if (!size) return zero_size_ptr; #define CACHE (x) if (size <= x) goto found; else i++; #inclu De <linux/kmalloc_sizes.h> #undef cachereturn null;found: #ifdef config_zone_dmaif (Flags & GFP_DMA) Cachep = Malloc_sizes[i].cs_dmacachep;else#endifcachep = Malloc_sizes[i].cs_cachep;ret = Kmem_cache_alloc_notrace (Cachep, Flags); Trace_kmalloc (_this_ip_, ret,      size, slab_buffer_size (CACHEP), flags); return ret;} Return __kmalloc (size, flags);}
The Kfree function is implemented as follows:

/** * Kfree-free previously allocated memory * @objp: pointer returned by KMALLOC. * * If @objp is NULL and no operation is performed. * * Don ' t free memory is originally allocated by kmalloc () * or you'll run into trouble. */void kfree (const void *OBJP) {struct Kmem_cache *c;unsigned long flags;trace_kfree (_ret_ip_, OBJP); if (Unlikely (zero_ Or_null_ptr (OBJP)) Return;local_irq_save (Flags) Kfree_debugcheck (OBJP); c = Virt_to_cache (OBJP);d Ebug_check_no_ Locks_freed (OBJP, Obj_size (c));d Ebug_check_no_obj_freed (OBJP, Obj_size (c)); __cache_free (c, (void *) OBJP); Local_irq _restore (flags);}

Finally, in conjunction with the previous section,look at the selection of the allocation function:

If you need a contiguous physical page, you can use a low-level page allocator or Kmalloc ().
If you want to allocate from high-end memory, use Alloc_pages ().
If you do not need a physically contiguous page, but merely a contiguous page on a virtual address, use Vmalloc.
If you want to create and destroy many large data structures, consider establishing a slab cache.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Mastering the Linux kernel Design (12): Slab Allocator for memory management

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.