Linux page-level memory management and processing details

Source: Internet
Author: User

After figuring out the principles of the partner system algorithm, we can happily process the page box.

 

We can use six slightly different function and macro request page boxes. Generally, both return the linear address of the first allocated page, or return NULL if the allocation fails.

Alloc_pages (gfp_mask, order): use this function to request 2 consecutive page boxes. It returns the address of the first allocated page frame descriptor, or if it fails, it returns NULL.

Alloc_page (gfp_mask): used to obtain a macro for a single page box. It is actually only alloc_pages (gfp_mask, 0 ). It returns the address of the descriptor of the allocated page, or if the allocation fails, null is returned.

_ Get_free_pages (gfp_mask, order): this function is similar to alloc_pages (), except that it returns the memory linear address corresponding to the first allocated page.

_ Get_free_page (gfp_mask): used to obtain a macro of a separate page box. It is just _ get_free_pages (gfp_mask, 0)

Get_zeroed_page (gfp_mask): The function is used to obtain a page full of 0. It calls alloc_pages (gfp_mask | _ gfp_zero, 0) and returns the linear address of the obtained page box.

_ Get_dma_pages (gfp_mask, order): This macro obtains the page box for DMA. It extends the call to _ get_free_pages (gfp_mask | _ gfp_dma, order ).

The gfp_mask parameter is a set of flags that indicate how to find idle page boxes:

 

Flag

Description

_ Gfp_dma

The requested page must be in the zone_dma management area.

_ Gfp_highmem

The requested page is in the zone_highmem management area.

_ Gfp_wait

Allows the kernel to block the current process waiting for the idle page.

_ Gfp_high

Allow the kernel to access the reserved page box pool

_ Gfp_io

Allow the kernel to execute I/O transmission on the low-end Memory Page to release the page box

_ Gfp_fs

If the value is 0, the kernel is not allowed to perform operations dependent on the file system.

_ Gfp_cold

The requested page may be "cold"

_ Gfp_nowarn

If a memory allocation fails, no warning is generated.

_ Gfp_repeat

Kernel retry memory allocation until successful

_ Gfp_nofail

Same as _ gfp_repeat

_ Gfp_noretry

No retry after a memory allocation failure

_ Gfp_no_grow

The slab distributor cannot increase the slab cache speed.

_ Gfp_comp

Page of the extension page

_ Gfp_zero

Any returned page box must be filled with 0

 

Any of the following four functions and macros can be released:

_ Free_pages (page, order): This function first finds the page descriptor pointed to by page. If the page is not retained (pg_reserved is 0), the Count field of the descriptor is reduced by 1. If the Count field changes to 0, it is assumed that the 2order consecutive page boxes starting from the corresponding page box are no longer used. In this case, the function releases the page box.

Free_pages (ADDR, order): this function is similar to _ free_pages (), except that the parameter it receives is the linear address ADDR of the first page box to be released.

_ Free_page (page): This macro releases the page box corresponding to the descriptor specified by page, which is extended to _ free_pages (page, 0)

Free_page (ADDR): This macro releases the page box with the linear address ADDR, which is extended to: free_pages (ADDR, 0)

 

Assign a group of pages

 

Each request to a set of consecutive page boxes is actually processed by executing the alloc_pages macro. Then, the macro calls the _ alloc_pages () function in turn, which is the core of the distribution page box. It receives the following three parameters:
Gfp_mask: The identifier specified in the memory allocation request (see the previous blog ).
Order: logarithm of the number of consecutive page boxes to be allocated (that is, two consecutive page boxes must be allocated ).
Zonelist: pointer to the zonelist data structure, which describes the memory management zones suitable for memory allocation in priority.

 

The _ alloc_pages () function summarizes and executes the following code:
For (I = 0; (Z = zonelist-> zones [I])! = NULL; I ++ ){
If (zone_watermark_ OK (z, order ,...)){
Page = buffered_rmqueue (z, order, gfp_mask );
If (page)
Return page;
}
}

 

The _ alloc_pages () function first scans each memory management zone contained in the zonelist data structure.

 

For each memory management area, this function compares the number of free page boxes with a threshold value. The threshold value depends on the memory allocation flag, the type of the current process, and the number of times that the management area has been checked by the function.

 

In fact, if the idle memory is insufficient, each memory management area is usually checked n times, and each time based on the requested idle memory quota, a lower threshold value is used for scanning. Therefore, the previous code is copied several times in the _ alloc_pages () function, and each change is very small. _ Alloc_pages () function calls buffered_rmqueue () function: it returns the page descriptor of the first allocated page box. If the memory management area does not have a set of consecutive page boxes of the requested size, returns null.

 

The buffered_rmqueue () function has a page box in the specified memory management area. The parameter is the address of the memory management area descriptor, the log order of the memory size requested for allocation, and the allocation flag gfp_flags. This function essentially performs the following operations:
1. if order is equal to 0, the cache is used on each CPU page. We will not discuss it here. If order is not equal to 0, it indicates that the request spans several consecutive page boxes, the cache on each CPU page cannot be used. perform the following steps for the function:
2. Call the _ rmqueue () function to allocate the requested page box from the partner system.
3. If the memory request is satisfied, the function will initialize the page descriptor of the (first) page box: Clear some flags, set the private field to 0, and set the reference counter of the page box to 1. In addition, if the _ gpf_zero flag in gfp_flags is set, the function fills the allocated memory area with 0.
4. Return the page descriptor address of the (first) page. If the memory allocation request fails, null is returned.

 

