[PATCH] fix SPARSEMEM extreme for ppc64

Dave Hansen haveblue at us.ibm.com
Sat Aug 27 00:23:40 EST 2005


From: Joel Schopp <jschopp at austin.ibm.com>
From: Arnd Bergmann <arnd at arndb.de>

SPARSEMEM EXTREME uses bootmem allocator, so the memory_present()
calls need to happen later.

The extra loop in the NUMA code probably needs to go, but that's
a cleanup for another day.

Applies to 2.6.13-rc6-mm2.

Signed-off-by: Dave Hansen <haveblue at us.ibm.com>
---

 Re_Lhms-devel_2.6.13-rc3-git7-mhp1-1.patch |    0 
 memhotplug-dave/arch/ppc64/mm/init.c       |   29 ++++++-------------
 memhotplug-dave/arch/ppc64/mm/numa.c       |   43 ++++++++++++++++++++++++++---
 memhotplug-dave/include/asm-ppc64/lmb.h    |   22 ++++++++++++++
 4 files changed, 72 insertions(+), 22 deletions(-)

diff -puN arch/ppc64/mm/init.c~B-sparse-183-ppc64-later-sparse-init arch/ppc64/mm/init.c
--- memhotplug/arch/ppc64/mm/init.c~B-sparse-183-ppc64-later-sparse-init	2005-08-24 10:35:40.000000000 -0700
+++ memhotplug-dave/arch/ppc64/mm/init.c	2005-08-24 10:35:40.000000000 -0700
@@ -557,27 +557,18 @@ void __init do_init_bootmem(void)
 	/* Add all physical memory to the bootmem map, mark each area
 	 * present.
 	 */
-	for (i=0; i < lmb.memory.cnt; i++) {
-		unsigned long physbase, size;
-		unsigned long start_pfn, end_pfn;
-
-		physbase = lmb.memory.region[i].physbase;
-		size = lmb.memory.region[i].size;
-
-		start_pfn = physbase >> PAGE_SHIFT;
-		end_pfn = start_pfn + (size >> PAGE_SHIFT);
-		memory_present(0, start_pfn, end_pfn);
-
-		free_bootmem(physbase, size);
-	}
+	for (i=0; i < lmb.memory.cnt; i++)
+		free_bootmem(lmb_start_pfn(&lmb.memory, i),
+			     lmb_size_bytes(&lmb.memory, i));
 
 	/* reserve the sections we're already using */
-	for (i=0; i < lmb.reserved.cnt; i++) {
-		unsigned long physbase = lmb.reserved.region[i].physbase;
-		unsigned long size = lmb.reserved.region[i].size;
-
-		reserve_bootmem(physbase, size);
-	}
+	for (i=0; i < lmb.reserved.cnt; i++)
+		reserve_bootmem(lmb_start_pfn(&lmb.reserved, i),
+				lmb_size_bytes(&lmb.reserved, i));
+
+	for (i=0; i < lmb.memory.cnt; i++)
+		memory_present(0, lmb_start_pfn(&lmb.memory, i),
+			       lmb_end_pfn(&lmb.memory, i));
 }
 
 /*
diff -puN include/asm-ppc64/lmb.h~B-sparse-183-ppc64-later-sparse-init include/asm-ppc64/lmb.h
--- memhotplug/include/asm-ppc64/lmb.h~B-sparse-183-ppc64-later-sparse-init	2005-08-24 10:35:40.000000000 -0700
+++ memhotplug-dave/include/asm-ppc64/lmb.h	2005-08-24 10:35:40.000000000 -0700
@@ -57,4 +57,26 @@ extern void lmb_dump_all(void);
 
 extern unsigned long io_hole_start;
 
+static inline unsigned long
+lmb_size_bytes(struct lmb_region *type, unsigned long region_nr)
+{
+	return type->region[region_nr].size;
+}
+static inline unsigned long
+lmb_size_pages(struct lmb_region *type, unsigned long region_nr)
+{
+	return lmb_size_bytes(type, region_nr) >> PAGE_SHIFT;
+}
+static inline unsigned long
+lmb_start_pfn(struct lmb_region *type, unsigned long region_nr)
+{
+	return type->region[region_nr].physbase >> PAGE_SHIFT;
+}
+static inline unsigned long
+lmb_end_pfn(struct lmb_region *type, unsigned long region_nr)
+{
+	return lmb_start_pfn(type, region_nr) +
+	       lmb_size_pages(type, region_nr);
+}
+
 #endif /* _PPC64_LMB_H */
diff -puN arch/ppc64/mm/numa.c~B-sparse-183-ppc64-later-sparse-init arch/ppc64/mm/numa.c
--- memhotplug/arch/ppc64/mm/numa.c~B-sparse-183-ppc64-later-sparse-init	2005-08-24 10:35:40.000000000 -0700
+++ memhotplug-dave/arch/ppc64/mm/numa.c	2005-08-24 10:35:40.000000000 -0700
@@ -440,8 +440,6 @@ new_range:
 		for (i = start ; i < (start+size); i += MEMORY_INCREMENT)
 			numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] =
 				numa_domain;
-		memory_present(numa_domain, start >> PAGE_SHIFT,
-						(start + size) >> PAGE_SHIFT);
 
 		if (--ranges)
 			goto new_range;
@@ -483,7 +481,6 @@ static void __init setup_nonnuma(void)
 
 	for (i = 0 ; i < top_of_ram; i += MEMORY_INCREMENT)
 		numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] = 0;
-	memory_present(0, 0, init_node_data[0].node_end_pfn);
 }
 
 static void __init dump_numa_topology(void)
@@ -695,6 +692,46 @@ new_range:
 						     size);
 			}
 		}
+		/*
+		 * This loop may look famaliar, but we have to do it again
+		 * after marking our reserved memory to mark memory present
+		 * for sparsemem.
+		 */
+		addr_cells = get_mem_addr_cells();
+		size_cells = get_mem_size_cells();
+		memory = NULL;
+		while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
+			unsigned long mem_start, mem_size;
+			int numa_domain, ranges;
+			unsigned int *memcell_buf;
+			unsigned int len;
+
+			memcell_buf = (unsigned int *)get_property(memory, "reg", &len);
+			if (!memcell_buf || len <= 0)
+				continue;
+
+			ranges = memory->n_addrs;	/* ranges in cell */
+new_range2:
+			mem_start = read_n_cells(addr_cells, &memcell_buf);
+			mem_size = read_n_cells(size_cells, &memcell_buf);
+			if (numa_enabled) {
+				numa_domain = of_node_numa_domain(memory);
+				if (numa_domain  >= MAX_NUMNODES)
+					numa_domain = 0;
+			} else
+				numa_domain =  0;
+
+			if (numa_domain != nid)
+				continue;
+
+			mem_size = numa_enforce_memory_limit(mem_start, mem_size);
+			memory_present(numa_domain, mem_start >> PAGE_SHIFT,
+				       (mem_start + mem_size) >> PAGE_SHIFT);
+
+			if (--ranges)		/* process all ranges in cell */
+				goto new_range2;
+		}
+
 	}
 }
 
diff -puN arch/ppc64/kernel/setup.c~B-sparse-183-ppc64-later-sparse-init arch/ppc64/kernel/setup.c
diff -puN Re_Lhms-devel_2.6.13-rc3-git7-mhp1-1.patch~B-sparse-183-ppc64-later-sparse-init Re_Lhms-devel_2.6.13-rc3-git7-mhp1-1.patch
_



More information about the Linuxppc64-dev mailing list