Signed-off-by: Dave Hansen Index: linux-2.6.13/mm/sparse.c =================================================================== --- linux-2.6.13.orig/mm/sparse.c 2005-08-30 11:58:56.000000000 -0700 +++ linux-2.6.13/mm/sparse.c 2005-08-30 11:58:57.000000000 -0700 @@ -16,6 +16,18 @@ #ifdef CONFIG_ARCH_SPARSEMEM_EXTREME struct mem_section *mem_section[NR_SECTION_ROOTS] ____cacheline_maxaligned_in_smp; +#else +struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT] + ____cacheline_maxaligned_in_smp; +#endif +EXPORT_SYMBOL(mem_section); + +static void sparse_alloc_root(unsigned long root) +{ +#ifdef CONFIG_ARCH_SPARSEMEM_EXTREME + mem_section[root] = alloc_bootmem_node(NODE_DATA(nid), PAGE_SIZE); +#endif +} static void sparse_index_init(unsigned long section, int nid) { @@ -23,18 +35,14 @@ static void sparse_index_init(unsigned l if (mem_section[root]) return; - mem_section[root] = alloc_bootmem_node(NODE_DATA(nid), PAGE_SIZE); + + sparse_alloc_root(root); + if (mem_section[root]) memset(mem_section[root], 0, PAGE_SIZE); else panic("memory_present: NO MEMORY\n"); } -#else -struct mem_section mem_section[NR_MEM_SECTIONS] - ____cacheline_maxaligned_in_smp; -#endif -EXPORT_SYMBOL(mem_section); - /* Record a memory area against a node. */ void memory_present(int nid, unsigned long start, unsigned long end) { Index: linux-2.6.13/include/linux/mmzone.h =================================================================== --- linux-2.6.13.orig/include/linux/mmzone.h 2005-08-30 11:58:56.000000000 -0700 +++ linux-2.6.13/include/linux/mmzone.h 2005-08-30 11:58:57.000000000 -0700 @@ -507,19 +507,6 @@ static inline struct mem_section *__nr_t return &mem_section[SECTION_TO_ROOT(nr)][nr & SECTION_ROOT_MASK]; } -#else - -extern struct mem_section mem_section[NR_MEM_SECTIONS]; - -static inline struct mem_section *__nr_to_section(unsigned long nr) -{ - return &mem_section[nr]; -} - -#define sparse_index_init(_sec, _nid) do {} while (0) - -#endif - /* * We use the lower bits of the mem_map pointer to store * a little bit of information. There should be at least Index: linux-2.6.13/mm/Kconfig =================================================================== --- linux-2.6.13.orig/mm/Kconfig 2005-08-30 11:58:56.000000000 -0700 +++ linux-2.6.13/mm/Kconfig 2005-08-30 11:58:57.000000000 -0700 @@ -91,10 +91,23 @@ config HAVE_MEMORY_PRESENT depends on ARCH_HAVE_MEMORY_PRESENT || SPARSEMEM # +# SPARSEMEM_EXTREME (which is the default) does some bootmem +# allocations when memory_present() is called. If this can not +# be done on your architecture, select this option. However, +# statically allocating the mem_section[] array can potentially +# consume vast quantities of .bss, so be careful. +# +# This option will also potentially produce smaller runtime code +# with gcc 3.4 and later. +# +config SPARSEMEM_STATIC + def_bool n + +# # Architectecture platforms which require a two level mem_section in SPARSEMEM # must select this option. This is usually for architecture platforms with # an extremely sparse physical address space. # -config ARCH_SPARSEMEM_EXTREME - def_bool n - depends on SPARSEMEM && 64BIT +config SPARSEMEM_EXTREME + def_bool y + depends on SPARSEMEM && !SPARSEMEM_STATIC Index: linux-2.6.13/arch/i386/Kconfig =================================================================== --- linux-2.6.13.orig/arch/i386/Kconfig 2005-08-28 16:41:01.000000000 -0700 +++ linux-2.6.13/arch/i386/Kconfig 2005-08-30 11:58:57.000000000 -0700 @@ -754,6 +754,7 @@ config NUMA depends on SMP && HIGHMEM64G && (X86_NUMAQ || X86_GENERICARCH || (X86_SUMMIT && ACPI)) default n if X86_PC default y if (X86_NUMAQ || X86_SUMMIT) + select SPARSEMEM_STATIC # Need comments to help the hapless user trying to turn on NUMA support comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support"