diff options
author | Yinghai Lu <yinghai@kernel.org> | 2010-07-28 01:43:02 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2010-08-04 22:56:33 -0400 |
commit | 10d0643988e976360eb3497dcafb55b393b8e480 (patch) | |
tree | fa8f614dd7ab2ffc2f94700451e6c9e6d26c702e | |
parent | f0b37fad9a63217c39997b2d2b31f44e3d8be727 (diff) |
memblock: Option for the architecture to put memblock into the .init section
Arch code can define ARCH_DISCARD_MEMBLOCK in asm/memblock.h,
which in turns causes memblock code and data to go respectively
into the .init and .initdata sections. This will be used by the
x86 architecture.
If ARCH_DISCARD_MEMBLOCK is defined, the debugfs files to inspect
the memblock arrays after boot are not created.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | include/linux/memblock.h | 8 | ||||
-rw-r--r-- | mm/memblock.c | 48 |
2 files changed, 32 insertions, 24 deletions
diff --git a/include/linux/memblock.h b/include/linux/memblock.h index c24b2784909..3978e6a8e82 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h | |||
@@ -149,6 +149,14 @@ static inline unsigned long memblock_region_pages(const struct memblock_region * | |||
149 | region++) | 149 | region++) |
150 | 150 | ||
151 | 151 | ||
152 | #ifdef ARCH_DISCARD_MEMBLOCK | ||
153 | #define __init_memblock __init | ||
154 | #define __initdata_memblock __initdata | ||
155 | #else | ||
156 | #define __init_memblock | ||
157 | #define __initdata_memblock | ||
158 | #endif | ||
159 | |||
152 | #endif /* CONFIG_HAVE_MEMBLOCK */ | 160 | #endif /* CONFIG_HAVE_MEMBLOCK */ |
153 | 161 | ||
154 | #endif /* __KERNEL__ */ | 162 | #endif /* __KERNEL__ */ |
diff --git a/mm/memblock.c b/mm/memblock.c index cb520df2a41..a17faea37d4 100644 --- a/mm/memblock.c +++ b/mm/memblock.c | |||
@@ -20,12 +20,12 @@ | |||
20 | #include <linux/seq_file.h> | 20 | #include <linux/seq_file.h> |
21 | #include <linux/memblock.h> | 21 | #include <linux/memblock.h> |
22 | 22 | ||
23 | struct memblock memblock; | 23 | struct memblock memblock __initdata_memblock; |
24 | 24 | ||
25 | int memblock_debug; | 25 | int memblock_debug __initdata_memblock; |
26 | int memblock_can_resize; | 26 | int memblock_can_resize __initdata_memblock; |
27 | static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS + 1]; | 27 | static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS + 1] __initdata_memblock; |
28 | static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS + 1]; | 28 | static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS + 1] __initdata_memblock; |
29 | 29 | ||
30 | /* inline so we don't get a warning when pr_debug is compiled out */ | 30 | /* inline so we don't get a warning when pr_debug is compiled out */ |
31 | static inline const char *memblock_type_name(struct memblock_type *type) | 31 | static inline const char *memblock_type_name(struct memblock_type *type) |
@@ -42,23 +42,23 @@ static inline const char *memblock_type_name(struct memblock_type *type) | |||
42 | * Address comparison utilities | 42 | * Address comparison utilities |
43 | */ | 43 | */ |
44 | 44 | ||
45 | static phys_addr_t memblock_align_down(phys_addr_t addr, phys_addr_t size) | 45 | static phys_addr_t __init_memblock memblock_align_down(phys_addr_t addr, phys_addr_t size) |
46 | { | 46 | { |
47 | return addr & ~(size - 1); | 47 | return addr & ~(size - 1); |
48 | } | 48 | } |
49 | 49 | ||
50 | static phys_addr_t memblock_align_up(phys_addr_t addr, phys_addr_t size) | 50 | static phys_addr_t __init_memblock memblock_align_up(phys_addr_t addr, phys_addr_t size) |
51 | { | 51 | { |
52 | return (addr + (size - 1)) & ~(size - 1); | 52 | return (addr + (size - 1)) & ~(size - 1); |
53 | } | 53 | } |
54 | 54 | ||
55 | static unsigned long memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1, | 55 | static unsigned long __init_memblock memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1, |
56 | phys_addr_t base2, phys_addr_t size2) | 56 | phys_addr_t base2, phys_addr_t size2) |
57 | { | 57 | { |
58 | return ((base1 < (base2 + size2)) && (base2 < (base1 + size1))); | 58 | return ((base1 < (base2 + size2)) && (base2 < (base1 + size1))); |
59 | } | 59 | } |
60 | 60 | ||
61 | static long memblock_addrs_adjacent(phys_addr_t base1, phys_addr_t size1, | 61 | static long __init_memblock memblock_addrs_adjacent(phys_addr_t base1, phys_addr_t size1, |
62 | phys_addr_t base2, phys_addr_t size2) | 62 | phys_addr_t base2, phys_addr_t size2) |
63 | { | 63 | { |
64 | if (base2 == base1 + size1) | 64 | if (base2 == base1 + size1) |
@@ -69,7 +69,7 @@ static long memblock_addrs_adjacent(phys_addr_t base1, phys_addr_t size1, | |||
69 | return 0; | 69 | return 0; |
70 | } | 70 | } |
71 | 71 | ||
72 | static long memblock_regions_adjacent(struct memblock_type *type, | 72 | static long __init_memblock memblock_regions_adjacent(struct memblock_type *type, |
73 | unsigned long r1, unsigned long r2) | 73 | unsigned long r1, unsigned long r2) |
74 | { | 74 | { |
75 | phys_addr_t base1 = type->regions[r1].base; | 75 | phys_addr_t base1 = type->regions[r1].base; |
@@ -80,7 +80,7 @@ static long memblock_regions_adjacent(struct memblock_type *type, | |||
80 | return memblock_addrs_adjacent(base1, size1, base2, size2); | 80 | return memblock_addrs_adjacent(base1, size1, base2, size2); |
81 | } | 81 | } |
82 | 82 | ||
83 | long memblock_overlaps_region(struct memblock_type *type, phys_addr_t base, phys_addr_t size) | 83 | long __init_memblock memblock_overlaps_region(struct memblock_type *type, phys_addr_t base, phys_addr_t size) |
84 | { | 84 | { |
85 | unsigned long i; | 85 | unsigned long i; |
86 | 86 | ||
@@ -162,7 +162,7 @@ static phys_addr_t __init memblock_find_base(phys_addr_t size, phys_addr_t align | |||
162 | return MEMBLOCK_ERROR; | 162 | return MEMBLOCK_ERROR; |
163 | } | 163 | } |
164 | 164 | ||
165 | static void memblock_remove_region(struct memblock_type *type, unsigned long r) | 165 | static void __init_memblock memblock_remove_region(struct memblock_type *type, unsigned long r) |
166 | { | 166 | { |
167 | unsigned long i; | 167 | unsigned long i; |
168 | 168 | ||
@@ -174,7 +174,7 @@ static void memblock_remove_region(struct memblock_type *type, unsigned long r) | |||
174 | } | 174 | } |
175 | 175 | ||
176 | /* Assumption: base addr of region 1 < base addr of region 2 */ | 176 | /* Assumption: base addr of region 1 < base addr of region 2 */ |
177 | static void memblock_coalesce_regions(struct memblock_type *type, | 177 | static void __init_memblock memblock_coalesce_regions(struct memblock_type *type, |
178 | unsigned long r1, unsigned long r2) | 178 | unsigned long r1, unsigned long r2) |
179 | { | 179 | { |
180 | type->regions[r1].size += type->regions[r2].size; | 180 | type->regions[r1].size += type->regions[r2].size; |
@@ -184,7 +184,7 @@ static void memblock_coalesce_regions(struct memblock_type *type, | |||
184 | /* Defined below but needed now */ | 184 | /* Defined below but needed now */ |
185 | static long memblock_add_region(struct memblock_type *type, phys_addr_t base, phys_addr_t size); | 185 | static long memblock_add_region(struct memblock_type *type, phys_addr_t base, phys_addr_t size); |
186 | 186 | ||
187 | static int memblock_double_array(struct memblock_type *type) | 187 | static int __init_memblock memblock_double_array(struct memblock_type *type) |
188 | { | 188 | { |
189 | struct memblock_region *new_array, *old_array; | 189 | struct memblock_region *new_array, *old_array; |
190 | phys_addr_t old_size, new_size, addr; | 190 | phys_addr_t old_size, new_size, addr; |
@@ -255,13 +255,13 @@ static int memblock_double_array(struct memblock_type *type) | |||
255 | return 0; | 255 | return 0; |
256 | } | 256 | } |
257 | 257 | ||
258 | extern int __weak memblock_memory_can_coalesce(phys_addr_t addr1, phys_addr_t size1, | 258 | extern int __init_memblock __weak memblock_memory_can_coalesce(phys_addr_t addr1, phys_addr_t size1, |
259 | phys_addr_t addr2, phys_addr_t size2) | 259 | phys_addr_t addr2, phys_addr_t size2) |
260 | { | 260 | { |
261 | return 1; | 261 | return 1; |
262 | } | 262 | } |
263 | 263 | ||
264 | static long memblock_add_region(struct memblock_type *type, phys_addr_t base, phys_addr_t size) | 264 | static long __init_memblock memblock_add_region(struct memblock_type *type, phys_addr_t base, phys_addr_t size) |
265 | { | 265 | { |
266 | unsigned long coalesced = 0; | 266 | unsigned long coalesced = 0; |
267 | long adjacent, i; | 267 | long adjacent, i; |
@@ -348,13 +348,13 @@ static long memblock_add_region(struct memblock_type *type, phys_addr_t base, ph | |||
348 | return 0; | 348 | return 0; |
349 | } | 349 | } |
350 | 350 | ||
351 | long memblock_add(phys_addr_t base, phys_addr_t size) | 351 | long __init_memblock memblock_add(phys_addr_t base, phys_addr_t size) |
352 | { | 352 | { |
353 | return memblock_add_region(&memblock.memory, base, size); | 353 | return memblock_add_region(&memblock.memory, base, size); |
354 | 354 | ||
355 | } | 355 | } |
356 | 356 | ||
357 | static long __memblock_remove(struct memblock_type *type, phys_addr_t base, phys_addr_t size) | 357 | static long __init_memblock __memblock_remove(struct memblock_type *type, phys_addr_t base, phys_addr_t size) |
358 | { | 358 | { |
359 | phys_addr_t rgnbegin, rgnend; | 359 | phys_addr_t rgnbegin, rgnend; |
360 | phys_addr_t end = base + size; | 360 | phys_addr_t end = base + size; |
@@ -402,7 +402,7 @@ static long __memblock_remove(struct memblock_type *type, phys_addr_t base, phys | |||
402 | return memblock_add_region(type, end, rgnend - end); | 402 | return memblock_add_region(type, end, rgnend - end); |
403 | } | 403 | } |
404 | 404 | ||
405 | long memblock_remove(phys_addr_t base, phys_addr_t size) | 405 | long __init_memblock memblock_remove(phys_addr_t base, phys_addr_t size) |
406 | { | 406 | { |
407 | return __memblock_remove(&memblock.memory, base, size); | 407 | return __memblock_remove(&memblock.memory, base, size); |
408 | } | 408 | } |
@@ -568,7 +568,7 @@ phys_addr_t __init memblock_phys_mem_size(void) | |||
568 | return memblock.memory_size; | 568 | return memblock.memory_size; |
569 | } | 569 | } |
570 | 570 | ||
571 | phys_addr_t memblock_end_of_DRAM(void) | 571 | phys_addr_t __init_memblock memblock_end_of_DRAM(void) |
572 | { | 572 | { |
573 | int idx = memblock.memory.cnt - 1; | 573 | int idx = memblock.memory.cnt - 1; |
574 | 574 | ||
@@ -655,7 +655,7 @@ int memblock_is_region_memory(phys_addr_t base, phys_addr_t size) | |||
655 | memblock.reserved.regions[idx].size) >= (base + size); | 655 | memblock.reserved.regions[idx].size) >= (base + size); |
656 | } | 656 | } |
657 | 657 | ||
658 | int memblock_is_region_reserved(phys_addr_t base, phys_addr_t size) | 658 | int __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t size) |
659 | { | 659 | { |
660 | return memblock_overlaps_region(&memblock.reserved, base, size) >= 0; | 660 | return memblock_overlaps_region(&memblock.reserved, base, size) >= 0; |
661 | } | 661 | } |
@@ -666,7 +666,7 @@ void __init memblock_set_current_limit(phys_addr_t limit) | |||
666 | memblock.current_limit = limit; | 666 | memblock.current_limit = limit; |
667 | } | 667 | } |
668 | 668 | ||
669 | static void memblock_dump(struct memblock_type *region, char *name) | 669 | static void __init_memblock memblock_dump(struct memblock_type *region, char *name) |
670 | { | 670 | { |
671 | unsigned long long base, size; | 671 | unsigned long long base, size; |
672 | int i; | 672 | int i; |
@@ -682,7 +682,7 @@ static void memblock_dump(struct memblock_type *region, char *name) | |||
682 | } | 682 | } |
683 | } | 683 | } |
684 | 684 | ||
685 | void memblock_dump_all(void) | 685 | void __init_memblock memblock_dump_all(void) |
686 | { | 686 | { |
687 | if (!memblock_debug) | 687 | if (!memblock_debug) |
688 | return; | 688 | return; |
@@ -748,7 +748,7 @@ static int __init early_memblock(char *p) | |||
748 | } | 748 | } |
749 | early_param("memblock", early_memblock); | 749 | early_param("memblock", early_memblock); |
750 | 750 | ||
751 | #ifdef CONFIG_DEBUG_FS | 751 | #if defined(CONFIG_DEBUG_FS) && !defined(ARCH_DISCARD_MEMBLOCK) |
752 | 752 | ||
753 | static int memblock_debug_show(struct seq_file *m, void *private) | 753 | static int memblock_debug_show(struct seq_file *m, void *private) |
754 | { | 754 | { |