Message ID | 20230223124532.128744-1-bhe@redhat.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:5915:0:0:0:0:0 with SMTP id v21csp293993wrd; Thu, 23 Feb 2023 04:54:20 -0800 (PST) X-Google-Smtp-Source: AK7set/8OfAkm3cwSaG3nEtHmScOVdOK4E9Ab7OcpwD7/Y22DvDqmTYyLPZygvpoBZXL80GptLNQ X-Received: by 2002:a17:90a:bf0d:b0:233:a836:15f4 with SMTP id c13-20020a17090abf0d00b00233a83615f4mr11644437pjs.1.1677156859940; Thu, 23 Feb 2023 04:54:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1677156859; cv=none; d=google.com; s=arc-20160816; b=KGszUD/3SyS8nHClopOU3vvgd1Hj9wOZfw4YLm0YYeyEMPfLKiUChLr8p8ge6qOCxP XTW9MG1Qf4BZeHkJCvso5oecXvfYdUHWoI+yOXNqQO8dUh5ULSH9CqCJ6uH1wOcTZuUD vugohMIijwjcNxss6mNMESvPXlt/Ay2TVwWO37XWRD1AoKIo7xH8F4xlCW7X3xewz8Yq wWGTc9kBcKIEX2itt7lFpab1600ayzt88P52/3d5N0RIyv96b+sBuWnpUA3TEdJlNfTg TXKFs4tl7/wAtGwLcj10IgZXIHf/zFc/3v1lwXskyjyeqAxODO8j/p7gaM/m8CBOtXXr D9ZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=M8NX3ZsDrSBQPQ7I5uuezSkfCmMskoJHj9OKngyaMDw=; b=bujleNADPFCWulV9ptqln9bl87NMJ/5VkpLxrqEER74vBOXrgXc3IwvZDk8bK0SA+V HyoSpmJz+wdDtsXsswGVFtTyac2WbbZ8HYnFfsPz/IMvVZ/okY+2qDHDEzRUWj7gvzHc AhcPEIqVzmhS+4ttJ4AtOGNUiQRh+w16UUlrAoo4BqVDLFLC5Aq2dBgo03wTDXVM4rsh eN4W3iGvul+ybaxip+qE7/GQ3d94xoJ7nUYeeD/YcV9Mart0lhS0KQt/fdIY44/Y9Gta O9vX9PoeR3S9dzyc7A4bp81jrtmwLk53gJ8nf/a5F5WgnJ6Nb5mB+weD6/PFbEsyXLeR 9KkA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="OaOzq2e/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id p15-20020a17090a2d8f00b002340c152af7si12905351pjd.123.2023.02.23.04.54.06; Thu, 23 Feb 2023 04:54:19 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="OaOzq2e/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234199AbjBWMqj (ORCPT <rfc822;cambridge8321@gmail.com> + 99 others); Thu, 23 Feb 2023 07:46:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43334 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233823AbjBWMqh (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 23 Feb 2023 07:46:37 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 134B354A3E for <linux-kernel@vger.kernel.org>; Thu, 23 Feb 2023 04:45:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1677156345; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=M8NX3ZsDrSBQPQ7I5uuezSkfCmMskoJHj9OKngyaMDw=; b=OaOzq2e/5nqfsyT5pbGTUhdZPLvx2al/ozvuumV1WLkd1trPQvVGIkfAOOkKpOgb3fNYh4 yHyGXZpgZhtKsNAVEFdprztKrk8wPW9DN0TTV0oW4ZbV3c5e2iqcgFTmHkzX1XNXgtQkk6 ee1vkWAeJMwNtxfXjmI93Ktm4sQDS7U= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-515-2n2RkbemMAqn6nr-EOdDmA-1; Thu, 23 Feb 2023 07:45:43 -0500 X-MC-Unique: 2n2RkbemMAqn6nr-EOdDmA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 6EF9B802D2A; Thu, 23 Feb 2023 12:45:42 +0000 (UTC) Received: from MiWiFi-R3L-srv.redhat.com (ovpn-13-7.pek2.redhat.com [10.72.13.7]) by smtp.corp.redhat.com (Postfix) with ESMTP id CB1692166B2C; Thu, 23 Feb 2023 12:45:37 +0000 (UTC) From: Baoquan He <bhe@redhat.com> To: linux-kernel@vger.kernel.org Cc: catalin.marinas@arm.com, horms@kernel.org, thunder.leizhen@huawei.com, John.p.donnelly@oracle.com, will@kernel.org, kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, Baoquan He <bhe@redhat.com> Subject: [PATCH v3] arm64: kdump: simplify the reservation behaviour of crashkernel=,high Date: Thu, 23 Feb 2023 20:45:32 +0800 Message-Id: <20230223124532.128744-1-bhe@redhat.com> MIME-Version: 1.0 Content-type: text/plain Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1758626431986972058?= X-GMAIL-MSGID: =?utf-8?q?1758626431986972058?= |
Series |
[v3] arm64: kdump: simplify the reservation behaviour of crashkernel=,high
|
|
Commit Message
Baoquan He
Feb. 23, 2023, 12:45 p.m. UTC
On arm64, reservation for 'crashkernel=xM,high' is taken by searching for
suitable memory region top down. If the 'xM' of crashkernel high memory
is reserved from high memory successfully, it will try to reserve
crashkernel low memory later accoringly. Otherwise, it will try to search
low memory area for the 'xM' suitable region. Please see the details in
Documentation/admin-guide/kernel-parameters.txt.
While we observed an unexpected case where a reserved region crosses the
high and low meomry boundary. E.g on a system with 4G as low memory end,
user added the kernel parameters like: 'crashkernel=512M,high', it could
finally have [4G-126M, 4G+386M], [1G, 1G+128M] regions in running kernel.
The crashkernel high region crossing low and high memory boudary will bring
issues:
1) For crashkernel=x,high, if getting crashkernel high region across
low and high memory boundary, then user will see two memory regions in
low memory, and one memory region in high memory. The two crashkernel
low memory regions are confusing as shown in above example.
2) If people explicityly specify "crashkernel=x,high crashkernel=y,low"
and y <= 128M, when crashkernel high region crosses low and high memory
boundary and the part of crashkernel high reservation below boundary is
bigger than y, the expected crahskernel low reservation will be skipped.
But the expected crashkernel high reservation is shrank and could not
satisfy user space requirement.
3) The crossing boundary behaviour of crahskernel high reservation is
different than x86 arch. On x86_64, the low memory end is 4G fixedly,
and the memory near 4G is reserved by system, e.g for mapping firmware,
pci mapping, so the crashkernel reservation crossing boundary never happens.
From distros point of view, this brings inconsistency and confusion. Users
need to dig into x86 and arm64 system details to find out why.
For kernel itself, the impact of issue 3) could be slight. While issue
1) and 2) cause actual impact because it brings obscure semantics and
behaviour to crashkernel=,high reservation.
Here, for crashkernel=xM,high, search the high memory for the suitable
region only in high memory. If failed, try reserving the suitable
region only in low memory. Like this, the crashkernel high region will
only exist in high memory, and crashkernel low region only exists in low
memory. The reservation behaviour for crashkernel=,high is clearer and
simpler.
Note: On arm64, the high and low memory boudary could be 1G if it's RPi4
system, or 4G if other normal systems.
Signed-off-by: Baoquan He <bhe@redhat.com>
---
v2->v3:
- Rephrase patch log to clarify the current crashkernel high
reservation could cross the high and low memory boundary, but not
4G boundary only, because RPi4 of arm64 has high and low memory
boudary as 1G. The v3 patch log could mislead people that the RPi4
also use 4G as high,low memory boundary.
v1->v2:
- Fold patch 2 of v1 into patch 1 for better reviewing.
- Update patch log to add more details.
arch/arm64/mm/init.c | 43 +++++++++++++++++++++++++++++++++----------
1 file changed, 33 insertions(+), 10 deletions(-)
Comments
On 2023/2/23 20:45, Baoquan He wrote: > On arm64, reservation for 'crashkernel=xM,high' is taken by searching for > suitable memory region top down. If the 'xM' of crashkernel high memory > is reserved from high memory successfully, it will try to reserve > crashkernel low memory later accoringly. Otherwise, it will try to search > low memory area for the 'xM' suitable region. Please see the details in > Documentation/admin-guide/kernel-parameters.txt. > > While we observed an unexpected case where a reserved region crosses the > high and low meomry boundary. E.g on a system with 4G as low memory end, > user added the kernel parameters like: 'crashkernel=512M,high', it could > finally have [4G-126M, 4G+386M], [1G, 1G+128M] regions in running kernel. > The crashkernel high region crossing low and high memory boudary will bring > issues: > > 1) For crashkernel=x,high, if getting crashkernel high region across > low and high memory boundary, then user will see two memory regions in > low memory, and one memory region in high memory. The two crashkernel > low memory regions are confusing as shown in above example. > > 2) If people explicityly specify "crashkernel=x,high crashkernel=y,low" > and y <= 128M, when crashkernel high region crosses low and high memory > boundary and the part of crashkernel high reservation below boundary is > bigger than y, the expected crahskernel low reservation will be skipped. > But the expected crashkernel high reservation is shrank and could not > satisfy user space requirement. > > 3) The crossing boundary behaviour of crahskernel high reservation is > different than x86 arch. On x86_64, the low memory end is 4G fixedly, > and the memory near 4G is reserved by system, e.g for mapping firmware, > pci mapping, so the crashkernel reservation crossing boundary never happens. >>From distros point of view, this brings inconsistency and confusion. Users > need to dig into x86 and arm64 system details to find out why. > > For kernel itself, the impact of issue 3) could be slight. While issue > 1) and 2) cause actual impact because it brings obscure semantics and > behaviour to crashkernel=,high reservation. > > Here, for crashkernel=xM,high, search the high memory for the suitable > region only in high memory. If failed, try reserving the suitable > region only in low memory. Like this, the crashkernel high region will > only exist in high memory, and crashkernel low region only exists in low > memory. The reservation behaviour for crashkernel=,high is clearer and > simpler. > > Note: On arm64, the high and low memory boudary could be 1G if it's RPi4 > system, or 4G if other normal systems. There are two minor review comments, see below. Otherwise: Reviewed-by: Zhen Lei <thunder.leizhen@huawei.com> > > Signed-off-by: Baoquan He <bhe@redhat.com> > --- > v2->v3: > - Rephrase patch log to clarify the current crashkernel high > reservation could cross the high and low memory boundary, but not > 4G boundary only, because RPi4 of arm64 has high and low memory > boudary as 1G. The v3 patch log could mislead people that the RPi4 > also use 4G as high,low memory boundary. > v1->v2: > - Fold patch 2 of v1 into patch 1 for better reviewing. > - Update patch log to add more details. > arch/arm64/mm/init.c | 43 +++++++++++++++++++++++++++++++++---------- > 1 file changed, 33 insertions(+), 10 deletions(-) > > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c > index 58a0bb2c17f1..b8cb780df0cb 100644 > --- a/arch/arm64/mm/init.c > +++ b/arch/arm64/mm/init.c > @@ -127,12 +127,13 @@ static int __init reserve_crashkernel_low(unsigned long long low_size) > */ > static void __init reserve_crashkernel(void) > { > - unsigned long long crash_base, crash_size; > - unsigned long long crash_low_size = 0; > + unsigned long long crash_base, crash_size, search_base; > unsigned long long crash_max = CRASH_ADDR_LOW_MAX; > + unsigned long long crash_low_size = 0; > char *cmdline = boot_command_line; > - int ret; > bool fixed_base = false; > + bool high = false; > + int ret; > > if (!IS_ENABLED(CONFIG_KEXEC_CORE)) > return; > @@ -155,7 +156,9 @@ static void __init reserve_crashkernel(void) > else if (ret) > return; > > + search_base = CRASH_ADDR_LOW_MAX; > crash_max = CRASH_ADDR_HIGH_MAX; > + high = true; > } else if (ret || !crash_size) { > /* The specified value is invalid */ > return; > @@ -166,31 +169,51 @@ static void __init reserve_crashkernel(void) > /* User specifies base address explicitly. */ > if (crash_base) { > fixed_base = true; > + search_base = crash_base; > crash_max = crash_base + crash_size; > } > > retry: > crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN, > - crash_base, crash_max); > + search_base, crash_max); > if (!crash_base) { > /* > - * If the first attempt was for low memory, fall back to > - * high memory, the minimum required low memory will be > - * reserved later. > + * For crashkernel=size[KMG]@offset[KMG], print out failure > + * message if can't reserve the specified region. > */ > - if (!fixed_base && (crash_max == CRASH_ADDR_LOW_MAX)) { > + if (fixed_base) { > + pr_info("crashkernel reservation failed - memory is in use.\n"); How about changing pr_info to pr_warn? > + return; > + } > + > + /* > + * For crashkernel=size[KMG], if the first attempt was for > + * low memory, fall back to high memory, the minimum required > + * low memory will be reserved later. > + */ > + if (!high && crash_max == CRASH_ADDR_LOW_MAX) { > crash_max = CRASH_ADDR_HIGH_MAX; > + search_base = CRASH_ADDR_LOW_MAX; > crash_low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE; > goto retry; > } > > + /* > + * For crashkernel=size[KMG],high, if the first attempt was > + * for high memory, fall back to low memory. > + */ > + if (high && crash_max == CRASH_ADDR_HIGH_MAX) { Adding unlikely to indicate that it is rare would be better. if (unlikely(high && crash_max == CRASH_ADDR_HIGH_MAX)) > + crash_max = CRASH_ADDR_LOW_MAX; > + search_base = 0; > + goto retry; > + } > pr_warn("cannot allocate crashkernel (size:0x%llx)\n", > crash_size); > return; > } > > - if ((crash_base > CRASH_ADDR_LOW_MAX - crash_low_size) && > - crash_low_size && reserve_crashkernel_low(crash_low_size)) { > + if ((crash_base >= CRASH_ADDR_LOW_MAX) && crash_low_size && > + reserve_crashkernel_low(crash_low_size)) { > memblock_phys_free(crash_base, crash_size); > return; > } >
On 03/02/23 at 11:32am, Leizhen (ThunderTown) wrote: > > > On 2023/2/23 20:45, Baoquan He wrote: ...... > There are two minor review comments, see below. Otherwise: Makes sense, all accepted. Will update and repost. Thanks for careful reviewing. > > Reviewed-by: Zhen Lei <thunder.leizhen@huawei.com> > > > > > Signed-off-by: Baoquan He <bhe@redhat.com> > > --- > > v2->v3: > > - Rephrase patch log to clarify the current crashkernel high > > reservation could cross the high and low memory boundary, but not > > 4G boundary only, because RPi4 of arm64 has high and low memory > > boudary as 1G. The v3 patch log could mislead people that the RPi4 > > also use 4G as high,low memory boundary. > > v1->v2: > > - Fold patch 2 of v1 into patch 1 for better reviewing. > > - Update patch log to add more details. > > arch/arm64/mm/init.c | 43 +++++++++++++++++++++++++++++++++---------- > > 1 file changed, 33 insertions(+), 10 deletions(-) > > > > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c > > index 58a0bb2c17f1..b8cb780df0cb 100644 > > --- a/arch/arm64/mm/init.c > > +++ b/arch/arm64/mm/init.c > > @@ -127,12 +127,13 @@ static int __init reserve_crashkernel_low(unsigned long long low_size) > > */ > > static void __init reserve_crashkernel(void) > > { > > - unsigned long long crash_base, crash_size; > > - unsigned long long crash_low_size = 0; > > + unsigned long long crash_base, crash_size, search_base; > > unsigned long long crash_max = CRASH_ADDR_LOW_MAX; > > + unsigned long long crash_low_size = 0; > > char *cmdline = boot_command_line; > > - int ret; > > bool fixed_base = false; > > + bool high = false; > > + int ret; > > > > if (!IS_ENABLED(CONFIG_KEXEC_CORE)) > > return; > > @@ -155,7 +156,9 @@ static void __init reserve_crashkernel(void) > > else if (ret) > > return; > > > > + search_base = CRASH_ADDR_LOW_MAX; > > crash_max = CRASH_ADDR_HIGH_MAX; > > + high = true; > > } else if (ret || !crash_size) { > > /* The specified value is invalid */ > > return; > > @@ -166,31 +169,51 @@ static void __init reserve_crashkernel(void) > > /* User specifies base address explicitly. */ > > if (crash_base) { > > fixed_base = true; > > + search_base = crash_base; > > crash_max = crash_base + crash_size; > > } > > > > retry: > > crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN, > > - crash_base, crash_max); > > + search_base, crash_max); > > if (!crash_base) { > > /* > > - * If the first attempt was for low memory, fall back to > > - * high memory, the minimum required low memory will be > > - * reserved later. > > + * For crashkernel=size[KMG]@offset[KMG], print out failure > > + * message if can't reserve the specified region. > > */ > > - if (!fixed_base && (crash_max == CRASH_ADDR_LOW_MAX)) { > > + if (fixed_base) { > > + pr_info("crashkernel reservation failed - memory is in use.\n"); > > How about changing pr_info to pr_warn? > > > + return; > > + } > > + > > + /* > > + * For crashkernel=size[KMG], if the first attempt was for > > + * low memory, fall back to high memory, the minimum required > > + * low memory will be reserved later. > > + */ > > + if (!high && crash_max == CRASH_ADDR_LOW_MAX) { > > crash_max = CRASH_ADDR_HIGH_MAX; > > + search_base = CRASH_ADDR_LOW_MAX; > > crash_low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE; > > goto retry; > > } > > > > + /* > > + * For crashkernel=size[KMG],high, if the first attempt was > > + * for high memory, fall back to low memory. > > + */ > > + if (high && crash_max == CRASH_ADDR_HIGH_MAX) { > > Adding unlikely to indicate that it is rare would be better. > > if (unlikely(high && crash_max == CRASH_ADDR_HIGH_MAX)) > > > + crash_max = CRASH_ADDR_LOW_MAX; > > + search_base = 0; > > + goto retry; > > + } > > pr_warn("cannot allocate crashkernel (size:0x%llx)\n", > > crash_size); > > return; > > } > > > > - if ((crash_base > CRASH_ADDR_LOW_MAX - crash_low_size) && > > - crash_low_size && reserve_crashkernel_low(crash_low_size)) { > > + if ((crash_base >= CRASH_ADDR_LOW_MAX) && crash_low_size && > > + reserve_crashkernel_low(crash_low_size)) { > > memblock_phys_free(crash_base, crash_size); > > return; > > } > > > > -- > Regards, > Zhen Lei >
On 03/02/23 at 11:32am, Leizhen (ThunderTown) wrote: ...... > > @@ -166,31 +169,51 @@ static void __init reserve_crashkernel(void) > > /* User specifies base address explicitly. */ > > if (crash_base) { > > fixed_base = true; > > + search_base = crash_base; > > crash_max = crash_base + crash_size; > > } > > > > retry: > > crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN, > > - crash_base, crash_max); > > + search_base, crash_max); > > if (!crash_base) { > > /* > > - * If the first attempt was for low memory, fall back to > > - * high memory, the minimum required low memory will be > > - * reserved later. > > + * For crashkernel=size[KMG]@offset[KMG], print out failure > > + * message if can't reserve the specified region. > > */ > > - if (!fixed_base && (crash_max == CRASH_ADDR_LOW_MAX)) { > > + if (fixed_base) { > > + pr_info("crashkernel reservation failed - memory is in use.\n"); > > How about changing pr_info to pr_warn? > > > + return; > > + } > > + > > + /* > > + * For crashkernel=size[KMG], if the first attempt was for > > + * low memory, fall back to high memory, the minimum required > > + * low memory will be reserved later. > > + */ > > + if (!high && crash_max == CRASH_ADDR_LOW_MAX) { > > crash_max = CRASH_ADDR_HIGH_MAX; > > + search_base = CRASH_ADDR_LOW_MAX; > > crash_low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE; > > goto retry; > > } > > > > + /* > > + * For crashkernel=size[KMG],high, if the first attempt was > > + * for high memory, fall back to low memory. > > + */ > > + if (high && crash_max == CRASH_ADDR_HIGH_MAX) { > > Adding unlikely to indicate that it is rare would be better. > > if (unlikely(high && crash_max == CRASH_ADDR_HIGH_MAX)) Rethink about this and checked code in kernel, seems likely|unlikely are mostly used in highly frequent execution branch optimize code path, while crashkernel resevatoin is one time execution during boot, we may not need to bother to add unlikely. What do you think? > > > + crash_max = CRASH_ADDR_LOW_MAX; > > + search_base = 0; > > + goto retry; > > + } > > pr_warn("cannot allocate crashkernel (size:0x%llx)\n", > > crash_size); > > return; > > } > > > > - if ((crash_base > CRASH_ADDR_LOW_MAX - crash_low_size) && > > - crash_low_size && reserve_crashkernel_low(crash_low_size)) { > > + if ((crash_base >= CRASH_ADDR_LOW_MAX) && crash_low_size && > > + reserve_crashkernel_low(crash_low_size)) { > > memblock_phys_free(crash_base, crash_size); > > return; > > } > > > > -- > Regards, > Zhen Lei >
On 2023/3/3 11:01, Baoquan He wrote: > On 03/02/23 at 11:32am, Leizhen (ThunderTown) wrote: > ...... >>> @@ -166,31 +169,51 @@ static void __init reserve_crashkernel(void) >>> /* User specifies base address explicitly. */ >>> if (crash_base) { >>> fixed_base = true; >>> + search_base = crash_base; >>> crash_max = crash_base + crash_size; >>> } >>> >>> retry: >>> crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN, >>> - crash_base, crash_max); >>> + search_base, crash_max); >>> if (!crash_base) { >>> /* >>> - * If the first attempt was for low memory, fall back to >>> - * high memory, the minimum required low memory will be >>> - * reserved later. >>> + * For crashkernel=size[KMG]@offset[KMG], print out failure >>> + * message if can't reserve the specified region. >>> */ >>> - if (!fixed_base && (crash_max == CRASH_ADDR_LOW_MAX)) { >>> + if (fixed_base) { >>> + pr_info("crashkernel reservation failed - memory is in use.\n"); >> >> How about changing pr_info to pr_warn? >> >>> + return; >>> + } >>> + >>> + /* >>> + * For crashkernel=size[KMG], if the first attempt was for >>> + * low memory, fall back to high memory, the minimum required >>> + * low memory will be reserved later. >>> + */ >>> + if (!high && crash_max == CRASH_ADDR_LOW_MAX) { >>> crash_max = CRASH_ADDR_HIGH_MAX; >>> + search_base = CRASH_ADDR_LOW_MAX; >>> crash_low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE; >>> goto retry; >>> } >>> >>> + /* >>> + * For crashkernel=size[KMG],high, if the first attempt was >>> + * for high memory, fall back to low memory. >>> + */ >>> + if (high && crash_max == CRASH_ADDR_HIGH_MAX) { >> >> Adding unlikely to indicate that it is rare would be better. >> >> if (unlikely(high && crash_max == CRASH_ADDR_HIGH_MAX)) > > Rethink about this and checked code in kernel, seems likely|unlikely are > mostly used in highly frequent execution branch optimize code path, while > crashkernel resevatoin is one time execution during boot, we may not > need to bother to add unlikely. What do you think? OK. > > >> >>> + crash_max = CRASH_ADDR_LOW_MAX; >>> + search_base = 0; >>> + goto retry; >>> + } >>> pr_warn("cannot allocate crashkernel (size:0x%llx)\n", >>> crash_size); >>> return; >>> } >>> >>> - if ((crash_base > CRASH_ADDR_LOW_MAX - crash_low_size) && >>> - crash_low_size && reserve_crashkernel_low(crash_low_size)) { >>> + if ((crash_base >= CRASH_ADDR_LOW_MAX) && crash_low_size && >>> + reserve_crashkernel_low(crash_low_size)) { >>> memblock_phys_free(crash_base, crash_size); >>> return; >>> } >>> >> >> -- >> Regards, >> Zhen Lei >> > > . >
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 58a0bb2c17f1..b8cb780df0cb 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -127,12 +127,13 @@ static int __init reserve_crashkernel_low(unsigned long long low_size) */ static void __init reserve_crashkernel(void) { - unsigned long long crash_base, crash_size; - unsigned long long crash_low_size = 0; + unsigned long long crash_base, crash_size, search_base; unsigned long long crash_max = CRASH_ADDR_LOW_MAX; + unsigned long long crash_low_size = 0; char *cmdline = boot_command_line; - int ret; bool fixed_base = false; + bool high = false; + int ret; if (!IS_ENABLED(CONFIG_KEXEC_CORE)) return; @@ -155,7 +156,9 @@ static void __init reserve_crashkernel(void) else if (ret) return; + search_base = CRASH_ADDR_LOW_MAX; crash_max = CRASH_ADDR_HIGH_MAX; + high = true; } else if (ret || !crash_size) { /* The specified value is invalid */ return; @@ -166,31 +169,51 @@ static void __init reserve_crashkernel(void) /* User specifies base address explicitly. */ if (crash_base) { fixed_base = true; + search_base = crash_base; crash_max = crash_base + crash_size; } retry: crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN, - crash_base, crash_max); + search_base, crash_max); if (!crash_base) { /* - * If the first attempt was for low memory, fall back to - * high memory, the minimum required low memory will be - * reserved later. + * For crashkernel=size[KMG]@offset[KMG], print out failure + * message if can't reserve the specified region. */ - if (!fixed_base && (crash_max == CRASH_ADDR_LOW_MAX)) { + if (fixed_base) { + pr_info("crashkernel reservation failed - memory is in use.\n"); + return; + } + + /* + * For crashkernel=size[KMG], if the first attempt was for + * low memory, fall back to high memory, the minimum required + * low memory will be reserved later. + */ + if (!high && crash_max == CRASH_ADDR_LOW_MAX) { crash_max = CRASH_ADDR_HIGH_MAX; + search_base = CRASH_ADDR_LOW_MAX; crash_low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE; goto retry; } + /* + * For crashkernel=size[KMG],high, if the first attempt was + * for high memory, fall back to low memory. + */ + if (high && crash_max == CRASH_ADDR_HIGH_MAX) { + crash_max = CRASH_ADDR_LOW_MAX; + search_base = 0; + goto retry; + } pr_warn("cannot allocate crashkernel (size:0x%llx)\n", crash_size); return; } - if ((crash_base > CRASH_ADDR_LOW_MAX - crash_low_size) && - crash_low_size && reserve_crashkernel_low(crash_low_size)) { + if ((crash_base >= CRASH_ADDR_LOW_MAX) && crash_low_size && + reserve_crashkernel_low(crash_low_size)) { memblock_phys_free(crash_base, crash_size); return; }