diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/Kconfig | 19 | ||||
-rw-r--r-- | mm/sparse.c | 26 |
2 files changed, 33 insertions, 12 deletions
diff --git a/mm/Kconfig b/mm/Kconfig index fc644c5c065d..4e9937ac3529 100644 --- a/mm/Kconfig +++ b/mm/Kconfig | |||
@@ -91,10 +91,23 @@ config HAVE_MEMORY_PRESENT | |||
91 | depends on ARCH_HAVE_MEMORY_PRESENT || SPARSEMEM | 91 | depends on ARCH_HAVE_MEMORY_PRESENT || SPARSEMEM |
92 | 92 | ||
93 | # | 93 | # |
94 | # SPARSEMEM_EXTREME (which is the default) does some bootmem | ||
95 | # allocations when memory_present() is called. If this can not | ||
96 | # be done on your architecture, select this option. However, | ||
97 | # statically allocating the mem_section[] array can potentially | ||
98 | # consume vast quantities of .bss, so be careful. | ||
99 | # | ||
100 | # This option will also potentially produce smaller runtime code | ||
101 | # with gcc 3.4 and later. | ||
102 | # | ||
103 | config SPARSEMEM_STATIC | ||
104 | def_bool n | ||
105 | |||
106 | # | ||
94 | # Architectecture platforms which require a two level mem_section in SPARSEMEM | 107 | # Architectecture platforms which require a two level mem_section in SPARSEMEM |
95 | # must select this option. This is usually for architecture platforms with | 108 | # must select this option. This is usually for architecture platforms with |
96 | # an extremely sparse physical address space. | 109 | # an extremely sparse physical address space. |
97 | # | 110 | # |
98 | config ARCH_SPARSEMEM_EXTREME | 111 | config SPARSEMEM_EXTREME |
99 | def_bool n | 112 | def_bool y |
100 | depends on SPARSEMEM && 64BIT | 113 | depends on SPARSEMEM && !SPARSEMEM_STATIC |
diff --git a/mm/sparse.c b/mm/sparse.c index b2b456bf0a5d..fa01292157a9 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
@@ -13,28 +13,36 @@ | |||
13 | * | 13 | * |
14 | * 1) mem_section - memory sections, mem_map's for valid memory | 14 | * 1) mem_section - memory sections, mem_map's for valid memory |
15 | */ | 15 | */ |
16 | #ifdef CONFIG_ARCH_SPARSEMEM_EXTREME | 16 | #ifdef CONFIG_SPARSEMEM_EXTREME |
17 | struct mem_section *mem_section[NR_SECTION_ROOTS] | 17 | struct mem_section *mem_section[NR_SECTION_ROOTS] |
18 | ____cacheline_maxaligned_in_smp; | 18 | ____cacheline_maxaligned_in_smp; |
19 | #else | ||
20 | struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT] | ||
21 | ____cacheline_maxaligned_in_smp; | ||
22 | #endif | ||
23 | EXPORT_SYMBOL(mem_section); | ||
24 | |||
25 | static void sparse_alloc_root(unsigned long root, int nid) | ||
26 | { | ||
27 | #ifdef CONFIG_SPARSEMEM_EXTREME | ||
28 | mem_section[root] = alloc_bootmem_node(NODE_DATA(nid), PAGE_SIZE); | ||
29 | #endif | ||
30 | } | ||
19 | 31 | ||
20 | static void sparse_index_init(unsigned long section, int nid) | 32 | static void sparse_index_init(unsigned long section, int nid) |
21 | { | 33 | { |
22 | unsigned long root = SECTION_TO_ROOT(section); | 34 | unsigned long root = SECTION_NR_TO_ROOT(section); |
23 | 35 | ||
24 | if (mem_section[root]) | 36 | if (mem_section[root]) |
25 | return; | 37 | return; |
26 | mem_section[root] = alloc_bootmem_node(NODE_DATA(nid), PAGE_SIZE); | 38 | |
39 | sparse_alloc_root(root, nid); | ||
40 | |||
27 | if (mem_section[root]) | 41 | if (mem_section[root]) |
28 | memset(mem_section[root], 0, PAGE_SIZE); | 42 | memset(mem_section[root], 0, PAGE_SIZE); |
29 | else | 43 | else |
30 | panic("memory_present: NO MEMORY\n"); | 44 | panic("memory_present: NO MEMORY\n"); |
31 | } | 45 | } |
32 | #else | ||
33 | struct mem_section mem_section[NR_MEM_SECTIONS] | ||
34 | ____cacheline_maxaligned_in_smp; | ||
35 | #endif | ||
36 | EXPORT_SYMBOL(mem_section); | ||
37 | |||
38 | /* Record a memory area against a node. */ | 46 | /* Record a memory area against a node. */ |
39 | void memory_present(int nid, unsigned long start, unsigned long end) | 47 | void memory_present(int nid, unsigned long start, unsigned long end) |
40 | { | 48 | { |