Commit e7f21c70 authored by Keith Mannthey's avatar Keith Mannthey Committed by Linus Torvalds

[PATCH] Allow hot-add enabled i386 NUMA box to boot

Dave Hanson mentioned I should send this patch to you.  I posted it to
linux-mm a while ago without complaint.  This patch solves a simple
problem related to the interpretation on the SRAT table and the info
found in the e820.

When a possible hot-add area is exposed on my box (IBM x445 with hot
add enabled in the bios) my SRAT table correctly exposed a new node from
the end of my physical memory to 64gb.  In the present kernels the numa
KVA areas (based on the SRAT) are calculated before find_max_pfn.  The
remap area is created for this large non-populated zone and the system
dies a while later during bootup.

I believe the correct things to do (as did the hot-plug community) the
correct thing to do is the keep the node_start_end_pfn data structures
focuses on memory that is in the system.  That is all this patch does.
It ignores any node data (correctly reported by the SRAT) that is above
the e820 end of memory.    

Signed-off-by: <kmannth@us.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent acd41695
......@@ -203,6 +203,15 @@ static unsigned long calculate_numa_remap_pages(void)
for_each_online_node(nid) {
if (nid == 0)
continue;
/*
* The acpi/srat node info can show hot-add memroy zones
* where memory could be added but not currently present.
*/
if (node_start_pfn[nid] > max_pfn)
continue;
if (node_end_pfn[nid] > max_pfn)
node_end_pfn[nid] = max_pfn;
/* calculate the size of the mem_map needed in bytes */
size = (node_end_pfn[nid] - node_start_pfn[nid] + 1)
* sizeof(struct page) + sizeof(pg_data_t);
......@@ -265,12 +274,12 @@ unsigned long __init setup_memory(void)
printk("\n");
}
find_max_pfn();
reserve_pages = calculate_numa_remap_pages();
/* partially used pages are not usable - thus round upwards */
system_start_pfn = min_low_pfn = PFN_UP(init_pg_tables_end);
find_max_pfn();
system_max_low_pfn = max_low_pfn = find_max_low_pfn() - reserve_pages;
printk("reserve_pages = %ld find_max_low_pfn() ~ %ld\n",
reserve_pages, max_low_pfn + reserve_pages);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment