Linux memory management partner System (memory release)

Source: Internet
Author: User

Release the page in the Linux Kernel partner system. The main function is free_pages ()
 
I. Upper-layer operations
 
Www.2cto.com
/* Release with a virtual address */
Void free_pages (unsigned long addr, unsigned int order)
{
If (addr! = 0 ){
VM_BUG_ON (! Virt_addr_valid (void *) addr ));
_ Free_pages (pai_to_page (void *) addr), order);/* release function */
}
}
Www.2cto.com
/* Release page */
Void _ free_pages (struct page * page, unsigned int order)
{
If (put_page_testzero (page) {/* release when the count value is reduced to 0 */
/* Debug */
Trace_mm_page_free_direct (page, order );
If (order = 0)
Free_hot_page (page);/* release a single page */
Else
_ Free_pages_ OK (page, order );
}
}
2. release a single page
 
Release a single page free_hot_page () call the free_hot_cold_page () function
 
Www.2cto.com
Static void free_hot_cold_page (struct page * page, int cold)
{
Struct zone * zone = page_zone (page );
Struct per_cpu_pages * pcp;
Unsigned long flags;
Int migratetype;
Int wasMlocked = _ TestClearPageMlocked (page );
/* Debug Code */
Kmemcheck_free_shadow (page, 0 );
 
If (PageAnon (page ))
Page-> mapping = NULL;
If (free_pages_check (page ))
Return;
 
If (! PageHighMem (page )){
Debug_check_no_locks_freed (page_address (page), PAGE_SIZE );
Debug_check_no_obj_freed (page_address (page), PAGE_SIZE );
}
/* X86 is blank */
Arch_free_page (page, 0 );
/* Debugging */
Kernel_map_pages (page, 1, 0 );
/* Obtain the pcp of the cpu corresponding to the zone */
Pcp = & zone_pcp (zone, get_cpu ()-> pcp;
/* Obtain the migratetype of the page */
Migratetype = get_pageblock_migratetype (page );
Set_page_private (page, migratetype);/* set the private bit as the parameter */
Local_irq_save (flags);/* save interrupted */
If (unlikely (wasMlocked ))
Free_page_mlock (page );
_ Count_vm_event (PGFREE );
 
/*
* We only track unmovable, reclaimable and movable on pcp lists.
* Free ISOLATE pages back to the allocator because they are being
* Offlined but treat RESERVE as movable pages so we can get those
* Areas back if necessary. Otherwise, we may have to free
* Excessively into the page allocator
*/
If (migratetype> = MIGRATE_PCPTYPES ){
If (unlikely (migratetype ==migrate_isolate )){
/* Release to partner system */
Free_one_page (zone, page, 0, migratetype );
Goto out;
}
Migratetype = MIGRATE_MOVABLE;
}
 
If (cold)/* add to the tail of the pcp linked list */
List_add_tail (& page-> lru, & pcp-> lists [migratetype]);
Else/* add to the head of the pcp linked list */
List_add (& page-> lru, & pcp-> lists [migratetype]);
Pcp-> count ++;/* pcp count plus one */
If (pcp-> count> = pcp-> high) {/* when the number of pages in pcp exceeds its maximum value,
Release pcp> batch pages to partner systems */
Free_pcppages_bulk (zone, pcp-> batch, pcp );
Pcp-> count-= pcp-> batch;/* page count minus the number of released pages */
}
 
Out:
Local_irq_restore (flags);/* reply interrupted */
Put_cpu ();
}
Release page from pcp to partner System
 
Free_pcppages_bulk ()
 
Www.2cto.com
Are in same zone, and of same order.
* Count is the number of pages to free.
*
* If the zone was previusly in an "all pages pinned" state then look
* See if this freeing clears that state.
*
* And clear the zone's pages_scanned counter, to hold off the "all pages are
* Pinned "detection logic.
*/
/* Release count pages from PCP to partner system */
Static void free_pcppages_bulk (struct zone * zone, int count,
Struct per_cpu_pages * pcp)
{
Int migratetype = 0;
Int batch_free = 0;
/*
* Although the management area can be classified by CPU nodes, it can also allocate memory Across CPU nodes,
* Therefore, the spin lock must be used to protect the management zone.
* The purpose of using the cache per CPU is to reduce the use of this lock.
*/
Spin_lock (& zone-> lock );
/* All_unreclaimable indicates the memory shortage. After the memory is released, clear the mark */
Zone_clear_flag (zone, ZONE_ALL_UNRECLAIMABLE );
Zone-> pages_scanned = 0;/* pages_scanned indicates the number of pages scanned during page reclaim since the last memory shortage.
The memory is currently being released. Please clear it to 0 and re-count it when the recovery process is followed */
 
/* Increase the number of idle pages in the management area */
_ Mod_zone_page_state (zone, NR_FREE_PAGES, count );
While (count ){
Struct page * page;
Struct list_head * list;
 
/*
* Remove pages from lists in a round-robin fashion.
* Batch_free count is maintained that is incremented when
* Empty list is encountered. This is so more pages are freed
* Off fuller lists instead of spinning excessively around empty
* Lists
*/
Do {/* Find the empty one from the three linked lists of pcp and release */
Batch_free ++;/* See the English comments */
If (++ migratetype === MIGRATE_PCPTYPES)
Migratetype = 0;
List = & pcp-> lists [migratetype];
} While (list_empty (list ));
 
Do {
Page = list_entry (list-> prev, struct page, lru );
/* Must delete as _ free_one_page list manipulates */
List_del (& page-> lru );
/* Release a single page to the partner system. Pay attention to the classification and recycling here */
_ Free_one_page (page, zone, 0, migratetype );
Trace_mm_page_pcpu_drain (page, 0, migratetype );
} While (-- count & -- batch_free &&! List_empty (list ));
}
Spin_unlock (& zone-> lock );
}
3. Release multiple pages
 
Release multiple page_free_pages_ OK () Functions
 
Www.2cto.com
Int I;
Int bad = 0;
Int wasMlocked = _ TestClearPageMlocked (page );
/* For debugging and related macros */
Kmemcheck_free_shadow (page, order );
 
For (I = 0; I <(1 <order); ++ I)/* page check */
Bad + = free_pages_check (page + I );
If (bad)
Return;
 
If (! PageHighMem (page )){
Debug_check_no_locks_freed (page_address (page), PAGE_SIZE <order );
Debug_check_no_obj_freed (page_address (page ),
PAGE_SIZE <order );
}
/* Blank in X86 system */
Arch_free_page (page, order );
/* Debugging, macro definition */
Kernel_map_pages (page, 1 <order, 0 );
 
Local_irq_save (flags);/* Temporary flags storage, Guanzhong disconnection */
If (unlikely (wasMlocked ))
Free_page_mlock (page );
_ Count_vm_events (PGFREE, 1 <order );
/* Input a parameter to release the page of 1 <order
To partner system */
Free_one_page (page_zone (page), page, order,
Get_pageblock_migratetype (page);/* obtain the memory block type */
Local_irq_restore (flags);/* resume interruption */
Www.2cto.com
Static void free_one_page (struct zone * zone, struct page * page, int order,
Int migratetype)
{
Spin_lock (& zone-> lock);/* Get the spin lock of the management zone */
Zone_clear_flag (zone, ZONE_ALL_UNRECLAIMABLE);/* If the page is released, the two flags must be cleared to 0, indicating that the memory is no longer tight */
Zone-> pages_scanned = 0;
/* Count idle pages in the management area */
_ Mod_zone_page_state (zone, NR_FREE_PAGES, 1 <order );
/* Release the linked list to the specified partner system type */
_ Free_one_page (page, zone, order, migratetype );
Spin_unlock (& zone-> lock);/* release lock */
}
Www.2cto.com
Etype)
{
Unsigned long page_idx;
 
If (unlikely (PageCompound (page)/* The page to be released is part of a huge page */
/* Fix the giant page flag. If the giant page flag is faulty, exit */
If (unlikely (destroy_compound_page (page, order )))
Return;
 
VM_BUG_ON (migratetype ==- 1 );
/* Convert the page to the subscript of the global page array */
Page_idx = page_to_pfn (page) & (1 <MAX_ORDER)-1 );
/* If the released page is not the first page of the release level, the parameter is incorrect */
VM_BUG_ON (page_idx & (1 <order)-1 ));
/* Check whether the page block is valid, whether there are holes, and whether all the pages in the page block are in the same zone */
VM_BUG_ON (bad_range (zone, page ));
 
While (order | MAX_ORDER-1 ){
Unsigned long combined_idx;
Struct page * buddy;
/* Find the partners on the page
Find the partner of the page block to be released.
There is a "partner block" corresponding to the same size (known by the exponential principle of 2 )*/
Buddy = _ page_find_buddy (page, page_idx, order );
If (! Page_is_buddy (page, buddy, order)/* check whether the page is a partner */
Break;
 
/* Our buddy is free, merge with it and move up one order .*/
List_del (& buddy-> lru );
Zone-> free_area [order]. nr_free --;
/* Prepare for the following merge, clear the PG_buddy flag of the partner, and set the private member of the partner
0 */
Rmv_page_order (buddy );
/* Use the partner algorithm formula to calculate the page block index of the merged parent node */
/* This is actually the case. This should be used together with the above query for buddy.
* The algorithm goes up or down in the original subscript when identifying the buddy.
* (1 <order position
* The function here is to find the first address of the merged new block.
* That is to say, if the above is added, the base address remains unchanged.
* If the value is reduced, 1 is reduced here <order
* The label here is not a physical address or mem_map.
* Direct association is applied to the buddy algorithm.
* The constructed specific representation makes the partner search here
* The merger with partners is clever.
*/
Combined_idx = _ find_combined_index (page_idx, order );
Page = page + (combined_idx-page_idx );
Page_idx = combined_idx;
Order ++;
}
Set_page_order (page, order);/* sets the private attribute of page. The partner system uses this value
Determine the order of the page */
List_add (& page-> lru,
& Zone-> free_area [order]. free_list [migratetype]);/* Each order in the partner system has 5 idle linked lists */
Zone-> free_area [order]. nr_free ++;/* Add one to the free block of the order */
}
Iv. Partner operations
 
4.1. Search for partners
 
Www.2cto.com
Static inline struct page *
_ Page_find_buddy (struct page * page, unsigned long page_idx, unsigned int order)
{
/* Partner's computing principle,
* In fact, the order bit of page_idx is converted using the (1 <order) mask or (XOR ).
* Value. Therefore, if this bit is 0, buddy_idx is equal to page_idx + order
* Conversely, if this bit was originally 1, buddy_idx would be equal to the page_idx-order
* The calculated partner is the subscript in mem_map.
*/
Unsigned long buddy_idx = page_idx ^ (1 <order );
/* Return the Page Base Address of the partner block */
Return page + (buddy_idx-page_idx );
}
4.2. Check if it is a partner
 
Www.2cto.com
Static inline int page_is_buddy (struct page * page, struct page * buddy,
Int order)
{
If (! Pfn_valid_within (page_to_pfn (buddy)/* verify the validity of this buddy */
Return 0;
 
If (page_zone_id (page )! = Page_zone_id (buddy)/* verify whether the page and Its buddy are in the same zone */
Return 0;
/* Verify the order value of related bits and buddy */
/* Check the PG_buddy flag to determine whether buddy is in the partner system and whether buddy is in the order level.
In the linked list, the private member of the page stores the order of the linked list where the page block is located. */
If (PageBuddy (buddy) & page_order (buddy) = order ){
VM_BUG_ON (page_count (buddy )! = 0 );
Return 1;
}
Return 0;
}
Conclusion: The main process of memory release or release of the partner System
 
1. If a single page is released, consider whether to release it to the partner System Based on the page type and add it to the pcp linked list. If the pcp linked list contains too much memory, call the free_pcppages_bulk () function to return the large memory to the partner system;
 
2. If multiple pages are released, call _ free_one_page () to release them to the partner system.
 
3. When releasing the package to the partner system, you need to consider the merger with the partner.
 

Related Article

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.