Here we will mention the zone_watermark_ OK () helper function, which is used to detect whether there are enough idle page boxes in the corresponding memory management area. This function receives several parameters, they determine the threshold min for the number of idle page boxes in the memory management zone Z. The threshold value is a very advanced mathematical concept, which is difficult to explain, so I will not introduce it in detail. I will only explain the situation where zone_watermark_ OK meets both of the following conditions and returns 1:
1. In addition to the allocated page box, there are at least min idle page boxes in the memory management area, excluding the page boxes reserved for insufficient memory (lowmem_reserve field of the management area descriptor ).
2. in addition to the allocated page box, there are at least two free page boxes (MIN/2 k) in the blocks where order is at least K. For each K, the value is between 1 and the assigned order. Therefore,

If order is greater than 0, there are at least min/2 free page boxes in the blocks with at least 2; if order is greater than 1, at least four free page boxes are available for at least four blocks.

 

In the kernel, the true _ alloc_pages () function is very complicated. It needs to be analyzed based on the kernel recycle page box mechanism. In essence, it performs the following steps:
1. Perform the first scan of the memory management area (see the Code listed above ). In the first scan, the threshold Min is set to Z-> pages_low, And the Z points to the management descriptor being analyzed (the can_try_harder and gfp_high parameters are set to 0 ).
2. if the function is not terminated in the previous step, there is not much idle memory left: The function wakes up the kswapd kernel thread to asynchronously start recycling the page box.
3. Perform the second scan of the memory management area and pass the value Z-> pages_min as the threshold base. As explained above, the actual threshold value is determined by the_can_try_harder and gfp_high. This step is similar to step 1, but this function uses a lower threshold.
4. If the function is not terminated in the previous step, the system memory is insufficient. If the kernel control path that generates the memory allocation request is not an interrupt handler or a delayable function, and it tries to recycle the page box (or the current pf_memalloc flag is set to a bit, or its pf_memdie flag is set), then the function immediately executes the third scan to the memory management area, tries to allocate the page box and ignore the threshold of insufficient memory, that is, do not call zone_watermark_ OK (). Only in this case can the kernel control path be used to consume pages reserved for insufficient memory (specified by the lowmem_reserve field of the Management Zone descriptor ). In fact, in this case, the kernel control path that generates memory requests will eventually try to release the page box, so as long as it is possible, it should get the requested. If no memory management area contains enough page boxes, the function returns NULL to prompt the caller for an error.
5. Here, the kernel control path being called does not try to recycle the memory. If the gfp_mask _ gfp_wait flag is not set, the function returns NULL to indicate that the memory allocation of the kernel control path fails: in this case, if the current process is not blocked, there is no way to satisfy the request.
6. The current process can be blocked here: Call cond_resched () to check whether other processes require CPU.
7. Set the current pf_memalloc flag to indicate that the process is ready to execute memory recycle.
8. Save a pointer to the reclaim_state data structure to current-> reclaim_state. This data structure contains only one reclaimed_slab field and is initialized to 0 (we will see how to use this field in the "Slab splitter and partition page box distributor interface" blog below ).
9. Call try_to_free_pages () to find some page boxes for recycling. The latter function may block the current process. Once the function returns, __alloc_pages () resets the current pf_memalloc flag and calls cond_resched () again ().
10. If some page boxes have been released in the previous step, the function will perform the same memory management area scan as step 1. If the memory allocation request cannot be met, the function determines whether to continue scanning the memory management zone. If the _ gfp_noretry flag is cleared, in addition, the memory allocation request spans up to eight page boxes or one of the _ gfp_repeat and _ gfp_nofail signs is set, so the function calls blk_congestion_wait () to sleep the process for a while, and jump back to step 1. Otherwise, the function returns NULL to indicate that the caller's memory allocation has failed.
11. If no page box is released in step 1, it means that the kernel has a lot of trouble, because the free page box is no longer dangerous and it is impossible to recycle any page box. It may be time to make an important decision. If you allow the kernel control path to execute operations dependent on the file system to kill a process (the _ gfp_fs flag in gfp_mask is set to a bit) and the _ gfp_noretry flag is 0, perform the following sub-steps:
A) Use a threshold value equal to Z-> pages_high to scan the memory management area again.
B) Call out_of_memory () to release some memory by killing a process (For details, refer to the section "Remove Programs with insufficient memory" in Chapter 17th ).
C) skip back to step 2.

 

Because step 11A uses a much higher value than the previously used value for scanning, this step is easy to fail. In fact, step 11A is executed successfully only when another kernel control path has killed a process to recycle its memory. Therefore, step 11A avoids two innocent processes (not one) from being killed.

 

Release a group of pages

 

The management area distributor is also responsible for releasing the page box; it is much easier to release memory than to allocate it.

 

All kernel macros and functions in the release page depend on the _ free_pages () function. The parameter it receives is the address (PAGE) of the page descriptor of the first page box to be released and the logarithm (Order) of the number of consecutive page boxes to be released ). Perform the following steps:
1. Check whether the box on the first page is actually in dynamic memory (its pg_reserved flag is cleared to 0); if not, it is terminated.
2. Reduce page-> _ count to use the counter value. If it is still greater than or equal to 0, it is terminated.
3. If order is equal to 0, this function calls free_hot_page () to release the page box to the hot cache of each CPU in the appropriate memory management area.
4. If order is greater than 0, it adds the page box to the local linked list, and calls the free_pages_bulk () function to release them to the partner System in the appropriate memory management area.

 

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.