The difference between the Linux kernel space memory application functions kmalloc, kzalloc, and vmalloc

        Reprinted from: https://blog.csdn.net/lu_embedded/article/details/51588902

        We all know that the function used to dynamically apply for memory in user space is malloc(). This function is used consistently on various operating systems, and the corresponding user space memory release function is free(). Note: The dynamically applied memory must be released after use, otherwise it will cause a memory leak. If the memory leak occurs in the kernel space, it will cause the system to crash. 

  So, how to apply for memory in kernel space? Generally, we will use kmalloc(), kzalloc(), vmalloc(), etc. Let us introduce the use of these functions and the differences between them.
kmalloc()

Function prototype:

void *kmalloc(size_t size, gfp_t flags);

  The memory applied by kmalloc() is located in the physical memory mapping area, and it is also physically continuous. They have only a fixed offset from the real physical address. Because there is a simpler conversion relationship, there is a limit to the size of the applied memory. Cannot exceed 128KB. 
   
The more commonly used flags (method of allocating memory):

  • GFP_ATOMIC  - The process of allocating memory is an atomic process, and the process of allocating memory will not be interrupted by (high priority process or interrupt);
  • GFP_KERNEL  - normal allocation of memory;
  • GFP_DMA  - To allocate memory to the DMA controller, this flag needs to be used (DMA requires the allocation of virtual addresses and physical addresses to be consecutive).

Reference usage of flags: 
 |– Process context, can sleep GFP_KERNEL 
 |– Process context, can not sleep GFP_ATOMIC 
 | |– Interrupt handler GFP_ATOMIC 
 | |– Soft interrupt GFP_ATOMIC 
 | |– Tasklet GFP_ATOMIC 
 |– Memory for DMA, can sleep GFP_DMA | GFP_KERNEL  |– memory used for DMA, cannot sleep. The memory release function corresponding to
 GFP_DMA | GFP_ATOMIC  is:
   

void kfree(const void *objp);
kzalloc()

  The kzalloc() function is very similar to kmalloc(), and the parameters and return values ​​are the same. It can be said that the former is a variant of the latter, because kzalloc() actually just adds the  __GFP_ZERO  flag. Therefore, in addition to applying for kernel memory, it also clears the contents of the applied memory.

/**
 * kzalloc - allocate memory. The memory is set to zero.
 * @size: how many bytes of memory are required.
 * @flags: the type of memory to allocate (see kmalloc).
 */
static inline void *kzalloc(size_t size, gfp_t flags)
{
    return kmalloc(size, flags | __GFP_ZERO);
}

The memory release function corresponding to kzalloc() is also kfree().

vmalloc()

Function prototype:

void *vmalloc(unsigned long size);

  The vmalloc() function will give a continuous memory area in the virtual memory space, but this continuous virtual memory is not necessarily continuous in the physical memory. Since vmalloc() does not guarantee that the applied physical memory is contiguous, there is no limit to the applied memory size. If you need to apply for a larger memory space, you need to use this function.

The corresponding memory release function is:

void vfree(const void *addr);

Note: vmalloc() and vfree() can sleep and therefore cannot be called from interrupt context. 
  

Summarize

The common features of kmalloc(), kzalloc(), vmalloc() are:

  1. Memory used to apply for kernel space;
  2. Memory is allocated in bytes;
  3. The allocated memory virtual addresses are contiguous;

The difference between kmalloc(), kzalloc(), vmalloc() is:

  1. kzalloc is a forced clearing kmalloc operation; (the following description does not distinguish between kmalloc and kzalloc)
  2. The memory size allocated by kmalloc has a limit (128KB), while vmalloc has no limit;
  3. kmalloc can guarantee that the physical addresses of allocated memory are contiguous, but vmalloc cannot guarantee;
  4. The process of kmalloc allocating memory can be an atomic process (using GFP_ATOMIC), while vmalloc may block when allocating memory;
  5. The overhead of kmalloc allocating memory is small, so kmalloc is faster than vmalloc;

Under normal circumstances, the memory needs to be physically contiguous only when it is to be accessed by DMA, but for performance reasons, kmalloc() is generally used in the kernel, and vmalloc() is only used when a large block of memory needs to be obtained. For example, when a module is dynamically loaded into the kernel, the module is loaded into memory allocated by vmalloc().


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326075543&siteId=291194637