Linux Kernel Architecture

(Jacob Rumans) #1

Chapter3:MemoryManagement


The data structure is mostly self-explanatory: When the kernel wants to allocate un-movable pages, but
the corresponding list is empty, then it falls back to reclaimable pages, then to movable pages, and finally
to the emergency reserve.

Global Variables and Auxiliary Functions


While page mobility grouping is always compiled into the kernel, it only makes sense if enough memory
that can be distributed across multiple migrate lists is present in a system. Since on each migrate list a
suitable amount of memory should be present, the kernel needs a notion of ‘‘suitable.’’Thisisprovided
by the two global variablespageblock_orderandpageblock_nr_pages. The first denotes an allocation
order that is considered to be ‘‘large,’’ andpageblock_nr_pagesdenotes the corresponding number of
pages for this allocation order. Usually the the page order is selected to be the order of huge pages if such
are provided by the architecture:

<pageblock-flags.h>
#define pageblock_order HUGETLB_PAGE_ORDER

On the IA-32 architecture, huge pages are 4 MiB in size, so each huge page consists of 1,024 regular pages
andHUGETLB_PAGE_ORDERis defined to be 10. The IA-64 architecture, in contrast, allows varying regular
and huge page sizes, so the value ofHUGETLB_PAGE_ORDERdepends on the kernel configuration.

If an architecture does not support huge pages, then the second highest allocation order is taken as a
large order:

<pageblock-flags.h>
#define pageblock_order (MAX_ORDER-1)

Page migration will not provide any benefits if each migrate type cannot at least be equipped with one
large page block, so the feature is turned off by the kernel if too little memory is available. This is checked
in the functionbuild_all_zonelists, which is used to initialize the zone lists. If not enough memory is
available, the global variablepage_group_by_mobilityis set to 0, otherwise to 1.^18

How does the kernel know to which migrate type a given allocation belongs? As you will see
in Section 3.5.4, details about each memory allocation are specified by anallocation mask.Thekernel
provides two flags that signal that the allocated memory will be movable (__GFP_MOVABLE) or reclaimable
(__GFP_RECLAIMABLE). If none of these flags is specified, the allocation is assumed to be non-movable.
The following auxiliary function converts between allocation flags and their corresponding migrate
types:

<gfp.h>
static inline int allocflags_to_migratetype(gfp_t gfp_flags)
{
if (unlikely(page_group_by_mobility_disabled))
return MIGRATE_UNMOVABLE;

/* Group based on mobility */
return (((gfp_flags & __GFP_MOVABLE) != 0) << 1) |
((gfp_flags & __GFP_RECLAIMABLE) != 0);
}

(^18) Note that systems not only with little memory but also with extremely large page sizes can be affected by this since the check is
performed on a pages-per-list basis.

Free download pdf