Linux Kernel Architecture

(Jacob Rumans) #1

Chapter3:MemoryManagement


If the node is equipped with memory as indicated by thenode_present_pagesfield, this is
reflected in the node bitmap by setting theN_HIGH_MEMORYflag. Recall from Section 3.2.2 that the
flag — despite its name — only signals thateitherregularorhigh memory is present on the node, so
check_for_regular_memorychecks if pages in any zone belowZONE_HIGHMEMare present and sets the
flagN_NORMAL_MEMORYin the node bitmap accordingly.

Creating Data Structures forEach Node


Once the zone boundaries have been determined,free_area_init_nodescreates the data structures for
the individual zones iteratively by callingfree_area_init_node. Several helper functions are required
for this purpose.

calculate_node_totalpagesfirst calculates the total number of pages in the node by summing up the
pages in the individual zones. In the case of contiguous memory, this could be done inzones_size_init,
butcalculate_zone_totalpagesalso takes holes in the zone into account. The number of pages found
for each node is output in a short message when the system is booted. The example below is taken from
a UMA system with 512 MiB of RAM.

wolfgang@meitner>dmesg
...
On node 0 totalpages: 131056
...

alloc_node_mem_mapis responsible for initializing a simple but nevertheless very important data struc-
ture. As noted above, there is an instance ofstruct pagefor every physical memory page in the system.
Initialization of this structure is performed byalloc_node_mem_map.

mm/page_alloc.c
static void __init_refok alloc_node_mem_map(struct pglist_data *pgdat)
{
/* Skip empty nodes */
if (!pgdat->node_spanned_pages)
return;

if (!pgdat->node_mem_map) {
unsigned long size, start, end;
struct page *map;

start = pgdat->node_start_pfn & ~(MAX_ORDER_NR_PAGES - 1);
end = pgdat->node_start_pfn + pgdat->node_spanned_pages;
end = ALIGN(end, MAX_ORDER_NR_PAGES);
size = (end - start) * sizeof(struct page);
map = alloc_remap(pgdat->node_id, size);
if (!map)
map = alloc_bootmem_node(pgdat, size);
pgdat->node_mem_map = map + (pgdat->node_start_pfn - start);
}

if (pgdat == NODE_DATA(0))
mem_map = NODE_DATA(0)->node_mem_map;
}
Free download pdf