From nobody Thu May 14 10:27:16 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 06C81C433F5 for ; Mon, 11 Apr 2022 15:22:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347873AbiDKPZJ (ORCPT ); Mon, 11 Apr 2022 11:25:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46026 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346414AbiDKPY7 (ORCPT ); Mon, 11 Apr 2022 11:24:59 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 3CF153B2BF for ; Mon, 11 Apr 2022 08:22:45 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 08119169C; Mon, 11 Apr 2022 08:22:45 -0700 (PDT) Received: from e122027.arm.com (unknown [10.57.40.227]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 557503F73B; Mon, 11 Apr 2022 08:22:43 -0700 (PDT) From: Steven Price To: Thomas Gleixner , Vincent Donnefort , Peter Zijlstra Cc: Steven Price , linux-kernel@vger.kernel.org, Baokun Li , Dongli Zhang , Randy Dunlap , Valentin Schneider , Yuan ZhaoXiong , YueHaibing , Dietmar Eggemann Subject: [PATCH v3 1/2] cpu/hotplug: Remove the 'cpu' member of cpuhp_cpu_state Date: Mon, 11 Apr 2022 16:22:32 +0100 Message-Id: <20220411152233.474129-2-steven.price@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220411152233.474129-1-steven.price@arm.com> References: <20220411152233.474129-1-steven.price@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Currently the setting of the 'cpu' member of struct cpuhp_cpu_state in cpuhp_create() is too late as it is used earlier in _cpu_up(). If the kzalloc_node() in __smpboot_create_thread() fails then the rollback will be done with st->cpu=3D=3D0 causing CPU0 to be erroneously set to be dying, causing the scheduler to get mightily confused and throw its toys out of the pram. However the cpu number is actually available directly, so simply remove the 'cpu' member and avoid the problem in the first place. Fixes: 2ea46c6fc945 ("cpumask/hotplug: Fix cpu_dying() state tracking") Signed-off-by: Steven Price --- kernel/cpu.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/kernel/cpu.c b/kernel/cpu.c index 407a2568f35e..5601216eb51b 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -70,7 +70,6 @@ struct cpuhp_cpu_state { bool rollback; bool single; bool bringup; - int cpu; struct hlist_node *node; struct hlist_node *last; enum cpuhp_state cb_state; @@ -474,7 +473,7 @@ static inline bool cpu_smt_allowed(unsigned int cpu) { = return true; } #endif =20 static inline enum cpuhp_state -cpuhp_set_state(struct cpuhp_cpu_state *st, enum cpuhp_state target) +cpuhp_set_state(int cpu, struct cpuhp_cpu_state *st, enum cpuhp_state targ= et) { enum cpuhp_state prev_state =3D st->state; bool bringup =3D st->state < target; @@ -485,14 +484,15 @@ cpuhp_set_state(struct cpuhp_cpu_state *st, enum cpuh= p_state target) st->target =3D target; st->single =3D false; st->bringup =3D bringup; - if (cpu_dying(st->cpu) !=3D !bringup) - set_cpu_dying(st->cpu, !bringup); + if (cpu_dying(cpu) !=3D !bringup) + set_cpu_dying(cpu, !bringup); =20 return prev_state; } =20 static inline void -cpuhp_reset_state(struct cpuhp_cpu_state *st, enum cpuhp_state prev_state) +cpuhp_reset_state(int cpu, struct cpuhp_cpu_state *st, + enum cpuhp_state prev_state) { bool bringup =3D !st->bringup; =20 @@ -519,8 +519,8 @@ cpuhp_reset_state(struct cpuhp_cpu_state *st, enum cpuh= p_state prev_state) } =20 st->bringup =3D bringup; - if (cpu_dying(st->cpu) !=3D !bringup) - set_cpu_dying(st->cpu, !bringup); + if (cpu_dying(cpu) !=3D !bringup) + set_cpu_dying(cpu, !bringup); } =20 /* Regular hotplug invocation of the AP hotplug thread */ @@ -540,15 +540,16 @@ static void __cpuhp_kick_ap(struct cpuhp_cpu_state *s= t) wait_for_ap_thread(st, st->bringup); } =20 -static int cpuhp_kick_ap(struct cpuhp_cpu_state *st, enum cpuhp_state targ= et) +static int cpuhp_kick_ap(int cpu, struct cpuhp_cpu_state *st, + enum cpuhp_state target) { enum cpuhp_state prev_state; int ret; =20 - prev_state =3D cpuhp_set_state(st, target); + prev_state =3D cpuhp_set_state(cpu, st, target); __cpuhp_kick_ap(st); if ((ret =3D st->result)) { - cpuhp_reset_state(st, prev_state); + cpuhp_reset_state(cpu, st, prev_state); __cpuhp_kick_ap(st); } =20 @@ -580,7 +581,7 @@ static int bringup_wait_for_ap(unsigned int cpu) if (st->target <=3D CPUHP_AP_ONLINE_IDLE) return 0; =20 - return cpuhp_kick_ap(st, st->target); + return cpuhp_kick_ap(cpu, st, st->target); } =20 static int bringup_cpu(unsigned int cpu) @@ -703,7 +704,7 @@ static int cpuhp_up_callbacks(unsigned int cpu, struct = cpuhp_cpu_state *st, ret, cpu, cpuhp_get_step(st->state)->name, st->state); =20 - cpuhp_reset_state(st, prev_state); + cpuhp_reset_state(cpu, st, prev_state); if (can_rollback_cpu(st)) WARN_ON(cpuhp_invoke_callback_range(false, cpu, st, prev_state)); @@ -720,7 +721,6 @@ static void cpuhp_create(unsigned int cpu) =20 init_completion(&st->done_up); init_completion(&st->done_down); - st->cpu =3D cpu; } =20 static int cpuhp_should_run(unsigned int cpu) @@ -874,7 +874,7 @@ static int cpuhp_kick_ap_work(unsigned int cpu) cpuhp_lock_release(true); =20 trace_cpuhp_enter(cpu, st->target, prev_state, cpuhp_kick_ap_work); - ret =3D cpuhp_kick_ap(st, st->target); + ret =3D cpuhp_kick_ap(cpu, st, st->target); trace_cpuhp_exit(cpu, st->state, prev_state, ret); =20 return ret; @@ -1106,7 +1106,7 @@ static int cpuhp_down_callbacks(unsigned int cpu, str= uct cpuhp_cpu_state *st, ret, cpu, cpuhp_get_step(st->state)->name, st->state); =20 - cpuhp_reset_state(st, prev_state); + cpuhp_reset_state(cpu, st, prev_state); =20 if (st->state < prev_state) WARN_ON(cpuhp_invoke_callback_range(true, cpu, st, @@ -1133,7 +1133,7 @@ static int __ref _cpu_down(unsigned int cpu, int task= s_frozen, =20 cpuhp_tasks_frozen =3D tasks_frozen; =20 - prev_state =3D cpuhp_set_state(st, target); + prev_state =3D cpuhp_set_state(cpu, st, target); /* * If the current CPU state is in the range of the AP hotplug thread, * then we need to kick the thread. @@ -1164,7 +1164,7 @@ static int __ref _cpu_down(unsigned int cpu, int task= s_frozen, ret =3D cpuhp_down_callbacks(cpu, st, target); if (ret && st->state < prev_state) { if (st->state =3D=3D CPUHP_TEARDOWN_CPU) { - cpuhp_reset_state(st, prev_state); + cpuhp_reset_state(cpu, st, prev_state); __cpuhp_kick_ap(st); } else { WARN(1, "DEAD callback error for CPU%d", cpu); @@ -1351,7 +1351,7 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen= , enum cpuhp_state target) =20 cpuhp_tasks_frozen =3D tasks_frozen; =20 - cpuhp_set_state(st, target); + cpuhp_set_state(cpu, st, target); /* * If the current CPU state is in the range of the AP hotplug thread, * then we need to kick the thread once more. --=20 2.25.1 From nobody Thu May 14 10:27:16 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B28D7C433FE for ; Mon, 11 Apr 2022 15:23:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347869AbiDKPZP (ORCPT ); Mon, 11 Apr 2022 11:25:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46060 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347841AbiDKPZB (ORCPT ); Mon, 11 Apr 2022 11:25:01 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 37F7F3B57F for ; Mon, 11 Apr 2022 08:22:47 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id EEBEB169E; Mon, 11 Apr 2022 08:22:46 -0700 (PDT) Received: from e122027.arm.com (unknown [10.57.40.227]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 466053F73B; Mon, 11 Apr 2022 08:22:45 -0700 (PDT) From: Steven Price To: Thomas Gleixner , Vincent Donnefort , Peter Zijlstra Cc: Steven Price , linux-kernel@vger.kernel.org, Baokun Li , Dongli Zhang , Randy Dunlap , Valentin Schneider , Yuan ZhaoXiong , YueHaibing , Dietmar Eggemann Subject: [PATCH v3 2/2] cpu/hotplug: Initialise all cpuhp_cpu_state structs earlier Date: Mon, 11 Apr 2022 16:22:33 +0100 Message-Id: <20220411152233.474129-3-steven.price@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220411152233.474129-1-steven.price@arm.com> References: <20220411152233.474129-1-steven.price@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Rather than waiting until a CPU is first brought online, do the initialisation of the cpuhp_cpu_state structure for each CPU during the __init phase. This saves a (small) amount of non-__init memory and avoids potential confusion about when the cpuhp_cpu_state struct is valid. Suggested-by: Thomas Gleixner Signed-off-by: Steven Price --- kernel/cpu.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/kernel/cpu.c b/kernel/cpu.c index 5601216eb51b..65903cb10a55 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -715,14 +715,6 @@ static int cpuhp_up_callbacks(unsigned int cpu, struct= cpuhp_cpu_state *st, /* * The cpu hotplug threads manage the bringup and teardown of the cpus */ -static void cpuhp_create(unsigned int cpu) -{ - struct cpuhp_cpu_state *st =3D per_cpu_ptr(&cpuhp_state, cpu); - - init_completion(&st->done_up); - init_completion(&st->done_down); -} - static int cpuhp_should_run(unsigned int cpu) { struct cpuhp_cpu_state *st =3D this_cpu_ptr(&cpuhp_state); @@ -882,15 +874,27 @@ static int cpuhp_kick_ap_work(unsigned int cpu) =20 static struct smp_hotplug_thread cpuhp_threads =3D { .store =3D &cpuhp_state.thread, - .create =3D &cpuhp_create, .thread_should_run =3D cpuhp_should_run, .thread_fn =3D cpuhp_thread_fun, .thread_comm =3D "cpuhp/%u", .selfparking =3D true, }; =20 +static __init void cpuhp_init_state(void) +{ + struct cpuhp_cpu_state *st; + int cpu; + + for_each_possible_cpu(cpu) { + st =3D per_cpu_ptr(&cpuhp_state, cpu); + init_completion(&st->done_up); + init_completion(&st->done_down); + } +} + void __init cpuhp_threads_init(void) { + cpuhp_init_state(); BUG_ON(smpboot_register_percpu_thread(&cpuhp_threads)); kthread_unpark(this_cpu_read(cpuhp_state.thread)); } --=20 2.25.1