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

Configure Feed

Select the types of activity you want to include in your feed.

x86: kdump: use generic interface to simplify crashkernel reservation code

With the help of newly changed function parse_crashkernel() and generic
reserve_crashkernel_generic(), crashkernel reservation can be simplified
by steps:

1) Add a new header file <asm/crash_core.h>, and define CRASH_ALIGN,
CRASH_ADDR_LOW_MAX, CRASH_ADDR_HIGH_MAX and
DEFAULT_CRASH_KERNEL_LOW_SIZE in <asm/crash_core.h>;

2) Add arch_reserve_crashkernel() to call parse_crashkernel() and
reserve_crashkernel_generic(), and do the ARCH specific work if
needed.

3) Add ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION Kconfig in
arch/x86/Kconfig.

When adding DEFAULT_CRASH_KERNEL_LOW_SIZE, add crash_low_size_default() to
calculate crashkernel low memory because x86_64 has special requirement.

The old reserve_crashkernel_low() and reserve_crashkernel() can be
removed.

[bhe@redhat.com: move crash_low_size_default() code into <asm/crash_core.h>]
Link: https://lkml.kernel.org/r/ZQpeAjOmuMJBFw1/@MiWiFi-R3L-srv
Link: https://lkml.kernel.org/r/20230914033142.676708-7-bhe@redhat.com
Signed-off-by: Baoquan He <bhe@redhat.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Chen Jiahao <chenjiahao16@huawei.com>
Cc: Zhen Lei <thunder.leizhen@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Baoquan He and committed by
Andrew Morton
9c08a2a1 b631b95d

