Analysis of Linux memory pool source code

Source: Internet
Author: User
Tags function prototype

The Memery pool technique is to apply a certain number of memory blocks that are equal in size (typically) to be reserved before actually using memory. When there is a new memory requirement, a portion of the memory block is separated from the memory pool, and if the memory block is not enough, then continue to request new memory. One notable advantage of this is that memory fragmentation is avoided as much as possible, resulting in improved memory allocation efficiency.

Not only is it widely used in user-state applications, but it is also widely used in the Linux kernel, where memory allocations in the kernel are not allowed to fail. As a way to ensure allocation in these cases, the kernel developer creates an abstraction known as a memory pool (or "Mempool"), in which the memory pool in the kernel is really just equivalent to the fallback cache, and it tries to keep an idle memory list for emergency use. While there is usually a memory requirement or a direct allocation from public memory, this is a bit of a suspicion of hogging memory, but it can fundamentally guarantee that critical applications will still be successful in memory-intensive applications.

Below look at the kernel memory pool source code, kernel memory pool source in, implementation is very concise, describes the structure of the memory pool mempool_t in the header file, the structure is described as follows:

typedef struct MEMPOOL_S {
spinlock_t lock; /* Protect the memory pool spin lock */
int min_nr; /* The minimum number of elements that can be allocated in the memory pool */
int curr_nr; /* remaining number of elements to allocate */
void **elements; /* Pointer to element pool */
void *pool_data; /* Memory source, which is the true allocation of elements in the pool */
mempool_alloc_t *alloc; /*www.qixoo.qixoo.com method of assigning elements */
mempool_free_t *free; /* Method of retrieving elements */
wait_queue_head_t wait; /* Blocked waiting queue */
} mempool_t;

The function prototype of the memory pool creation function mempool_create is as follows:

mempool_t *mempool_create (int min_nr, mempool_alloc_t *alloc_fn,
mempool_free_t *free_fn, void *pool_data)
{
Return Mempool_create_node (MIN_NR,ALLOC_FN,FREE_FN, pool_data,-1);
}

Function prototypes specify how many elements a memory pool can hold, how to request an element, how to dispose of an element, and an optional memory source (usually a cache) that automatically calls the Alloc method when the memory pool object is created to populate the memory pool with MIN_NR elements allocated from Pool_data.

The prototype of the memory pool's release function Mempool_destory function is simple, and it should also be guessed that the element object is removed from the pool, then released to Pool_data, and finally the pool object is released as follows:

void Mempool_destroy (mempool_t *pool)
{
while (POOL->CURR_NR) {
void *element = Remove_element (pool);
Pool->free (element, pool->pool_data);
}
Kfree (pool->elements);
Kfree (pool);
}

It is important to note that the memory pool allocates and reclaims the objects ' functions: Mempool_alloc and Mempool_free. The function of Mempool_alloc is to request/get an object from the specified memory pool, and the functions are prototyped as follows:

void * Mempool_alloc (mempool_t *pool, gfp_t gfp_mask) {
......
element = Pool->alloc (gfp_temp, pool->pool_data);
if (likely (element! = NULL))
return element;

Spin_lock_irqsave (&pool->lock, flags);
if (likely (POOL->CURR_NR)) {
element = Remove_element (pool);/* Extracts an object from the memory pool */
Spin_unlock_irqrestore (&pool->lock, flags);
/* paired with $ in mempool_free (), read comment there */
SMP_WMB ();
return element;
}
......

}

The function first applies the element object from the Pool_data, and when it is not pool_data from the pool, the object is extracted from the pools, so you can discover that the kernel memory pool Mempool is actually a fallback pool that is really fetched from the pool in the case of tight memory. This will ensure that in extreme cases the success rate of the application of the object, the single is not always successful, because the size of the memory pool is limited after all, if the memory pool objects are used up, then the process can only go to sleep, that is joined to the pool->wait waiting queue, When you wait for an object that is available in the memory pool to be awakened, retry the request element from the pool:

Init_wait (&wait);
Prepare_to_wait (&pool->wait, &wait, task_uninterruptible);
Spin_unlock_irqrestore (&pool->lock, flags);
Io_schedule_timeout (5*hz);
Finish_wait (&pool->wait, &wait);

The function Mempool_free of the pool Reclaim object is as follows:

void Mempool_free (void *element, mempool_t *pool)
{
if (Pool->curr_nr < POOL-&GT;MIN_NR) {
Spin_lock_irqsave (&pool->lock, flags);
if (Pool->curr_nr < POOL-&GT;MIN_NR) {
Add_element (pool, Element);
Spin_unlock_irqrestore (&pool->lock, flags);
WAKE_UP (&pool->wait);
Return
}
Spin_unlock_irqrestore (&pool->lock, flags);
}
Pool->free (element, pool->pool_data);
}

In fact, the principle and mempool_alloc are corresponding, the release of the object is sufficient to see whether the available elements in the pool (pool->curr_nr = = POOL-&GT;MIN_NR), if not the element object is released back to the pool, otherwise the element object is returned to the pool- >pool_data.

In addition, Mempool provides or specifies several pairs of alloc/free functions, and the alloc and free functions that must be specified when Mempool_create creates a pool, respectively, for memory pools of elements of different sizes or types, as follows:

void *mempool_alloc_slab (gfp_t gfp_mask, void *pool_data)
{
struct Kmem_cache *mem = pool_data;
Return Kmem_cache_alloc (Mem, gfp_mask);
}
void Mempool_free_slab (void *element, void *pool_data)
{
struct Kmem_cache *mem = pool_data;
Kmem_cache_free (mem, Element);
}

void *mempool_kmalloc (gfp_t gfp_mask, void *pool_data)
{
size_t size = (size_t) pool_data;
Return Kmalloc (size, gfp_mask);
}
void Mempool_kfree (void *element, void *pool_data)
{
Kfree (Element);
}

void *mempool_alloc_pages (gfp_t gfp_mask, void *pool_data)
{
int order = (int) (long) Pool_data;
Return Alloc_pages (gfp_mask, order);
}
void Mempool_free_pages (void *element, void *pool_data)
{
int order = (int) (long) Pool_data;
__free_pages (element, order);
}

Generally speaking, the implementation of Mempool is very simple, but not simple, and very light and easy to use, which is the secret of the kernel.

Analysis of Linux memory pool source code

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.