[Linux] kernel function 1 kmalloc

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/zztingfeng/article/details/90680953

Function prototype

#include Linux/slab.h> 
void *kmalloc(size_t size, int flags); 

size is the size of memory to be allocated, but the size of the kernel will be adapted, for example, take 32, 64, etc., and architecture is a relationship of cache lines, etc., in short, may be larger than the memory you want to apply some of them. 
flags are interacting with the partner system tags, although kmalloc () to allocate memory from the slab, but the bottom still have to interact with the system and partners.

flags mark:

These flags are above the underlying combination of these flags implemented following: 
__GFP_DMA 
this flag requires partitioned memory area capable of DMA exact meaning is platform-dependent.
__GFP_HIGHMEM 
this flag indicates the allocated memory may be located in upper memory. 
__GFP_COLD 
normally, the memory allocator try to return to "buffer hot" page - page may be found in the processor buffer the contrary, this flag requests a "cold" page, it has not been used for some time it has allocated page is useful for DMA read this. when the buffer is present in the processor useless. 
__GFP_NOWARN 
this flag prevents rarely used to warn the kernel (using the printk), when an allocation can not be met. 
__GFP_HIGH 
this flag identifies a high-priority request, it is allowed to consume even kernel reserved for emergencies last memory page. 
__GFP_REPEAT 
__GFP_NOFAIL 
__GFP_NORETRY 
these flags modify how the distributor action, when it is difficult to satisfy an allocation __GFP_REPEAT means "do more to try something" through repeated attempts - but still possible allocation failed. __GFP_NOFAIL flag tells the Orchestration Do not fail; it do its utmost to meet the requirements of use __GFP_NOFAIL is strongly recommended; probably never have a valid reason to use it in a device driver in the final, __GFP_NORETRY inform the distributor immediately give up if it is not requested. . the memory 
of the Linux kernel source code:

/***kmalloc***/
static inline void *kmalloc(size_t size, gfp_t flags)
{
    if (__builtin_constant_p(size)) {
        int i = 0;
#define CACHE(x) \
        if (size <= x) \
            goto found; \
        else \
            i++;
#include "kmalloc_sizes.h"
#undef CACHE
        {
            extern void __you_cannot_kmalloc_that_much(void);
            __you_cannot_kmalloc_that_much();
        }
found:
#ifdef CONFIG_ZONE_DMA
        if (flags & GFP_DMA)
            return kmem_cache_alloc(malloc_sizes[i].cs_dmacachep,
                        flags);
#endif
        return kmem_cache_alloc(malloc_sizes[i].cs_cachep, flags);
    }
    return __kmalloc(size, flags);
}

Code analysis: first determine the memory size to apply in this function manually, (1) if successful jump to found, execution kmem_cache_alloc (), because of its size has been found. the kmem_cache_alloc () call to the underlying transfer __cache_alloc () function. (2) If unsuccessful, perform __kmalloc () function, and __kmalloc () function will also fit the size of the bottom, it calls relationship __kmalloc () -> __ do_kmalloc (), then __do_kmalloc () function will perform __find_general_cachep (), this function is used to manually determine the size of the function call __cache_alloc () function to determine the size. So in both cases ultimately will determine the size of memory to be allocated, referred __cache_alloc () function to perform assigned work.

cache allocation determined by the size kmalloc_sizes.h

#if (PAGE_SIZE == 4096)
    CACHE(32)
#endif
    CACHE(64)
#if L1_CACHE_BYTES < 64
    CACHE(96)
#endif
    CACHE(128)

Wherein, # IF L1_CACHE_BYTES <64, CACHE (96), that is, if the cache line size is greater than equal to 64, 96 will not be allocated bytes of memory, but directly to 128. 96-64 = 32 because 64 is less than the cache line size. As can be seen from this, if a size is 4K, then the memory allocation is the minimum size of 32 bytes, allowing other allocated memory size may also depend on the size of the cache line.

Since kmalloc () low-level calls __cache_alloc () function, this is it and kmem_cache_create () function common interface.

Guess you like

Origin blog.csdn.net/zztingfeng/article/details/90680953