Linux Kernel Architecture

(Jacob Rumans) #1

Chapter3:MemoryManagement


ThecallisframedbycodethatsetstheabovePF_MEMALLOCflag. It may be necessary for
try_to_free_pagesto allocate new memory for its own work. As this additional memory is
needed to obtain fresh memory (a rather paradoxical situation), the process should, of course, enjoy
maximum priority in terms of memory management from this point on — this is achieved by setting the
above flag.


Recall that only a few lines ago, a very aggressive attempt at memory allocation was tried conditioned on
PF_MEMALLOCbeing set.

Besides, setting the flag ensures thattry_to_free_pagesis not called recursively because__alloc_pages
will already have aborted before ifPF_MEMALLOCis set.


try_to_free_pagesis itself a lengthy and complex function whose implementation I won’t discuss
here. Instead, see Chapter 18, which includes a detailed description of the underlying mechanism. At the
moment, it is sufficient to know that the function selects pages not recently in very active use and writes
them to the swap area to free space in RAM memory. The number of freed pages bytry_to_free_pages
is returned as the result.


try_to_free_pagesacts only on the node containing the desired zone. All other
nodes are ignored.

If more than one page is to be allocated, pages from the per-CPU cache are brought back into the buddy
system:


mm/page_alloc.c
if (order != 0)
drain_all_local_pages();

How this is technically done is not of relevance here, so it is not necessary to discussdrainall
local_pagesin detail.


The next kernel action — could it be any different — is to invokeget_page_from_freelistto attempt
allocation again if some pages could be freed bytry_to_free_pages:


mm/page_alloc.c
if (likely(did_some_progress)) {
page = get_page_from_freelist(gfp_mask, order,
zonelist, alloc_flags);
if (page)
goto got_pg;
} else if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY)) {
...

If the kernel may perform calls that affect the VFS layer and is not hindered byGFP_NORETRY, the out-of-
memory (OOM) killer is invoked:


mm/page_alloc.c
/* The OOM killer will not help higher order allocs so fail */
if (order > PAGE_ALLOC_COSTLY_ORDER) {
clear_zonelist_oom(zonelist);
Free download pdf