+56 -137
+3
arch/x86/Kconfig
··· 2062 2062 config ARCH_SUPPORTS_CRASH_HOTPLUG 2063 2063 def_bool y 2064 2064 2065 + config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION 2066 + def_bool CRASH_CORE 2067 + 2065 2068 config PHYSICAL_START 2066 2069 hex "Physical address where the kernel is loaded" if (EXPERT || CRASH_DUMP) 2067 2070 default "0x1000000"
+42
arch/x86/include/asm/crash_core.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _X86_CRASH_CORE_H 3 + #define _X86_CRASH_CORE_H 4 + 5 + /* 16M alignment for crash kernel regions */ 6 + #define CRASH_ALIGN SZ_16M 7 + 8 + /* 9 + * Keep the crash kernel below this limit. 10 + * 11 + * Earlier 32-bits kernels would limit the kernel to the low 512 MB range 12 + * due to mapping restrictions. 13 + * 14 + * 64-bit kdump kernels need to be restricted to be under 64 TB, which is 15 + * the upper limit of system RAM in 4-level paging mode. Since the kdump 16 + * jump could be from 5-level paging to 4-level paging, the jump will fail if 17 + * the kernel is put above 64 TB, and during the 1st kernel bootup there's 18 + * no good way to detect the paging mode of the target kernel which will be 19 + * loaded for dumping. 20 + */ 21 + extern unsigned long swiotlb_size_or_default(void); 22 + 23 + #ifdef CONFIG_X86_32 24 + # define CRASH_ADDR_LOW_MAX SZ_512M 25 + # define CRASH_ADDR_HIGH_MAX SZ_512M 26 + #else 27 + # define CRASH_ADDR_LOW_MAX SZ_4G 28 + # define CRASH_ADDR_HIGH_MAX SZ_64T 29 + #endif 30 + 31 + # define DEFAULT_CRASH_KERNEL_LOW_SIZE crash_low_size_default() 32 + 33 + static inline unsigned long crash_low_size_default(void) 34 + { 35 + #ifdef CONFIG_X86_64 36 + return max(swiotlb_size_or_default() + (8UL << 20), 256UL << 20); 37 + #else 38 + return 0; 39 + #endif 40 + } 41 + 42 + #endif /* _X86_CRASH_CORE_H */
+11 -137
arch/x86/kernel/setup.c
··· 466 466 } 467 467 } 468 468 469 - /* 470 - * --------- Crashkernel reservation ------------------------------ 471 - */ 472 - 473 - /* 16M alignment for crash kernel regions */ 474 - #define CRASH_ALIGN SZ_16M 475 - 476 - /* 477 - * Keep the crash kernel below this limit. 478 - * 479 - * Earlier 32-bits kernels would limit the kernel to the low 512 MB range 480 - * due to mapping restrictions. 481 - * 482 - * 64-bit kdump kernels need to be restricted to be under 64 TB, which is 483 - * the upper limit of system RAM in 4-level paging mode. Since the kdump 484 - * jump could be from 5-level paging to 4-level paging, the jump will fail if 485 - * the kernel is put above 64 TB, and during the 1st kernel bootup there's 486 - * no good way to detect the paging mode of the target kernel which will be 487 - * loaded for dumping. 488 - */ 489 - #ifdef CONFIG_X86_32 490 - # define CRASH_ADDR_LOW_MAX SZ_512M 491 - # define CRASH_ADDR_HIGH_MAX SZ_512M 492 - #else 493 - # define CRASH_ADDR_LOW_MAX SZ_4G 494 - # define CRASH_ADDR_HIGH_MAX SZ_64T 495 - #endif 496 - 497 - static int __init reserve_crashkernel_low(void) 469 + static void __init arch_reserve_crashkernel(void) 498 470 { 499 - #ifdef CONFIG_X86_64 500 - unsigned long long base, low_base = 0, low_size = 0; 501 - unsigned long low_mem_limit; 502 - int ret; 503 - 504 - low_mem_limit = min(memblock_phys_mem_size(), CRASH_ADDR_LOW_MAX); 505 - 506 - /* crashkernel=Y,low */ 507 - ret = parse_crashkernel_low(boot_command_line, low_mem_limit, &low_size, &base); 508 - if (ret) { 509 - /* 510 - * two parts from kernel/dma/swiotlb.c: 511 - * -swiotlb size: user-specified with swiotlb= or default. 512 - * 513 - * -swiotlb overflow buffer: now hardcoded to 32k. We round it 514 - * to 8M for other buffers that may need to stay low too. Also 515 - * make sure we allocate enough extra low memory so that we 516 - * don't run out of DMA buffers for 32-bit devices. 517 - */ 518 - low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL << 20); 519 - } else { 520 - /* passed with crashkernel=0,low ? */ 521 - if (!low_size) 522 - return 0; 523 - } 524 - 525 - low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, 0, CRASH_ADDR_LOW_MAX); 526 - if (!low_base) { 527 - pr_err("Cannot reserve %ldMB crashkernel low memory, please try smaller size.\n", 528 - (unsigned long)(low_size >> 20)); 529 - return -ENOMEM; 530 - } 531 - 532 - pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (low RAM limit: %ldMB)\n", 533 - (unsigned long)(low_size >> 20), 534 - (unsigned long)(low_base >> 20), 535 - (unsigned long)(low_mem_limit >> 20)); 536 - 537 - crashk_low_res.start = low_base; 538 - crashk_low_res.end = low_base + low_size - 1; 539 - insert_resource(&iomem_resource, &crashk_low_res); 540 - #endif 541 - return 0; 542 - } 543 - 544 - static void __init reserve_crashkernel(void) 545 - { 546 - unsigned long long crash_size, crash_base, total_mem; 471 + unsigned long long crash_base, crash_size, low_size = 0; 472 + char *cmdline = boot_command_line; 547 473 bool high = false; 548 474 int ret; 549 475 550 476 if (!IS_ENABLED(CONFIG_KEXEC_CORE)) 551 477 return; 552 478 553 - total_mem = memblock_phys_mem_size(); 554 - 555 - /* crashkernel=XM */ 556 - ret = parse_crashkernel(boot_command_line, total_mem, 557 - &crash_size, &crash_base, NULL, NULL); 558 - if (ret != 0 || crash_size <= 0) { 559 - /* crashkernel=X,high */ 560 - ret = parse_crashkernel_high(boot_command_line, total_mem, 561 - &crash_size, &crash_base); 562 - if (ret != 0 || crash_size <= 0) 563 - return; 564 - high = true; 565 - } 479 + ret = parse_crashkernel(cmdline, memblock_phys_mem_size(), 480 + &crash_size, &crash_base, 481 + &low_size, &high); 482 + if (ret) 483 + return; 566 484 567 485 if (xen_pv_domain()) { 568 486 pr_info("Ignoring crashkernel for a Xen PV domain\n"); 569 487 return; 570 488 } 571 489 572 - /* 0 means: find the address automatically */ 573 - if (!crash_base) { 574 - /* 575 - * Set CRASH_ADDR_LOW_MAX upper bound for crash memory, 576 - * crashkernel=x,high reserves memory over 4G, also allocates 577 - * 256M extra low memory for DMA buffers and swiotlb. 578 - * But the extra memory is not required for all machines. 579 - * So try low memory first and fall back to high memory 580 - * unless "crashkernel=size[KMG],high" is specified. 581 - */ 582 - if (!high) 583 - crash_base = memblock_phys_alloc_range(crash_size, 584 - CRASH_ALIGN, CRASH_ALIGN, 585 - CRASH_ADDR_LOW_MAX); 586 - if (!crash_base) 587 - crash_base = memblock_phys_alloc_range(crash_size, 588 - CRASH_ALIGN, CRASH_ALIGN, 589 - CRASH_ADDR_HIGH_MAX); 590 - if (!crash_base) { 591 - pr_info("crashkernel reservation failed - No suitable area found.\n"); 592 - return; 593 - } 594 - } else { 595 - unsigned long long start; 596 - 597 - start = memblock_phys_alloc_range(crash_size, SZ_1M, crash_base, 598 - crash_base + crash_size); 599 - if (start != crash_base) { 600 - pr_info("crashkernel reservation failed - memory is in use.\n"); 601 - return; 602 - } 603 - } 604 - 605 - if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) { 606 - memblock_phys_free(crash_base, crash_size); 607 - return; 608 - } 609 - 610 - pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n", 611 - (unsigned long)(crash_size >> 20), 612 - (unsigned long)(crash_base >> 20), 613 - (unsigned long)(total_mem >> 20)); 614 - 615 - crashk_res.start = crash_base; 616 - crashk_res.end = crash_base + crash_size - 1; 617 - insert_resource(&iomem_resource, &crashk_res); 490 + reserve_crashkernel_generic(cmdline, crash_size, crash_base, 491 + low_size, high); 618 492 } 619 493 620 494 static struct resource standard_io_resources[] = { ··· 1102 1228 * Reserve memory for crash kernel after SRAT is parsed so that it 1103 1229 * won't consume hotpluggable memory. 1104 1230 */ 1105 - reserve_crashkernel(); 1231 + arch_reserve_crashkernel(); 1106 1232 1107 1233 memblock_find_dma_reserve(); 1108 1234