[PATCH] x86: replace shrink pages with remove_active_ranges

From: Yinghai Lu
Date: Thu Jun 12 2008 - 16:05:38 EST


in case we have kva before ramdisk on node, we still need to use
those ranges.

This fixes 32-bit NUMA crashes with less than 960 MB of RAM.

Signed-off-by: Yinghai Lu <yhlu.kernel@xxxxxxxxx>
Signed-off-by: Ingo Molnar <mingo@xxxxxxx>

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 2154086..e35ad52 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3577,30 +3577,44 @@ void __init add_active_range(unsigned int nid, unsigned long start_pfn,
}

/**
- * shrink_active_range - Shrink an existing registered range of PFNs
+ * remove_active_range - Shrink an existing registered range of PFNs
* @nid: The node id the range is on that should be shrunk
- * @new_end_pfn: The new PFN of the range
+ * @start_pfn: The new PFN of the range
+ * @end_pfn: The new PFN of the range
*
* i386 with NUMA use alloc_remap() to store a node_mem_map on a local node.
* The map is kept near the end physical page range that has already been
* registered. This function allows an arch to shrink an existing registered
* range.
*/
-void __init shrink_active_range(unsigned int nid, unsigned long new_end_pfn)
+void __init remove_active_range(unsigned int nid, unsigned long start_pfn,
+ unsigned long end_pfn)
{
int i, j;
int removed = 0;

/* Find the old active region end and shrink */
for_each_active_range_index_in_nid(i, nid) {
- if (early_node_map[i].start_pfn >= new_end_pfn) {
+ if (early_node_map[i].start_pfn >= start_pfn &&
+ early_node_map[i].end_pfn <= end_pfn) {
/* clear it */
+ early_node_map[i].start_pfn = 0;
early_node_map[i].end_pfn = 0;
removed = 1;
continue;
}
- if (early_node_map[i].end_pfn > new_end_pfn) {
- early_node_map[i].end_pfn = new_end_pfn;
+ if (early_node_map[i].start_pfn < start_pfn &&
+ early_node_map[i].end_pfn > start_pfn) {
+ unsigned long temp_end_pfn = early_node_map[i].end_pfn;
+ early_node_map[i].end_pfn = start_pfn;
+ if (temp_end_pfn > end_pfn)
+ add_active_range(nid, end_pfn, temp_end_pfn);
+ continue;
+ }
+ if (early_node_map[i].start_pfn >= start_pfn &&
+ early_node_map[i].end_pfn > end_pfn &&
+ early_node_map[i].start_pfn < end_pfn) {
+ early_node_map[i].start_pfn = end_pfn;
continue;
}
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/