LDD Reading notes _ memory Management

Source: Internet
Author: User

This section is not just an introduction to LDD, but also includes a summary of the Linux memory model.


A word summary

The partner system is the cornerstone, slab based on the partner system, Kmalloc based on slab.

Key points

? The partner system is for continuous large memory, the resulting unit of memory from 1 page to 211 page, to solve the external fragmentation problem.? Slab Splitter is for small memory, from 32B to 128KB, to solve the internal fragmentation problem, Kmalloc is based on the slab allocator. If the physical memory plus the size of the IO space that needs to be mapped adds up to more than 896M, it is necessary to turn on the Highmen function.

Agenda
Memory model (zone, partner system, Slab)
Get the page (Request page Frame)
Release page (Release page Frame)
High-end memory access
? Permanent Kernel Mapping
? Temporary kernel Mapping

? noncontiguous memory allocation


? Linux divides memory into node, three zone per node–ZONE_DMA, usually corresponding to the space below 16M, ISA bus limit –zone_normal–zone_highmem, usually corresponds to more than 896M of space, this part of the space does not directly map to the kernel 4GB range, should not be directly accessible to this kernel



Buddy System Algorithm

? External fragmentation: Frequent allocation/release results in a whole block of contiguous memory, causing a lot of intermittent fragmentation, resulting in subsequent allocations of successive memory failures, even if the total remaining space is sufficient. Workaround: – Re-map discontinuous physical addresses to contiguous linear addresses – develop memory management techniques to record idle contiguous memory – The kernel takes the second approach
The Kernel groups free page frames into 11 block linked lists, respectively, corresponding to the 1,2,4,8,16,32,64,128,256,512,1024 consecutive page box, that is, the maximum allocation size corresponding to 4M.
And the starting address of each block is an integer multiple of the size of the continuous page box inside the block.      Kernel approach – If you want to apply for 256 page boxes, the kernel first checks if there are any such free blocks in the corresponding list.      – If not, check the list of 512 page boxes, and if there are free blocks, divide the 512 page box evenly, one to satisfy the request, and one to insert into the linked list of the 256-page box. – If the list of 512-page boxes does not have a free block, the list of 1024 page boxes is found, and 256 page boxes are used to meet the requirements if it finds one. The remaining 786 page boxes are divided into two parts, 512 of which are inserted into the 512 linked list,
The remaining 256 are inserted into the 256 linked list.      – If the list in the 1024-page box has no free blocks, an error is returned. – The inverse process above is the corresponding release process? The request of the partner of the page box size B-also has the same size – the physical address is continuous – the physical address of the first page box of the first block is a multiple of 2 * b * 4K
Slab
As mentioned earlier, the partner algorithm uses the page box as the basic memory unit allocation, this is suitable for the large memory allocation, how to deal with the small memory?? The kernel puts the allocation of small memory into the same page box, but this brings up the new problem. Internal fragmentation: The size of the memory request does not match the size assigned to him. For example, a byte is required, but it is assigned a byte. Because the kernel allocates small memory to a power of 2, the default is level 13, from 128K to byte. What to do – Frequent request/release: Slab Allocator – Infrequent request/release: Kmalloc/kfree
? Kernel functions tend to repeatedly request the same type of memory area, if there is no slab allocator, the kernel needs to repeatedly allocate and reclaim the page box containing the same memory area, affecting efficiency.
The slab allocator saves the page box in the cache and can be reused quickly.

? The existing common slab cache –cache_cache contains the allocation type for allocating kmem_cache_t cache –32b–128kb, one for DMA and one for general assignment (Kmalloc) – Initialize in Kmem_cache_init? Special slab cache used by the kernel – Created with Kmem_cache_create – destroyed with Kmem_cache_destroy (for module form), or km Em_cache_shrink? Slab How to –kmem_getpages the page frame you need? How does the Slab page box release –kmem_freepages? Assign Slab object –kmem_cache_alloc? Release Slab Object –kmem_cache_free

Request Page Frame

Alloc_pages (gfp_mask, order) gets the 2^order continuous page frame, returns the struct page* of the first page that satisfies the condition, or null?alloc_page (gfp_mask) alloc_ Pages (gfp_mask, 0)? _ _get_free_pages (Gfp_mask, order) is similar to alloc_pages, but returns the linear address of the first page? _ _get_free_page (Gfp_mask) _ _ge T_free_pages (gfp_mask, 0)? Get_zeroed_page (Gfp_mask) alloc_pages (Gfp_mask | _ _gfp_zero, 0), return linear address, page filled to 0?_ _GET_DMA _pages (Gfp_mask, order) _ _get_free_pages (Gfp_mask | _ _GFP_DMA, order), return to the linear address used for DMA transmission

