Chapter3:MemoryManagement
if ((alloc_flags & ALLOC_CPUSET) &&
!cpuset_zone_allowed_softwall(zone, gfp_mask))
continue;
if (!(alloc_flags & ALLOC_NO_WATERMARKS)) {
unsigned long mark;
if (alloc_flags & ALLOC_WMARK_MIN)
mark = zone->pages_min;
else if (alloc_flags & ALLOC_WMARK_LOW)
mark = zone->pages_low;
else
mark = zone->pages_high;
if (!zone_watermark_ok(zone, order, mark,
classzone_idx, alloc_flags))
continue;
}
...
A pointer to the fallback list is passed as parameter to the function. This list determines the order in
which the other zones (and nodes) of the system are scanned if no pages are free in the desired zone. The
layout and meaning of this data structure are discussed extensively in Section 3.4.1.
The subsequentdoloop does more or less exactly what would intuitively be expected as the simplest
way of finding a suitable free memory block — it iterates over all zones of the fallback list. First of all,
theALLOC_*flags are interpreted (cpuset_zone_allowed_softwallis another helper function to check
whether the given zone belongs to the allowed CPUs for the process).zone_watermark_okthen checks
each zone to find out if enough pages are present and attempts to allocate a contiguous memory block. If
one of these two conditions is not met — either there are not enough free pages or the request cannot be
satisfied withcontiguouspages — the next zone in the fallback list is checked in the same way.
If the zone is suitable for the current request,buffered_rmqueuetries to remove the desired number of
pages from it:
mm/page_alloc.c
...
page = buffered_rmqueue(*z, order, gfp_mask);
if (page) {
zone_statistics(zonelist, *z);
break;
}
} while (*(++z) != NULL);
return page;
}
We take a closer look atbuffered_rmqueuein Section 3.5.4. If page removal was successful, the page(s)
can be returned to the caller. Otherwise, the loop starts anew, and the next best zone is selected.
Allocation Control
As mentioned above,__alloc_pagesis the main function of the buddy system. Now that we have dealt
with all preparatory work and described all possible flags, we turn our attention to the relatively complex
implementation of the function that is one of the lengthier parts of the kernel. Complexity arises above