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.

arm64: kdump: use generic interface to simplify crashkernel reservation

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();

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

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

Link: https://lkml.kernel.org/r/20230914033142.676708-8-bhe@redhat.com
Signed-off-by: Baoquan He <bhe@redhat.com>
Reviewed-by: Zhen Lei <thunder.leizhen@huawei.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Chen Jiahao <chenjiahao16@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Baoquan He and committed by
Andrew Morton
fdc26823 9c08a2a1

+21 -132
+3
arch/arm64/Kconfig
··· 1483 1483 config ARCH_SUPPORTS_CRASH_DUMP 1484 1484 def_bool y 1485 1485 1486 + config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION 1487 + def_bool CRASH_CORE 1488 + 1486 1489 config TRANS_TABLE 1487 1490 def_bool y 1488 1491 depends on HIBERNATION || KEXEC_CORE
+10
arch/arm64/include/asm/crash_core.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + #ifndef _ARM64_CRASH_CORE_H 3 + #define _ARM64_CRASH_CORE_H 4 + 5 + /* Current arm64 boot protocol requires 2MB alignment */ 6 + #define CRASH_ALIGN SZ_2M 7 + 8 + #define CRASH_ADDR_LOW_MAX arm64_dma_phys_limit 9 + #define CRASH_ADDR_HIGH_MAX (PHYS_MASK + 1) 10 + #endif
+8 -132
arch/arm64/mm/init.c
··· 64 64 */ 65 65 phys_addr_t __ro_after_init arm64_dma_phys_limit; 66 66 67 - /* Current arm64 boot protocol requires 2MB alignment */ 68 - #define CRASH_ALIGN SZ_2M 69 - 70 - #define CRASH_ADDR_LOW_MAX arm64_dma_phys_limit 71 - #define CRASH_ADDR_HIGH_MAX (PHYS_MASK + 1) 72 - #define CRASH_HIGH_SEARCH_BASE SZ_4G 73 - 74 - #define DEFAULT_CRASH_KERNEL_LOW_SIZE (128UL << 20) 75 - 76 67 /* 77 68 * To make optimal use of block mappings when laying out the linear 78 69 * mapping, round down the base of physical memory to a size that can ··· 91 100 #define ARM64_MEMSTART_ALIGN (1UL << ARM64_MEMSTART_SHIFT) 92 101 #endif 93 102 94 - static int __init reserve_crashkernel_low(unsigned long long low_size) 103 + static void __init arch_reserve_crashkernel(void) 95 104 { 96 - unsigned long long low_base; 97 - 98 - low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, 0, CRASH_ADDR_LOW_MAX); 99 - if (!low_base) { 100 - pr_err("cannot allocate crashkernel low memory (size:0x%llx).\n", low_size); 101 - return -ENOMEM; 102 - } 103 - 104 - pr_info("crashkernel low memory reserved: 0x%08llx - 0x%08llx (%lld MB)\n", 105 - low_base, low_base + low_size, low_size >> 20); 106 - 107 - crashk_low_res.start = low_base; 108 - crashk_low_res.end = low_base + low_size - 1; 109 - insert_resource(&iomem_resource, &crashk_low_res); 110 - 111 - return 0; 112 - } 113 - 114 - /* 115 - * reserve_crashkernel() - reserves memory for crash kernel 116 - * 117 - * This function reserves memory area given in "crashkernel=" kernel command 118 - * line parameter. The memory reserved is used by dump capture kernel when 119 - * primary kernel is crashing. 120 - */ 121 - static void __init reserve_crashkernel(void) 122 - { 123 - unsigned long long crash_low_size = 0, search_base = 0; 124 - unsigned long long crash_max = CRASH_ADDR_LOW_MAX; 105 + unsigned long long low_size = 0; 125 106 unsigned long long crash_base, crash_size; 126 107 char *cmdline = boot_command_line; 127 - bool fixed_base = false; 128 108 bool high = false; 129 109 int ret; 130 110 131 111 if (!IS_ENABLED(CONFIG_KEXEC_CORE)) 132 112 return; 133 113 134 - /* crashkernel=X[@offset] */ 135 114 ret = parse_crashkernel(cmdline, memblock_phys_mem_size(), 136 - &crash_size, &crash_base, NULL, NULL); 137 - if (ret == -ENOENT) { 138 - ret = parse_crashkernel_high(cmdline, 0, &crash_size, &crash_base); 139 - if (ret || !crash_size) 140 - return; 141 - 142 - /* 143 - * crashkernel=Y,low can be specified or not, but invalid value 144 - * is not allowed. 145 - */ 146 - ret = parse_crashkernel_low(cmdline, 0, &crash_low_size, &crash_base); 147 - if (ret == -ENOENT) 148 - crash_low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE; 149 - else if (ret) 150 - return; 151 - 152 - search_base = CRASH_HIGH_SEARCH_BASE; 153 - crash_max = CRASH_ADDR_HIGH_MAX; 154 - high = true; 155 - } else if (ret || !crash_size) { 156 - /* The specified value is invalid */ 115 + &crash_size, &crash_base, 116 + &low_size, &high); 117 + if (ret) 157 118 return; 158 - } 159 119 160 - crash_size = PAGE_ALIGN(crash_size); 161 - 162 - /* User specifies base address explicitly. */ 163 - if (crash_base) { 164 - fixed_base = true; 165 - search_base = crash_base; 166 - crash_max = crash_base + crash_size; 167 - } 168 - 169 - retry: 170 - crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN, 171 - search_base, crash_max); 172 - if (!crash_base) { 173 - /* 174 - * For crashkernel=size[KMG]@offset[KMG], print out failure 175 - * message if can't reserve the specified region. 176 - */ 177 - if (fixed_base) { 178 - pr_warn("crashkernel reservation failed - memory is in use.\n"); 179 - return; 180 - } 181 - 182 - /* 183 - * For crashkernel=size[KMG], if the first attempt was for 184 - * low memory, fall back to high memory, the minimum required 185 - * low memory will be reserved later. 186 - */ 187 - if (!high && crash_max == CRASH_ADDR_LOW_MAX) { 188 - crash_max = CRASH_ADDR_HIGH_MAX; 189 - search_base = CRASH_ADDR_LOW_MAX; 190 - crash_low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE; 191 - goto retry; 192 - } 193 - 194 - /* 195 - * For crashkernel=size[KMG],high, if the first attempt was 196 - * for high memory, fall back to low memory. 197 - */ 198 - if (high && crash_max == CRASH_ADDR_HIGH_MAX) { 199 - crash_max = CRASH_ADDR_LOW_MAX; 200 - search_base = 0; 201 - goto retry; 202 - } 203 - pr_warn("cannot allocate crashkernel (size:0x%llx)\n", 204 - crash_size); 205 - return; 206 - } 207 - 208 - if ((crash_base >= CRASH_ADDR_LOW_MAX) && crash_low_size && 209 - reserve_crashkernel_low(crash_low_size)) { 210 - memblock_phys_free(crash_base, crash_size); 211 - return; 212 - } 213 - 214 - pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n", 215 - crash_base, crash_base + crash_size, crash_size >> 20); 216 - 217 - /* 218 - * The crashkernel memory will be removed from the kernel linear 219 - * map. Inform kmemleak so that it won't try to access it. 220 - */ 221 - kmemleak_ignore_phys(crash_base); 222 - if (crashk_low_res.end) 223 - kmemleak_ignore_phys(crashk_low_res.start); 224 - 225 - crashk_res.start = crash_base; 226 - crashk_res.end = crash_base + crash_size - 1; 227 - insert_resource(&iomem_resource, &crashk_res); 120 + reserve_crashkernel_generic(cmdline, crash_size, crash_base, 121 + low_size, high); 228 122 } 229 123 230 124 /* ··· 355 479 * request_standard_resources() depends on crashkernel's memory being 356 480 * reserved, so do it here. 357 481 */ 358 - reserve_crashkernel(); 482 + arch_reserve_crashkernel(); 359 483 360 484 memblock_dump_all(); 361 485 }