Chapter3:MemoryManagement
Interestingly, there is no__GFP_NORMALconstant, although the main burden of allocation falls on this
zone. The kernel takes account of this fact by providing a function that calculates the highest memory
zone compatible with the given allocation flags. Allocations can then be made from this zone and from
those below it.
mm/page_alloc.c
static inline enum zone_type gfp_zone(gfp_t flags)
{
#ifdef CONFIG_ZONE_DMA
if (flags & __GFP_DMA)
return ZONE_DMA;
#endif
#ifdef CONFIG_ZONE_DMA32
if (flags & __GFP_DMA32)
return ZONE_DMA32;
#endif
if ((flags & (__GFP_HIGHMEM | __GFP_MOVABLE)) ==
(__GFP_HIGHMEM | __GFP_MOVABLE))
return ZONE_MOVABLE;
#ifdef CONFIG_HIGHMEM
if (flags & __GFP_HIGHMEM)
return ZONE_HIGHMEM;
#endif
return ZONE_NORMAL;
}
Because the way in which the zone modifiers are interpreted may not immediately appear to be intuitive,
Table 3-7 shows an example of the function results when the zones for DMA and DMA32 are identical.
Assume that the__GFP_MOVABLEmodifier is not set in the following:
If bothGFP_DMAand__GFP_HIGHMEMarenotset,ZONE_NORMALis first scanned, followed byZONE_DMA.If
GFP_HIGHMEMis set andGFP_DMAis not set, the result is that all three zones are scanned starting with
ZONE_HIGHMEM.IfGFP_DMAis set, it is irrelevant to the kernel whetherGFP_HIGHMEMis set or not. Only
ZONE_DMAis used in both cases. This is reasonable because the simultaneous use ofGFP_HIGHMEMand
__GFP_DMAmakes no sense. Highmem is never DMA-suitable.
Table 3-7: Correlation between Zone Modifiers and Zones Scanned
Modifier Zones scanned
Empty ZONE_NORMAL,ZONE_DMA
__GFP_DMA ZONE_DMA
__GFP_DMA&__GFP_HIGHMEM ZONE_DMA
__GFP_HIGHMEM ZONE_HIGHMEM,ZONE_NORMAL,
ZONE_DMA