diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-05-10 07:17:25 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-05-10 07:17:25 -0400 |
commit | 5e2ff328c0668794ff408a4632f5b8a62827571f (patch) | |
tree | 53a35de722c44c6739541d6b9ae74970520191f9 /arch/sh | |
parent | 19d8f84f86af867abee174be8bf1e4941a59143d (diff) |
sh: rework memory limits to work with LMB.
This reworks the memory limit handling to tie in through the available
LMB infrastructure. This requires a bit of reordering as we need to have
all of the LMB reservations taken care of prior to establishing the
limits.
While we're at it, the crash kernel reservation semantics are reworked
so that we allocate from the bottom up and reduce the risk of having
to disable the memory limit due to a clash with the crash kernel
reservation.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/include/asm/page.h | 2 | ||||
-rw-r--r-- | arch/sh/kernel/machine_kexec.c | 20 | ||||
-rw-r--r-- | arch/sh/kernel/setup.c | 63 |
3 files changed, 40 insertions, 45 deletions
diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index 0152c040f6c3..fb703d120d09 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h | |||
@@ -49,7 +49,7 @@ | |||
49 | 49 | ||
50 | extern unsigned long shm_align_mask; | 50 | extern unsigned long shm_align_mask; |
51 | extern unsigned long max_low_pfn, min_low_pfn; | 51 | extern unsigned long max_low_pfn, min_low_pfn; |
52 | extern unsigned long memory_start, memory_end; | 52 | extern unsigned long memory_start, memory_end, memory_limit; |
53 | 53 | ||
54 | static inline unsigned long | 54 | static inline unsigned long |
55 | pages_do_alias(unsigned long addr1, unsigned long addr2) | 55 | pages_do_alias(unsigned long addr1, unsigned long addr2) |
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c index f0f049caa6e2..7f68fc0e89e8 100644 --- a/arch/sh/kernel/machine_kexec.c +++ b/arch/sh/kernel/machine_kexec.c | |||
@@ -169,7 +169,8 @@ void __init reserve_crashkernel(void) | |||
169 | 169 | ||
170 | crash_size = PAGE_ALIGN(crashk_res.end - crashk_res.start + 1); | 170 | crash_size = PAGE_ALIGN(crashk_res.end - crashk_res.start + 1); |
171 | if (!crashk_res.start) { | 171 | if (!crashk_res.start) { |
172 | crashk_res.start = lmb_alloc(crash_size, PAGE_SIZE); | 172 | unsigned long max = lmb_end_of_DRAM() - memory_limit; |
173 | crashk_res.start = __lmb_alloc_base(crash_size, PAGE_SIZE, max); | ||
173 | if (!crashk_res.start) { | 174 | if (!crashk_res.start) { |
174 | pr_err("crashkernel allocation failed\n"); | 175 | pr_err("crashkernel allocation failed\n"); |
175 | goto disable; | 176 | goto disable; |
@@ -183,15 +184,22 @@ void __init reserve_crashkernel(void) | |||
183 | } | 184 | } |
184 | } | 185 | } |
185 | 186 | ||
186 | pr_info("Reserving %ldMB of memory at %ldMB " | 187 | crashk_res.end = crashk_res.start + crash_size - 1; |
188 | |||
189 | /* | ||
190 | * Crash kernel trumps memory limit | ||
191 | */ | ||
192 | if ((lmb_end_of_DRAM() - memory_limit) <= crashk_res.end) { | ||
193 | memory_limit = 0; | ||
194 | pr_info("Disabled memory limit for crashkernel\n"); | ||
195 | } | ||
196 | |||
197 | pr_info("Reserving %ldMB of memory at 0x%08lx " | ||
187 | "for crashkernel (System RAM: %ldMB)\n", | 198 | "for crashkernel (System RAM: %ldMB)\n", |
188 | (unsigned long)(crash_size >> 20), | 199 | (unsigned long)(crash_size >> 20), |
189 | (unsigned long)(crashk_res.start >> 20), | 200 | (unsigned long)(crashk_res.start), |
190 | (unsigned long)(lmb_phys_mem_size() >> 20)); | 201 | (unsigned long)(lmb_phys_mem_size() >> 20)); |
191 | 202 | ||
192 | crashk_res.end = crashk_res.start + crash_size - 1; | ||
193 | insert_resource(&iomem_resource, &crashk_res); | ||
194 | |||
195 | return; | 203 | return; |
196 | 204 | ||
197 | disable: | 205 | disable: |
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 2c9ab2842765..f6a2db12ad78 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c | |||
@@ -95,6 +95,7 @@ unsigned long memory_start; | |||
95 | EXPORT_SYMBOL(memory_start); | 95 | EXPORT_SYMBOL(memory_start); |
96 | unsigned long memory_end = 0; | 96 | unsigned long memory_end = 0; |
97 | EXPORT_SYMBOL(memory_end); | 97 | EXPORT_SYMBOL(memory_end); |
98 | unsigned long memory_limit = 0; | ||
98 | 99 | ||
99 | static struct resource mem_resources[MAX_NUMNODES]; | 100 | static struct resource mem_resources[MAX_NUMNODES]; |
100 | 101 | ||
@@ -102,21 +103,12 @@ int l1i_cache_shape, l1d_cache_shape, l2_cache_shape; | |||
102 | 103 | ||
103 | static int __init early_parse_mem(char *p) | 104 | static int __init early_parse_mem(char *p) |
104 | { | 105 | { |
105 | unsigned long size; | 106 | if (!p) |
107 | return 1; | ||
106 | 108 | ||
107 | memory_start = (unsigned long)__va(__MEMORY_START); | 109 | memory_limit = PAGE_ALIGN(memparse(p, &p)); |
108 | size = memparse(p, &p); | ||
109 | |||
110 | if (size > __MEMORY_SIZE) { | ||
111 | printk(KERN_ERR | ||
112 | "Using mem= to increase the size of kernel memory " | ||
113 | "is not allowed.\n" | ||
114 | " Recompile the kernel with the correct value for " | ||
115 | "CONFIG_MEMORY_SIZE.\n"); | ||
116 | return 0; | ||
117 | } | ||
118 | 110 | ||
119 | memory_end = memory_start + size; | 111 | pr_notice("Memory limited to %ldMB\n", memory_limit >> 20); |
120 | 112 | ||
121 | return 0; | 113 | return 0; |
122 | } | 114 | } |
@@ -252,7 +244,7 @@ void __init do_init_bootmem(void) | |||
252 | { | 244 | { |
253 | unsigned long bootmap_size; | 245 | unsigned long bootmap_size; |
254 | unsigned long bootmap_pages, bootmem_paddr; | 246 | unsigned long bootmap_pages, bootmem_paddr; |
255 | u64 total_pages = (lmb_end_of_DRAM() - __MEMORY_START) >> PAGE_SHIFT; | 247 | u64 total_pages = lmb_phys_mem_size() >> PAGE_SHIFT; |
256 | int i; | 248 | int i; |
257 | 249 | ||
258 | bootmap_pages = bootmem_bootmap_pages(total_pages); | 250 | bootmap_pages = bootmem_bootmap_pages(total_pages); |
@@ -277,12 +269,6 @@ void __init do_init_bootmem(void) | |||
277 | } | 269 | } |
278 | 270 | ||
279 | /* | 271 | /* |
280 | * Handle additional early reservations | ||
281 | */ | ||
282 | check_for_initrd(); | ||
283 | reserve_crashkernel(); | ||
284 | |||
285 | /* | ||
286 | * Add all physical memory to the bootmem map and mark each | 272 | * Add all physical memory to the bootmem map and mark each |
287 | * area as present. | 273 | * area as present. |
288 | */ | 274 | */ |
@@ -299,7 +285,7 @@ void __init do_init_bootmem(void) | |||
299 | sparse_memory_present_with_active_regions(0); | 285 | sparse_memory_present_with_active_regions(0); |
300 | } | 286 | } |
301 | 287 | ||
302 | static void __init setup_memory(void) | 288 | static void __init early_reserve_mem(void) |
303 | { | 289 | { |
304 | unsigned long start_pfn; | 290 | unsigned long start_pfn; |
305 | 291 | ||
@@ -326,11 +312,11 @@ static void __init setup_memory(void) | |||
326 | if (CONFIG_ZERO_PAGE_OFFSET != 0) | 312 | if (CONFIG_ZERO_PAGE_OFFSET != 0) |
327 | lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET); | 313 | lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET); |
328 | 314 | ||
329 | lmb_analyze(); | 315 | /* |
330 | lmb_dump_all(); | 316 | * Handle additional early reservations |
331 | 317 | */ | |
332 | do_init_bootmem(); | 318 | check_for_initrd(); |
333 | plat_mem_setup(); | 319 | reserve_crashkernel(); |
334 | } | 320 | } |
335 | 321 | ||
336 | /* | 322 | /* |
@@ -397,10 +383,6 @@ void __init setup_arch(char **cmdline_p) | |||
397 | bss_resource.start = virt_to_phys(__bss_start); | 383 | bss_resource.start = virt_to_phys(__bss_start); |
398 | bss_resource.end = virt_to_phys(_ebss)-1; | 384 | bss_resource.end = virt_to_phys(_ebss)-1; |
399 | 385 | ||
400 | memory_start = (unsigned long)__va(__MEMORY_START); | ||
401 | if (!memory_end) | ||
402 | memory_end = memory_start + __MEMORY_SIZE; | ||
403 | |||
404 | #ifdef CONFIG_CMDLINE_OVERWRITE | 386 | #ifdef CONFIG_CMDLINE_OVERWRITE |
405 | strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line)); | 387 | strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line)); |
406 | #else | 388 | #else |
@@ -417,8 +399,6 @@ void __init setup_arch(char **cmdline_p) | |||
417 | 399 | ||
418 | parse_early_param(); | 400 | parse_early_param(); |
419 | 401 | ||
420 | uncached_init(); | ||
421 | |||
422 | plat_early_device_setup(); | 402 | plat_early_device_setup(); |
423 | 403 | ||
424 | /* Let earlyprintk output early console messages */ | 404 | /* Let earlyprintk output early console messages */ |
@@ -429,21 +409,28 @@ void __init setup_arch(char **cmdline_p) | |||
429 | sh_mv_setup(); | 409 | sh_mv_setup(); |
430 | sh_mv.mv_mem_init(); | 410 | sh_mv.mv_mem_init(); |
431 | 411 | ||
432 | /* | 412 | early_reserve_mem(); |
433 | * Find the highest page frame number we have available | 413 | |
434 | */ | 414 | lmb_enforce_memory_limit(memory_limit); |
435 | max_pfn = PFN_DOWN(__pa(memory_end)); | 415 | lmb_analyze(); |
416 | |||
417 | lmb_dump_all(); | ||
436 | 418 | ||
437 | /* | 419 | /* |
438 | * Determine low and high memory ranges: | 420 | * Determine low and high memory ranges: |
439 | */ | 421 | */ |
440 | max_low_pfn = max_pfn; | 422 | max_low_pfn = max_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT; |
441 | min_low_pfn = __MEMORY_START >> PAGE_SHIFT; | 423 | min_low_pfn = __MEMORY_START >> PAGE_SHIFT; |
442 | 424 | ||
443 | nodes_clear(node_online_map); | 425 | nodes_clear(node_online_map); |
444 | 426 | ||
427 | memory_start = (unsigned long)__va(__MEMORY_START); | ||
428 | memory_end = memory_start + (memory_limit ?: lmb_phys_mem_size()); | ||
429 | |||
430 | uncached_init(); | ||
445 | pmb_init(); | 431 | pmb_init(); |
446 | setup_memory(); | 432 | do_init_bootmem(); |
433 | plat_mem_setup(); | ||
447 | sparse_init(); | 434 | sparse_init(); |
448 | 435 | ||
449 | #ifdef CONFIG_DUMMY_CONSOLE | 436 | #ifdef CONFIG_DUMMY_CONSOLE |