lkml.org 
[lkml]   [2020]   [May]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v8 1/5] x86: kdump: move reserve_crashkernel_low() into crash_core.c
    Date
    In preparation for supporting reserve_crashkernel_low in arm64 as
    x86_64 does, move reserve_crashkernel_low() into kernel/crash_core.c.
    BTW, move x86 CRASH_ALIGN to 2M.

    Note, in arm64, we reserve low memory if and only if crashkernel=X,low
    is specified. Different with x86_64, don't set low memory automatically.

    Reported-by: kbuild test robot <lkp@intel.com>
    Signed-off-by: Chen Zhou <chenzhou10@huawei.com>
    Tested-by: John Donnelly <John.p.donnelly@oracle.com>
    Tested-by: Prabhakar Kushwaha <pkushwaha@marvell.com>
    ---
    arch/x86/kernel/setup.c | 66 ++++-------------------------
    include/linux/crash_core.h | 3 ++
    include/linux/kexec.h | 2 -
    kernel/crash_core.c | 85 ++++++++++++++++++++++++++++++++++++++
    kernel/kexec_core.c | 17 --------
    5 files changed, 96 insertions(+), 77 deletions(-)

    diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
    index 4b3fa6cd3106..de75fec73d47 100644
    --- a/arch/x86/kernel/setup.c
    +++ b/arch/x86/kernel/setup.c
    @@ -395,8 +395,8 @@ static void __init memblock_x86_reserve_range_setup_data(void)

    #ifdef CONFIG_KEXEC_CORE

    -/* 16M alignment for crash kernel regions */
    -#define CRASH_ALIGN SZ_16M
    +/* 2M alignment for crash kernel regions */
    +#define CRASH_ALIGN SZ_2M

    /*
    * Keep the crash kernel below this limit.
    @@ -419,59 +419,6 @@ static void __init memblock_x86_reserve_range_setup_data(void)
    # define CRASH_ADDR_HIGH_MAX SZ_64T
    #endif

    -static int __init reserve_crashkernel_low(void)
    -{
    -#ifdef CONFIG_X86_64
    - unsigned long long base, low_base = 0, low_size = 0;
    - unsigned long total_low_mem;
    - int ret;
    -
    - total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
    -
    - /* crashkernel=Y,low */
    - ret = parse_crashkernel_low(boot_command_line, total_low_mem, &low_size, &base);
    - if (ret) {
    - /*
    - * two parts from kernel/dma/swiotlb.c:
    - * -swiotlb size: user-specified with swiotlb= or default.
    - *
    - * -swiotlb overflow buffer: now hardcoded to 32k. We round it
    - * to 8M for other buffers that may need to stay low too. Also
    - * make sure we allocate enough extra low memory so that we
    - * don't run out of DMA buffers for 32-bit devices.
    - */
    - low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL << 20);
    - } else {
    - /* passed with crashkernel=0,low ? */
    - if (!low_size)
    - return 0;
    - }
    -
    - low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
    - if (!low_base) {
    - pr_err("Cannot reserve %ldMB crashkernel low memory, please try smaller size.\n",
    - (unsigned long)(low_size >> 20));
    - return -ENOMEM;
    - }
    -
    - ret = memblock_reserve(low_base, low_size);
    - if (ret) {
    - pr_err("%s: Error reserving crashkernel low memblock.\n", __func__);
    - return ret;
    - }
    -
    - pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System low RAM: %ldMB)\n",
    - (unsigned long)(low_size >> 20),
    - (unsigned long)(low_base >> 20),
    - (unsigned long)(total_low_mem >> 20));
    -
    - crashk_low_res.start = low_base;
    - crashk_low_res.end = low_base + low_size - 1;
    - insert_resource(&iomem_resource, &crashk_low_res);
    -#endif
    - return 0;
    -}
    -
    static void __init reserve_crashkernel(void)
    {
    unsigned long long crash_size, crash_base, total_mem;
    @@ -535,9 +482,12 @@ static void __init reserve_crashkernel(void)
    return;
    }

    - if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
    - memblock_free(crash_base, crash_size);
    - return;
    + if (crash_base >= (1ULL << 32)) {
    + if (reserve_crashkernel_low()) {
    + memblock_free(crash_base, crash_size);
    + return;
    + }
    + insert_resource(&iomem_resource, &crashk_low_res);
    }

    pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
    diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
    index 525510a9f965..4df8c0bff03e 100644
    --- a/include/linux/crash_core.h
    +++ b/include/linux/crash_core.h
    @@ -63,6 +63,8 @@ phys_addr_t paddr_vmcoreinfo_note(void);
    extern unsigned char *vmcoreinfo_data;
    extern size_t vmcoreinfo_size;
    extern u32 *vmcoreinfo_note;
    +extern struct resource crashk_res;
    +extern struct resource crashk_low_res;

    Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
    void *data, size_t data_len);
    @@ -74,5 +76,6 @@ int parse_crashkernel_high(char *cmdline, unsigned long long system_ram,
    unsigned long long *crash_size, unsigned long long *crash_base);
    int parse_crashkernel_low(char *cmdline, unsigned long long system_ram,
    unsigned long long *crash_size, unsigned long long *crash_base);
    +int __init reserve_crashkernel_low(void);

    #endif /* LINUX_CRASH_CORE_H */
    diff --git a/include/linux/kexec.h b/include/linux/kexec.h
    index 1776eb2e43a4..5d5d9635b18d 100644
    --- a/include/linux/kexec.h
    +++ b/include/linux/kexec.h
    @@ -330,8 +330,6 @@ extern int kexec_load_disabled;

    /* Location of a reserved region to hold the crash kernel.
    */
    -extern struct resource crashk_res;
    -extern struct resource crashk_low_res;
    extern note_buf_t __percpu *crash_notes;

    /* flag to track if kexec reboot is in progress */
    diff --git a/kernel/crash_core.c b/kernel/crash_core.c
    index 9f1557b98468..a7580d291c37 100644
    --- a/kernel/crash_core.c
    +++ b/kernel/crash_core.c
    @@ -7,6 +7,8 @@
    #include <linux/crash_core.h>
    #include <linux/utsname.h>
    #include <linux/vmalloc.h>
    +#include <linux/memblock.h>
    +#include <linux/swiotlb.h>

    #include <asm/page.h>
    #include <asm/sections.h>
    @@ -19,6 +21,22 @@ u32 *vmcoreinfo_note;
    /* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
    static unsigned char *vmcoreinfo_data_safecopy;

    +/* Location of the reserved area for the crash kernel */
    +struct resource crashk_res = {
    + .name = "Crash kernel",
    + .start = 0,
    + .end = 0,
    + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
    + .desc = IORES_DESC_CRASH_KERNEL
    +};
    +struct resource crashk_low_res = {
    + .name = "Crash kernel",
    + .start = 0,
    + .end = 0,
    + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
    + .desc = IORES_DESC_CRASH_KERNEL
    +};
    +
    /*
    * parsing the "crashkernel" commandline
    *
    @@ -292,6 +310,73 @@ int __init parse_crashkernel_low(char *cmdline,
    "crashkernel=", suffix_tbl[SUFFIX_LOW]);
    }

    +#if defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
    +#define CRASH_ALIGN SZ_2M
    +#endif
    +
    +int __init reserve_crashkernel_low(void)
    +{
    +#if defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
    + unsigned long long base, low_base = 0, low_size = 0;
    + unsigned long total_low_mem;
    + int ret;
    +
    + total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
    +
    + /* crashkernel=Y,low */
    + ret = parse_crashkernel_low(boot_command_line, total_low_mem, &low_size,
    + &base);
    + if (ret) {
    +#ifdef CONFIG_X86_64
    + /*
    + * two parts from lib/swiotlb.c:
    + * -swiotlb size: user-specified with swiotlb= or default.
    + *
    + * -swiotlb overflow buffer: now hardcoded to 32k. We round it
    + * to 8M for other buffers that may need to stay low too. Also
    + * make sure we allocate enough extra low memory so that we
    + * don't run out of DMA buffers for 32-bit devices.
    + */
    + low_size = max(swiotlb_size_or_default() + (8UL << 20),
    + 256UL << 20);
    +#else
    + /*
    + * in arm64, reserve low memory if and only if crashkernel=X,low
    + * specified.
    + */
    + return -EINVAL;
    +#endif
    + } else {
    + /* passed with crashkernel=0,low ? */
    + if (!low_size)
    + return 0;
    + }
    +
    + low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
    + if (!low_base) {
    + pr_err("Cannot reserve %ldMB crashkernel low memory, please try smaller size.\n",
    + (unsigned long)(low_size >> 20));
    + return -ENOMEM;
    + }
    +
    + ret = memblock_reserve(low_base, low_size);
    + if (ret) {
    + pr_err("%s: Error reserving crashkernel low memblock.\n",
    + __func__);
    + return ret;
    + }
    +
    + pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System low RAM: %ldMB)\n",
    + (unsigned long)(low_size >> 20),
    + (unsigned long)(low_base >> 20),
    + (unsigned long)(total_low_mem >> 20));
    +
    + crashk_low_res.start = low_base;
    + crashk_low_res.end = low_base + low_size - 1;
    +#endif
    + return 0;
    +}
    +
    Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
    void *data, size_t data_len)
    {
    diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
    index c19c0dad1ebe..db66bbabfff3 100644
    --- a/kernel/kexec_core.c
    +++ b/kernel/kexec_core.c
    @@ -53,23 +53,6 @@ note_buf_t __percpu *crash_notes;
    /* Flag to indicate we are going to kexec a new kernel */
    bool kexec_in_progress = false;

    -
    -/* Location of the reserved area for the crash kernel */
    -struct resource crashk_res = {
    - .name = "Crash kernel",
    - .start = 0,
    - .end = 0,
    - .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
    - .desc = IORES_DESC_CRASH_KERNEL
    -};
    -struct resource crashk_low_res = {
    - .name = "Crash kernel",
    - .start = 0,
    - .end = 0,
    - .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
    - .desc = IORES_DESC_CRASH_KERNEL
    -};
    -
    int kexec_should_crash(struct task_struct *p)
    {
    /*
    --
    2.20.1
    \
     
     \ /
      Last update: 2020-05-21 11:36    [W:4.256 / U:0.484 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site