? Because the kernel frequently requests and frees individual page boxes, each zone defines a per-CPU page cache, which contains pre-allocated page boxes, in order to improve performance. In fact, this cache contains two parts, one is the hot cache (which will be stored in the cache), the cold high speed (often used as DMA, does not require CPU involvement)
struct Per_cpu_pages {int count;/* number of pages in the list */int low;/* low watermark, refill needed */int high;/* hig h watermark, emptying needed */int batch;/* chunk size for buddy Add/remove */struct List_head list;/* the list of pages * /};
? If the number of page boxes exceeds high, the Batch page box is released from the cache back to the partner system, and if it is below low, the batch page box is allocated from the partner system to the cache. ? Api–buffered_rmqueue by Per CPU page box cache allocation –free_hot_page/free_cold_page free page box to per CPU page box cache

Introduction to commonly used GFP mask

? Group name corresponding flags? Gfp_atomic _ _gfp_high? Gfp_noio _ _gfp_wait? Gfp_nofs _ _gfp_wait | _ _gfp_io? Gfp_kernel _ _gfp_wait | _ _gfp_io | _ _gfp_fs? Gfp_user _ _gfp_wait | _ _gfp_io | _ _gfp_fs? Gfp_highuser _ _gfp_wait | _ _gfp_io | _ _gfp_fs | _ _gfp_highmem

__GFP_DMA and __gfp_highmem are referred to as the admin area modifier, which indicates the search zone when searching for a free page frame, but actually:

? If the __GFP_DMA is set, the page frame can only be retrieved from the DMA zone. If the __gfp_highmem is not set, then the normal zone and DMA zone are obtained in order of precedence? If __gfp_highmem is set , the Highmem zone, normal zone, and DMA zone are prioritized in order to obtain

Release page Frame

_ _free_pages (page, order) – check if the page frame is reserved, if not, reduce counter, if counter is 0, it is considered that the continuous 2order page frame is no longer used? _ _f      Ree_page (page) –_ _free_pages (page, 0)? free_pages (addr, order) – Similar to __free_pages, just accept a linear address? Free_page (addr) –free_pages (addr, 0)


High-end memory access

? Because the page frame above 896M does not map to the scope of the 4th g of the kernel linear address space, the kernel cannot be accessed directly.? In other words, the allocation function (__get_free_pages) that returns a linear address cannot be used for high-end memory. can use Alloc_pages, return is page*? Therefore, part of the last 128M of the kernel linear address space is specifically designed to map high-end memory, thus achieving access to high-end memory.

High-end memory mapping method

? Permanent kernel mappingThe current process is blocked and therefore cannot be used in interrupts and Tasklet
In Pkmap_page_table, there is a total of last_pkmap (512/1024) table, which maps the address of 2m/4m. The page_address () function, which returns a linear address according to page descriptor – if it is non-highmem, the address must exist, __va (PAGE_TO_PFN (page) << Page_shi FT) – If it is in Highmem, it is found in page_address_htable and returns null if not
? Kmap used to establish a permanent mapping (actually called Kmap_high)
void * Kmap_high (struct page * page) {   unsigned long vaddr;   Spin_lock (&kmap_lock);   VADDR = (unsigned long) page_address (page);       if (!vaddr)      vaddr = map_new_virtual (page);    pkmap_count[(vaddr-pkmap_base) >> page_shift]++;   Spin_unlock (&kmap_lock);   
? Kunmap is used to remove permanent mappings (actually called Kunmap_high)
void Kunmap_high (struct page * page) {spin_lock (&kmap_lock); if (--pkmap_count[((unsigned long) page_address (page) -  Pkmap_base) >>page_shift]) = = 1)   if (waitqueue_active (&pkmap_map_wait))       wake_up (&pkmap _map_wait);  

? Temporary kernel mapping– Do not block, but avoid using the same mappings – the number is limited, typically 13 mapped windows per CPU
Enum Km_type {D (0) km_bounce_read,d (1) km_skb_sunrpc_data,d (2) km_skb_data_softirq,d (3) km_user0,d (4) km_user1,d (5) Miles _bio_src_irq,d (6) km_bio_dst_irq,d (7) km_pte0,d (8) km_pte1,d (9) km_irq0,d (Ten) km_irq1,d (one) km_softirq0,d (one) KM_ Softirq1,d (Km_type_nr});

– Using Interfaces Kmap_atomic and kunmap_atomic
void * kmap_atomic (struct page * page, enum Km_type type) {    enum fixed_addresses idx;    unsigned long vaddr;    Current_thread_info ()->preempt_count++;    if (! Pagehighmem (page))        return page_address (page);    IDX = type + KM_TYPE_NR * smp_processor_id ();    vaddr = Fix_to_virt (fix_kmap_begin + idx);    Set_pte (Kmap_pte-idx, Mk_pte (page, 0x063));    _ _flush_tlb_single (vaddr);    return (void *) vaddr;

void kunmap_atomic (void *kvaddr, enum km_type type) {#ifdef config_debug_highmemunsigned long vaddr = (unsigned long) kvadd R & page_mask;enum fixed_addresses idx = type + km_type_nr*smp_processor_id (); if (Vaddr < Fixaddr_start) {//Fixme Dec_preempt_count ();p reempt_check_resched (); return;} if (vaddr! = __fix_to_virt (FIX_KMAP_BEGIN+IDX)) BUG ();p te_clear (KMAP_PTE-IDX); __flush_tlb_one (vaddr); #endifdec_ Preempt_count ();p reempt_check_resched ();}

? noncontiguous memory allocation


? vmalloc/vmalloc_32 (can only be assigned from NORMAL/DMA Zone)? Vmap (provided the VM_STRUCT descriptor has been called Get_vm_area)? Ioremap? vfree VU Nmap Iounmap?

LDD Reading notes _ 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.