Article Title: LinuxKernel memory allocation method. Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.
This week, BSP met a very serious issue:
Loop-based streaming. The dma_alloc of the v4l2 output driver can easily fail. The kernel panic and dump output the status of the current buddy system.
The initial analysis is that the fragment memory does not allocate enough continuous memory to the v4l output driver. Start debug
First, you can use/proc/buddyinfo to continuously dump the buddy status when playing a movie, and find a large block of memory: 256 kb-4 MB.
The reduction was very rapid. After 1-2 hours, there was no large continuous memory in buddy. This proves that the preliminary analysis is correct, but you still do not know
WhO cauSed fragment, application layer, or v4l2 driver itself?
Next, add a NORMAL zone (DMA is used in the arm system, so application and dma both use a buddy system ),
Separate normal memory allocation from dma. Continue the test and find that the memory block status in the dma zone is NORMAL at the beginning, but the memory in the NORMAL zone
In the end, the NORMAL zone does not have enough memory for the application, and the kernel applies to the DMA zone,
Finally, the issue is reproduced.
Now the problem is very clear. The application has a memory leak, which is a very serious leak. But there will be no problem with dma_alloc?
After reading the problem I described, Fred pointed out some problems with the algorithm in dma_alloc: after applying for a 2 ^ memory block of sufficient size to buddy,
This function releases redundant pages in the Application Block to accelerate fragment. Later, we made an experiment to Release excess data in dma_alloc.
The fragment speed is greatly reduced when page functions are removed.
After studying this issue last week, I began to resummarize the methods and methods for memory allocation in the kernel, which are summarized as follows:
Page assignment
Unsigned long _ get_free_pages (gfp_t gfp_mask, unsigned int order)
Obtain the original page from the buddy system. The original allocation method.
Slab distributor
1. General cache
Void * kmalloc (size_t size, gfp_t flags)
Kmalloc is based on the following size mem cache: 32, 64,128,256,512, 1,024, 2,048, 4,096,
8,192, 16,384, 32,768, 65,536, and 131,072 bytes. In essence, kmem_cache_alloc is called for allocation.
Object. Therefore, the maximum size that kmalloc can allocate at a time is kb. The kmalloc allocation speed is very fast. Pay attention to the label flag when allocating kmalloc.
Parameter: GFP_ATOMIC is used in non-interrupt context (ISR, softirq, tasklet) and non-sleep context.
The kernel also adds the allocation function for memory resetting: kzarloc.
2. Dedicated cache
Kmem_cache_create ()
Void * kmem_cache_alloc (struct kmem_cache * cache, gfp_t flags)
If you need to allocate and release a structure frequently, we recommend that you do not use kmalloc, but create your own memory cache in the slab system.
Specify the object size of the structure. Use kmem_cache_alloc for allocation. The size of the same slab object is also limited. Generally
The next MAX_OBJ_ORDER is 5, that is, 32 pages, kb.
Non-continuous memory allocation
Void * vmalloc (unsigned long size)
The memory exceeding kb obviously cannot be allocated using slab, and when the requested continuous memory size cannot be satisfied in the buddy system
You need to use vmalloc. In order to map physical non-consecutive pages one by one, vmalloc is much larger than direct memory ing.
The backup buffer jitter. Do not use vmalloc unless you need a particularly large memory.
DMA-based allocation
Void * dma_alloc_coherent (struct device * dev, size_t size, dma_addr_t * handle, gfp_t green)
In some arch, you can use dma_alloc_coherent to allocate DMA dedicated memory. Included in arch/arm/mm/consistent. c
, This function first allocates 2 ^ order memory that can meet the minimum size, and then releases 2 ^ order-size excess pages to buddy. However, arch/i386/
In kernel/pci-dma.c, 2 ^ order block memory is allocated directly.
Direct ing allocation
Ioremap (unsigned long phys_addr, size_t size)
Int remap_pfn_range (struct vm_area_struct * vma, unsigned long addr,
Unsigned long pfn, unsigned long size, pgprot_t prot)
In some architectures, we can retain a region on the memory map segment as the proprietary memory of dma or other devices.
This memory is not under the control of the kernel buddy (not put into mem_maps), and you cannot obtain it from the above allocation methods.
Memory. At this time, you can use ioremap and remap_pfn_range to map the memory directly to the vm.