Registering Active Memory Regions

I noted above that initialization of the zone structures is an extensive task. Luckily this task is identical on all architectures. While kernel versions before 2.6.19 had to set up the required data structures on a per-architecture basis, the approach has become more modular in the meantime: The individual architectures only need to register a very simple map of all active memory regions, and generic code then generates the main data structures from this information.

Notice that individual architectures can still decide to set up all data structures on their own without relying on the generic framework provided by the kernel. Since both IA-32 and AMD64 let the kernel do the hard work, I will not discuss this possibility any further. Any architecture that wants to enjoy the possibilities offered by the generic framework must set the configuration option arch_populates_node_map. After all active memory regions are registered, the rest of the work is then performed by the generic kernel code.

An active memory region is simply a memory region that does not contain any holes. add_active_range must be used to register a region in the global variable early_node_map.

mm/page_alloc.c static struct node_active_region _meminitdata early_node_map[MAX_ACTIVE_REGIONS];

static int __meminitdata nr_nodemap_entries;

The number of currently registered regions is denoted by nr_nodemap_entries. The maximal number of distinct regions is given by max_active_regions. The value can be set by the architecture-specific code using config_max_active_regions. If not, the kernel allows for registering 256 active regions per default (or 50 regions per NUMA node if it is running on a system with more than 32 nodes). Each region is described by the following data structure:

struct node_active_region {

unsigned long start_pfn; unsigned long end_pfn; int nid;

start_pfn and end_pfn denote the first and last page frame in a continuous region, and nid is the NUMA ID of the node to which the memory belongs. UMA systems naturally set this to 0.

An active memory region is registered with add_active_range:

mm/page_alloc.c void _init add_active_range(unsigned int nid, unsigned long start_pfn, unsigned long end_pfn)

When two adjacent regions are registered, then add_active_regions ensures that they are merged to a single one. Besides, the function does not present any surprises.

Recall from Figures 3-12 and 3-13 that the function is called from zone_sizes_init on IA-32 systems, and in e820_register_active_regions on AMD64 systems. Thus I will briefly discuss these functions.

Continue reading here: Registering Regions on IA32

Was this article helpful?

0 0