Chapter3:MemoryManagement
alloc_flags |= ALLOC_HIGH;
if (wait)
alloc_flags |= ALLOC_CPUSET;
page = get_page_from_freelist(gfp_mask, order, zonelist, alloc_flags);
if (page)
goto got_pg;
...
}
The kernel again iterates over all zones in the fallback list and invokes thewakeup_kswapdeach time. As
its name suggests, this function wakes thekswapddaemon responsible for swapping out pages. The task
of the swapping daemons is complex and is therefore described in a separate chapter (Chapter 18). All
you need note here is that fresh memory can be obtained by, for example, shrinking kernel caches and
page reclaim, that is, writing back or swapping out rarely used pages. Both measures are initiated by the
daemon.
Once the swapping daemon has been woken, the kernel starts a new attempt to find a suitable memory
chunk in one of the zones. This time it goes about its search more aggressively by adjusting the allocation
flags to more promising values for the particular situation. In doing so, it reduces the watermark to its
minimum value.ALLOC_HARDERis set for real-time processes and for calls with__GFP_WAITthat may not
go to sleep. A further call ofget_page_from_freelistwith a changed set of flags tries to obtain the
desired pages.
If this also fails, the kernel resorts to more drastic measures:
mm/page_alloc.c
rebalance:
if (((p->flags & PF_MEMALLOC) || unlikely(test_thread_flag(TIF_MEMDIE)))
&& !in_interrupt()) {
if (!(gfp_mask & __GFP_NOMEMALLOC)) {
nofail_alloc:
/* go through the zonelist yet again, ignoring mins */
page = get_page_from_freelist(gfp_mask, order,
zonelist, ALLOC_NO_WATERMARKS);
if (page)
goto got_pg;
if (gfp_mask & __GFP_NOFAIL) {
congestion_wait(WRITE, HZ/50);
goto nofail_alloc;
}
}
goto nopage;
}
...
IfPF_MEMALLOCis set or if theTIF_MEMDIEflag is set for the task (in both cases, the kernel must not
be in the interrupt context).get_page_from_freelisttries once more to obtain the desired pages,
but this time, watermarks are completely ignored becauseALLOC_NO_WATERMARKSis set. Whereas the
PF_MEMALLOCcondition usually only applies when the call for more memory originates from the allocator
itself,TIF_MEMDIEis set when a thread has just been hit by the OOM killer.