Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+40 -45
+1 -1
arch/sh/include/asm/page.h
··· 49 49 50 50 extern unsigned long shm_align_mask; 51 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 54 static inline unsigned long 55 55 pages_do_alias(unsigned long addr1, unsigned long addr2)
+14 -6
arch/sh/kernel/machine_kexec.c
··· 169 169 170 170 crash_size = PAGE_ALIGN(crashk_res.end - crashk_res.start + 1); 171 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 174 if (!crashk_res.start) { 174 175 pr_err("crashkernel allocation failed\n"); 175 176 goto disable; ··· 184 183 } 185 184 } 186 185 187 - pr_info("Reserving %ldMB of memory at %ldMB " 186 + crashk_res.end = crashk_res.start + crash_size - 1; 187 + 188 + /* 189 + * Crash kernel trumps memory limit 190 + */ 191 + if ((lmb_end_of_DRAM() - memory_limit) <= crashk_res.end) { 192 + memory_limit = 0; 193 + pr_info("Disabled memory limit for crashkernel\n"); 194 + } 195 + 196 + pr_info("Reserving %ldMB of memory at 0x%08lx " 188 197 "for crashkernel (System RAM: %ldMB)\n", 189 198 (unsigned long)(crash_size >> 20), 190 - (unsigned long)(crashk_res.start >> 20), 199 + (unsigned long)(crashk_res.start), 191 200 (unsigned long)(lmb_phys_mem_size() >> 20)); 192 - 193 - crashk_res.end = crashk_res.start + crash_size - 1; 194 - insert_resource(&iomem_resource, &crashk_res); 195 201 196 202 return; 197 203
+25 -38
arch/sh/kernel/setup.c
··· 95 95 EXPORT_SYMBOL(memory_start); 96 96 unsigned long memory_end = 0; 97 97 EXPORT_SYMBOL(memory_end); 98 + unsigned long memory_limit = 0; 98 99 99 100 static struct resource mem_resources[MAX_NUMNODES]; 100 101 ··· 103 102 104 103 static int __init early_parse_mem(char *p) 105 104 { 106 - unsigned long size; 105 + if (!p) 106 + return 1; 107 107 108 - memory_start = (unsigned long)__va(__MEMORY_START); 109 - size = memparse(p, &p); 108 + memory_limit = PAGE_ALIGN(memparse(p, &p)); 110 109 111 - if (size > __MEMORY_SIZE) { 112 - printk(KERN_ERR 113 - "Using mem= to increase the size of kernel memory " 114 - "is not allowed.\n" 115 - " Recompile the kernel with the correct value for " 116 - "CONFIG_MEMORY_SIZE.\n"); 117 - return 0; 118 - } 119 - 120 - memory_end = memory_start + size; 110 + pr_notice("Memory limited to %ldMB\n", memory_limit >> 20); 121 111 122 112 return 0; 123 113 } ··· 244 252 { 245 253 unsigned long bootmap_size; 246 254 unsigned long bootmap_pages, bootmem_paddr; 247 - u64 total_pages = (lmb_end_of_DRAM() - __MEMORY_START) >> PAGE_SHIFT; 255 + u64 total_pages = lmb_phys_mem_size() >> PAGE_SHIFT; 248 256 int i; 249 257 250 258 bootmap_pages = bootmem_bootmap_pages(total_pages); ··· 269 277 } 270 278 271 279 /* 272 - * Handle additional early reservations 273 - */ 274 - check_for_initrd(); 275 - reserve_crashkernel(); 276 - 277 - /* 278 280 * Add all physical memory to the bootmem map and mark each 279 281 * area as present. 280 282 */ ··· 285 299 sparse_memory_present_with_active_regions(0); 286 300 } 287 301 288 - static void __init setup_memory(void) 302 + static void __init early_reserve_mem(void) 289 303 { 290 304 unsigned long start_pfn; 291 305 ··· 312 326 if (CONFIG_ZERO_PAGE_OFFSET != 0) 313 327 lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET); 314 328 315 - lmb_analyze(); 316 - lmb_dump_all(); 317 - 318 - do_init_bootmem(); 319 - plat_mem_setup(); 329 + /* 330 + * Handle additional early reservations 331 + */ 332 + check_for_initrd(); 333 + reserve_crashkernel(); 320 334 } 321 335 322 336 /* ··· 383 397 bss_resource.start = virt_to_phys(__bss_start); 384 398 bss_resource.end = virt_to_phys(_ebss)-1; 385 399 386 - memory_start = (unsigned long)__va(__MEMORY_START); 387 - if (!memory_end) 388 - memory_end = memory_start + __MEMORY_SIZE; 389 - 390 400 #ifdef CONFIG_CMDLINE_OVERWRITE 391 401 strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line)); 392 402 #else ··· 399 417 400 418 parse_early_param(); 401 419 402 - uncached_init(); 403 - 404 420 plat_early_device_setup(); 405 421 406 422 /* Let earlyprintk output early console messages */ ··· 409 429 sh_mv_setup(); 410 430 sh_mv.mv_mem_init(); 411 431 412 - /* 413 - * Find the highest page frame number we have available 414 - */ 415 - max_pfn = PFN_DOWN(__pa(memory_end)); 432 + early_reserve_mem(); 433 + 434 + lmb_enforce_memory_limit(memory_limit); 435 + lmb_analyze(); 436 + 437 + lmb_dump_all(); 416 438 417 439 /* 418 440 * Determine low and high memory ranges: 419 441 */ 420 - max_low_pfn = max_pfn; 442 + max_low_pfn = max_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT; 421 443 min_low_pfn = __MEMORY_START >> PAGE_SHIFT; 422 444 423 445 nodes_clear(node_online_map); 424 446 447 + memory_start = (unsigned long)__va(__MEMORY_START); 448 + memory_end = memory_start + (memory_limit ?: lmb_phys_mem_size()); 449 + 450 + uncached_init(); 425 451 pmb_init(); 426 - setup_memory(); 452 + do_init_bootmem(); 453 + plat_mem_setup(); 427 454 sparse_init(); 428 455 429 456 #ifdef CONFIG_DUMMY_CONSOLE