Article directory
In the [Linux Kernel Memory Management] Physical Allocation Page ② ( __alloc_pages_nodemask function parameter analysis | __alloc_pages_nodemask function allocation physical page process) blog, the __alloc_pages_nodemask
function as follows:
First , according to the gfp_t gfp_mask
allocation flag parameter, get the preferred "region type" and "migration type" of "memory node ";
Then , perform the "fast path" , the first allocation attempt uses a low watermark allocation;
If the above "fast path" assignment fails, then a "slow path" assignment is performed;
The above refers to "fast path" and "slow path" 2 22 physical page allocation methods;
Continue to the previous blog [Linux Kernel Memory Management] Physical Allocation Page ⑦ ( __alloc_pages_slowpath slow path call function source code analysis | judging page order | reading mems_allowed | allocation flag conversion) analysis Follow-up of the __alloc_pages_slowpath
slow path memory allocation call function part of the source code;
1. Get the preferred memory area
Get the "preferred memory area", if the acquisition fails, goto
jump to the nopage
label position to run the subsequent code;
/*
* We need to recalculate the starting point for the zonelist iterator
* because we might have used different nodemask in the fast path, or
* there was a cpuset modification and we are retrying - otherwise we
* could end up iterating over non-eligible zones endlessly.
*/
ac->preferred_zoneref = first_zones_zonelist(ac->zonelist,
ac->high_zoneidx, ac->nodemask);
if (!ac->preferred_zoneref->zone)
goto nopage;
Source code path: linux-4.12\mm\page_alloc.c #3731
2. Asynchronously reclaiming memory pages
Call a wake_all_kswapds
function to asynchronously recycle physical memory pages,
The asynchrony here is to recycle memory pages by waking up the "recycling thread" ;
if (gfp_mask & __GFP_KSWAPD_RECLAIM)
wake_all_kswapds(order, ac);
Source path: linux-4.12\mm\page_alloc.c #3736
3. The lowest water line is also allocated
call get_page_from_freelist
function to use "lowest watermark" for physical page allocation,
If the processing is successful, jump to the got_pg
label to execute;
/*
* The adjusted alloc_flags might result in immediate success, so try
* that first
*/
page = get_page_from_freelist(gfp_mask, order, alloc_flags, ac);
if (page)
goto got_pg;
Source code path: linux-4.12\mm\page_alloc.c #3743
Fourth, allocate memory directly
Apply for the order of physical page memory , meet the following 3 33 conditions:
can_direct_reclaim
(costly_order || (order > 0 && ac->migratetype != MIGRATE_MOVABLE))
!gfp_pfmemalloc_allowed(gfp_mask)
Execute the branch "directly allocate memory" operation;
/*
* For costly allocations, try direct compaction first, as it's likely
* that we have enough base pages and don't need to reclaim. For non-
* movable high-order allocations, do that as well, as compaction will
* try prevent permanent fragmentation by migrating from blocks of the
* same migratetype.
* Don't try this for allocations that are allowed to ignore
* watermarks, as the ALLOC_NO_WATERMARKS attempt didn't yet happen.
*/
if (can_direct_reclaim &&
(costly_order ||
(order > 0 && ac->migratetype != MIGRATE_MOVABLE))
&& !gfp_pfmemalloc_allowed(gfp_mask)) {
page = __alloc_pages_direct_compact(gfp_mask, order,
alloc_flags, ac,
INIT_COMPACT_PRIORITY,
&compact_result);
if (page)
goto got_pg;
/*
* Checks for costly allocations with __GFP_NORETRY, which
* includes THP page fault allocations
*/
if (costly_order && (gfp_mask & __GFP_NORETRY)) {
/*
* If compaction is deferred for high-order allocations,
* it is because sync compaction recently failed. If
* this is the case and the caller requested a THP
* allocation, we do not want to heavily disrupt the
* system, so we fail the allocation instead of entering
* direct reclaim.
*/
if (compact_result == COMPACT_DEFERRED)
goto nopage;
/*
* Looks like reclaim/compaction is worth trying, but
* sync compaction could be very expensive, so keep
* using async compaction.
*/
compact_priority = INIT_COMPACT_PRIORITY;
}
}
Source code path: linux-4.12\mm\page_alloc.c #3756