From: Pingfan Liu <kernelfans@gmail.com>
To: kexec@lists.infradead.org
Subject: [PATCHv4 1/2] cpu/hotplug: Keep cpu hotplug disabled until the rebooting cpu is stable
Date: Thu, 12 May 2022 11:06:18 +0800 [thread overview]
Message-ID: <20220512030619.13426-2-kernelfans@gmail.com> (raw)
In-Reply-To: <20220512030619.13426-1-kernelfans@gmail.com>
smp_shutdown_nonboot_cpus() repeats the same code chunk as
migrate_to_reboot_cpu() to ensure that the rebooting happens on a valid
cpu.
if (!cpu_online(primary_cpu))
primary_cpu = cpumask_first(cpu_online_mask);
This is due to an unexpected cpu-down event like the following:
kernel_kexec()
migrate_to_reboot_cpu();
cpu_hotplug_enable();
-----------> comes a cpu_down(this_cpu) on other cpu
machine_shutdown();
smp_shutdown_nonboot_cpus(); which needs to re-check "if (!cpu_online(primary_cpu))"
Although the kexec-reboot task can get through a cpu_down() on its cpu,
this code looks a little confusing.
Tracing down the git history, the cpu_hotplug_enable() called by
kernel_kexec() is introduced by commit 011e4b02f1da ("powerpc, kexec:
Fix "Processor X is stuck" issue during kexec from ST mode"), which
wakes up all offline cpu by cpu_up(cpu). Later, it is required by the
architectures(arm/arm64/ia64/riscv) which resort to cpu hot-removing to
achieve kexec-reboot by
smp_shutdown_nonboot_cpus()->cpu_down_maps_locked().
Hence, the cpu_hotplug_enable() in kernel_kexec() is an architecture
requirement.
By deferring the cpu hotplug enable to a more proper point, where
smp_shutdown_nonboot_cpus() holds cpu_add_remove_lock, the
unexpected cpu-down event is squashed out and the rebooting cpu can keep
unchanged. (For powerpc, no gains from this change.)
As a result, the repeated code chunk can be removed and in [2/2], the
callsites of smp_shutdown_nonboot_cpus() can be consistent.
Signed-off-by: Pingfan Liu <kernelfans@gmail.com>
Cc: Eric Biederman <ebiederm@xmission.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vincent Donnefort <vincent.donnefort@arm.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: YueHaibing <yuehaibing@huawei.com>
Cc: Baokun Li <libaokun1@huawei.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Valentin Schneider <valentin.schneider@arm.com>
Cc: kexec at lists.infradead.org
To: linuxppc-dev@lists.ozlabs.org
To: linux-kernel@vger.kernel.org
---
arch/powerpc/kexec/core_64.c | 1 +
kernel/cpu.c | 10 +++++-----
kernel/kexec_core.c | 11 +++++------
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c
index 6cc7793b8420..8ccf22197f08 100644
--- a/arch/powerpc/kexec/core_64.c
+++ b/arch/powerpc/kexec/core_64.c
@@ -224,6 +224,7 @@ static void wake_offline_cpus(void)
static void kexec_prepare_cpus(void)
{
+ cpu_hotplug_enable();
wake_offline_cpus();
smp_call_function(kexec_smp_down, NULL, /* wait */0);
local_irq_disable();
diff --git a/kernel/cpu.c b/kernel/cpu.c
index d0a9aa0b42e8..4415370f0e91 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1236,12 +1236,12 @@ void smp_shutdown_nonboot_cpus(unsigned int primary_cpu)
cpu_maps_update_begin();
/*
- * Make certain the cpu I'm about to reboot on is online.
- *
- * This is inline to what migrate_to_reboot_cpu() already do.
+ * At this point, the cpu hotplug is still disabled by
+ * migrate_to_reboot_cpu() to guarantee that the rebooting happens on
+ * the selected CPU. But cpu_down_maps_locked() returns -EBUSY, if
+ * cpu_hotplug_disabled. So re-enable CPU hotplug here.
*/
- if (!cpu_online(primary_cpu))
- primary_cpu = cpumask_first(cpu_online_mask);
+ __cpu_hotplug_enable();
for_each_online_cpu(cpu) {
if (cpu == primary_cpu)
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index 68480f731192..1bd5a8c95a20 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -1168,14 +1168,13 @@ int kernel_kexec(void)
kexec_in_progress = true;
kernel_restart_prepare("kexec reboot");
migrate_to_reboot_cpu();
-
/*
- * migrate_to_reboot_cpu() disables CPU hotplug assuming that
- * no further code needs to use CPU hotplug (which is true in
- * the reboot case). However, the kexec path depends on using
- * CPU hotplug again; so re-enable it here.
+ * migrate_to_reboot_cpu() disables CPU hotplug and pin the
+ * rebooting thread on the selected CPU. If an architecture
+ * requires CPU hotplug to achieve kexec reboot, it should
+ * enable the hotplug in the architecture specific code
*/
- cpu_hotplug_enable();
+
pr_notice("Starting new kernel\n");
machine_shutdown();
}
--
2.31.1
WARNING: multiple messages have this Message-ID (diff)
From: Pingfan Liu <kernelfans@gmail.com>
To: linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org
Cc: Mark Rutland <mark.rutland@arm.com>,
Vincent Donnefort <vincent.donnefort@arm.com>,
Peter Zijlstra <peterz@infradead.org>,
Randy Dunlap <rdunlap@infradead.org>,
YueHaibing <yuehaibing@huawei.com>,
Pingfan Liu <kernelfans@gmail.com>,
Valentin Schneider <valentin.schneider@arm.com>,
Baokun Li <libaokun1@huawei.com>,
Eric Biederman <ebiederm@xmission.com>,
kexec@lists.infradead.org, Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@kernel.org>
Subject: [PATCHv4 1/2] cpu/hotplug: Keep cpu hotplug disabled until the rebooting cpu is stable
Date: Thu, 12 May 2022 11:06:18 +0800 [thread overview]
Message-ID: <20220512030619.13426-2-kernelfans@gmail.com> (raw)
In-Reply-To: <20220512030619.13426-1-kernelfans@gmail.com>
smp_shutdown_nonboot_cpus() repeats the same code chunk as
migrate_to_reboot_cpu() to ensure that the rebooting happens on a valid
cpu.
if (!cpu_online(primary_cpu))
primary_cpu = cpumask_first(cpu_online_mask);
This is due to an unexpected cpu-down event like the following:
kernel_kexec()
migrate_to_reboot_cpu();
cpu_hotplug_enable();
-----------> comes a cpu_down(this_cpu) on other cpu
machine_shutdown();
smp_shutdown_nonboot_cpus(); which needs to re-check "if (!cpu_online(primary_cpu))"
Although the kexec-reboot task can get through a cpu_down() on its cpu,
this code looks a little confusing.
Tracing down the git history, the cpu_hotplug_enable() called by
kernel_kexec() is introduced by commit 011e4b02f1da ("powerpc, kexec:
Fix "Processor X is stuck" issue during kexec from ST mode"), which
wakes up all offline cpu by cpu_up(cpu). Later, it is required by the
architectures(arm/arm64/ia64/riscv) which resort to cpu hot-removing to
achieve kexec-reboot by
smp_shutdown_nonboot_cpus()->cpu_down_maps_locked().
Hence, the cpu_hotplug_enable() in kernel_kexec() is an architecture
requirement.
By deferring the cpu hotplug enable to a more proper point, where
smp_shutdown_nonboot_cpus() holds cpu_add_remove_lock, the
unexpected cpu-down event is squashed out and the rebooting cpu can keep
unchanged. (For powerpc, no gains from this change.)
As a result, the repeated code chunk can be removed and in [2/2], the
callsites of smp_shutdown_nonboot_cpus() can be consistent.
Signed-off-by: Pingfan Liu <kernelfans@gmail.com>
Cc: Eric Biederman <ebiederm@xmission.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vincent Donnefort <vincent.donnefort@arm.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: YueHaibing <yuehaibing@huawei.com>
Cc: Baokun Li <libaokun1@huawei.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Valentin Schneider <valentin.schneider@arm.com>
Cc: kexec@lists.infradead.org
To: linuxppc-dev@lists.ozlabs.org
To: linux-kernel@vger.kernel.org
---
arch/powerpc/kexec/core_64.c | 1 +
kernel/cpu.c | 10 +++++-----
kernel/kexec_core.c | 11 +++++------
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c
index 6cc7793b8420..8ccf22197f08 100644
--- a/arch/powerpc/kexec/core_64.c
+++ b/arch/powerpc/kexec/core_64.c
@@ -224,6 +224,7 @@ static void wake_offline_cpus(void)
static void kexec_prepare_cpus(void)
{
+ cpu_hotplug_enable();
wake_offline_cpus();
smp_call_function(kexec_smp_down, NULL, /* wait */0);
local_irq_disable();
diff --git a/kernel/cpu.c b/kernel/cpu.c
index d0a9aa0b42e8..4415370f0e91 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1236,12 +1236,12 @@ void smp_shutdown_nonboot_cpus(unsigned int primary_cpu)
cpu_maps_update_begin();
/*
- * Make certain the cpu I'm about to reboot on is online.
- *
- * This is inline to what migrate_to_reboot_cpu() already do.
+ * At this point, the cpu hotplug is still disabled by
+ * migrate_to_reboot_cpu() to guarantee that the rebooting happens on
+ * the selected CPU. But cpu_down_maps_locked() returns -EBUSY, if
+ * cpu_hotplug_disabled. So re-enable CPU hotplug here.
*/
- if (!cpu_online(primary_cpu))
- primary_cpu = cpumask_first(cpu_online_mask);
+ __cpu_hotplug_enable();
for_each_online_cpu(cpu) {
if (cpu == primary_cpu)
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index 68480f731192..1bd5a8c95a20 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -1168,14 +1168,13 @@ int kernel_kexec(void)
kexec_in_progress = true;
kernel_restart_prepare("kexec reboot");
migrate_to_reboot_cpu();
-
/*
- * migrate_to_reboot_cpu() disables CPU hotplug assuming that
- * no further code needs to use CPU hotplug (which is true in
- * the reboot case). However, the kexec path depends on using
- * CPU hotplug again; so re-enable it here.
+ * migrate_to_reboot_cpu() disables CPU hotplug and pin the
+ * rebooting thread on the selected CPU. If an architecture
+ * requires CPU hotplug to achieve kexec reboot, it should
+ * enable the hotplug in the architecture specific code
*/
- cpu_hotplug_enable();
+
pr_notice("Starting new kernel\n");
machine_shutdown();
}
--
2.31.1
WARNING: multiple messages have this Message-ID (diff)
From: Pingfan Liu <kernelfans@gmail.com>
To: linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org
Cc: Pingfan Liu <kernelfans@gmail.com>,
Eric Biederman <ebiederm@xmission.com>,
Peter Zijlstra <peterz@infradead.org>,
Thomas Gleixner <tglx@linutronix.de>,
Vincent Donnefort <vincent.donnefort@arm.com>,
Ingo Molnar <mingo@kernel.org>,
Michael Ellerman <mpe@ellerman.id.au>,
Mark Rutland <mark.rutland@arm.com>,
YueHaibing <yuehaibing@huawei.com>,
Baokun Li <libaokun1@huawei.com>,
Randy Dunlap <rdunlap@infradead.org>,
Valentin Schneider <valentin.schneider@arm.com>,
kexec@lists.infradead.org
Subject: [PATCHv4 1/2] cpu/hotplug: Keep cpu hotplug disabled until the rebooting cpu is stable
Date: Thu, 12 May 2022 11:06:18 +0800 [thread overview]
Message-ID: <20220512030619.13426-2-kernelfans@gmail.com> (raw)
In-Reply-To: <20220512030619.13426-1-kernelfans@gmail.com>
smp_shutdown_nonboot_cpus() repeats the same code chunk as
migrate_to_reboot_cpu() to ensure that the rebooting happens on a valid
cpu.
if (!cpu_online(primary_cpu))
primary_cpu = cpumask_first(cpu_online_mask);
This is due to an unexpected cpu-down event like the following:
kernel_kexec()
migrate_to_reboot_cpu();
cpu_hotplug_enable();
-----------> comes a cpu_down(this_cpu) on other cpu
machine_shutdown();
smp_shutdown_nonboot_cpus(); which needs to re-check "if (!cpu_online(primary_cpu))"
Although the kexec-reboot task can get through a cpu_down() on its cpu,
this code looks a little confusing.
Tracing down the git history, the cpu_hotplug_enable() called by
kernel_kexec() is introduced by commit 011e4b02f1da ("powerpc, kexec:
Fix "Processor X is stuck" issue during kexec from ST mode"), which
wakes up all offline cpu by cpu_up(cpu). Later, it is required by the
architectures(arm/arm64/ia64/riscv) which resort to cpu hot-removing to
achieve kexec-reboot by
smp_shutdown_nonboot_cpus()->cpu_down_maps_locked().
Hence, the cpu_hotplug_enable() in kernel_kexec() is an architecture
requirement.
By deferring the cpu hotplug enable to a more proper point, where
smp_shutdown_nonboot_cpus() holds cpu_add_remove_lock, the
unexpected cpu-down event is squashed out and the rebooting cpu can keep
unchanged. (For powerpc, no gains from this change.)
As a result, the repeated code chunk can be removed and in [2/2], the
callsites of smp_shutdown_nonboot_cpus() can be consistent.
Signed-off-by: Pingfan Liu <kernelfans@gmail.com>
Cc: Eric Biederman <ebiederm@xmission.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vincent Donnefort <vincent.donnefort@arm.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: YueHaibing <yuehaibing@huawei.com>
Cc: Baokun Li <libaokun1@huawei.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Valentin Schneider <valentin.schneider@arm.com>
Cc: kexec@lists.infradead.org
To: linuxppc-dev@lists.ozlabs.org
To: linux-kernel@vger.kernel.org
---
arch/powerpc/kexec/core_64.c | 1 +
kernel/cpu.c | 10 +++++-----
kernel/kexec_core.c | 11 +++++------
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c
index 6cc7793b8420..8ccf22197f08 100644
--- a/arch/powerpc/kexec/core_64.c
+++ b/arch/powerpc/kexec/core_64.c
@@ -224,6 +224,7 @@ static void wake_offline_cpus(void)
static void kexec_prepare_cpus(void)
{
+ cpu_hotplug_enable();
wake_offline_cpus();
smp_call_function(kexec_smp_down, NULL, /* wait */0);
local_irq_disable();
diff --git a/kernel/cpu.c b/kernel/cpu.c
index d0a9aa0b42e8..4415370f0e91 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1236,12 +1236,12 @@ void smp_shutdown_nonboot_cpus(unsigned int primary_cpu)
cpu_maps_update_begin();
/*
- * Make certain the cpu I'm about to reboot on is online.
- *
- * This is inline to what migrate_to_reboot_cpu() already do.
+ * At this point, the cpu hotplug is still disabled by
+ * migrate_to_reboot_cpu() to guarantee that the rebooting happens on
+ * the selected CPU. But cpu_down_maps_locked() returns -EBUSY, if
+ * cpu_hotplug_disabled. So re-enable CPU hotplug here.
*/
- if (!cpu_online(primary_cpu))
- primary_cpu = cpumask_first(cpu_online_mask);
+ __cpu_hotplug_enable();
for_each_online_cpu(cpu) {
if (cpu == primary_cpu)
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index 68480f731192..1bd5a8c95a20 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -1168,14 +1168,13 @@ int kernel_kexec(void)
kexec_in_progress = true;
kernel_restart_prepare("kexec reboot");
migrate_to_reboot_cpu();
-
/*
- * migrate_to_reboot_cpu() disables CPU hotplug assuming that
- * no further code needs to use CPU hotplug (which is true in
- * the reboot case). However, the kexec path depends on using
- * CPU hotplug again; so re-enable it here.
+ * migrate_to_reboot_cpu() disables CPU hotplug and pin the
+ * rebooting thread on the selected CPU. If an architecture
+ * requires CPU hotplug to achieve kexec reboot, it should
+ * enable the hotplug in the architecture specific code
*/
- cpu_hotplug_enable();
+
pr_notice("Starting new kernel\n");
machine_shutdown();
}
--
2.31.1
next prev parent reply other threads:[~2022-05-12 3:06 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-12 3:06 [PATCHv4 0/2] cpu/hotplug: Keep cpu hotplug disabled until the rebooting cpu is stable Pingfan Liu
2022-05-12 3:06 ` Pingfan Liu
2022-05-12 3:06 ` Pingfan Liu [this message]
2022-05-12 3:06 ` [PATCHv4 1/2] " Pingfan Liu
2022-05-12 3:06 ` Pingfan Liu
2022-05-12 3:06 ` [PATCHv4 2/2] cpu/hotplug: Remove the input parameter primary_cpu of smp_shutdown_nonboot_cpus() Pingfan Liu
2022-05-12 3:06 ` Pingfan Liu
2022-05-12 3:06 ` Pingfan Liu
2022-05-15 10:03 ` Catalin Marinas
2022-05-15 10:03 ` Catalin Marinas
2022-05-15 10:03 ` Catalin Marinas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220512030619.13426-2-kernelfans@gmail.com \
--to=kernelfans@gmail.com \
--cc=kexec@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.