* [PATCH] cpu/hotplug: Fix NULL kobject warning in cpuhp_smt_enable()
@ 2026-04-17 7:55 Jinjie Ruan
2026-04-18 11:55 ` Catalin Marinas
0 siblings, 1 reply; 3+ messages in thread
From: Jinjie Ruan @ 2026-04-17 7:55 UTC (permalink / raw)
To: tglx, peterz, sudeep.holla, yangyicong, dietmar.eggemann,
Jonathan.Cameron, catalin.marinas, linux-kernel
Cc: ruanjinjie
When booting with `maxcpus` greater than the number of present CPUs (e.g.,
QEMU -smp cpus=4,maxcpus=8), some CPUs are marked as 'present' but have not
yet been registered via register_cpu(). Consequently, the per-cpu device
objects for these CPUs are not yet initialized.
In cpuhp_smt_enable(), the code iterates over all present CPUs. Calling
_cpu_up() for these unregistered CPUs eventually leads to
sysfs_create_group() being called with a NULL kobject (or a kobject
without a directory), triggering the following warning in
fs/sysfs/group.c:
if (WARN_ON(!kobj || (!update && !kobj->sd)))
return -EINVAL;
Fix this by adding a check for get_cpu_device(cpu). This ensures that
SMT is only enabled for CPUs that have successfully completed their
base device registration in sysfs.
How to reproduce:
1. echo off > /sys/devices/system/cpu/smt/control
psci: CPU1 killed (polled 0 ms)
psci: CPU3 killed (polled 0 ms)
2. echo 2 > /sys/devices/system/cpu/smt/control
Detected PIPT I-cache on CPU1
GICv3: CPU1: found redistributor 1 region 0:0x00000000080c0000
CPU1: Booted secondary processor 0x0000000001 [0x410fd082]
Detected PIPT I-cache on CPU3
GICv3: CPU3: found redistributor 3 region 0:0x0000000008100000
CPU3: Booted secondary processor 0x0000000003 [0x410fd082]
------------[ cut here ]------------
WARNING: fs/sysfs/group.c:137 at internal_create_group+0x41c/0x4bc, CPU#2: sh/181
Modules linked in:
CPU: 2 UID: 0 PID: 181 Comm: sh Not tainted 7.0.0-rc1-00010-g8d13386c7624 #142 PREEMPT
Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015
pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : internal_create_group+0x41c/0x4bc
lr : sysfs_create_group+0x18/0x24
sp : ffff80008078ba40
x29: ffff80008078ba40 x28: ffff296c980ad000 x27: ffff00007fb94128
x26: 0000000000000054 x25: ffffd693e845f3f0 x24: 0000000000000001
x23: 0000000000000001 x22: 0000000000000004 x21: 0000000000000000
x20: ffffd693e845fc10 x19: 0000000000000004 x18: 00000000ffffffff
x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
x14: 0000000000000358 x13: 0000000000000007 x12: 0000000000000350
x11: 0000000000000008 x10: 0000000000000407 x9 : 0000000000000400
x8 : ffff00007fbf3b60 x7 : 0000000000000000 x6 : ffffd693e845f3f0
x5 : ffff00007fb94128 x4 : 0000000000000000 x3 : ffff000000f4eac0
x2 : ffffd693e7095a08 x1 : 0000000000000000 x0 : 0000000000000000
Call trace:
internal_create_group+0x41c/0x4bc (P)
sysfs_create_group+0x18/0x24
topology_add_dev+0x1c/0x28
cpuhp_invoke_callback+0x104/0x20c
__cpuhp_invoke_callback_range+0x94/0x11c
_cpu_up+0x200/0x37c
cpuhp_smt_enable+0xbc/0x114
control_store+0xe8/0x1d4
dev_attr_store+0x18/0x2c
sysfs_kf_write+0x7c/0x94
kernfs_fop_write_iter+0x128/0x1b8
vfs_write+0x2b0/0x354
ksys_write+0x68/0xfc
__arm64_sys_write+0x1c/0x28
invoke_syscall+0x48/0x10c
el0_svc_common.constprop.0+0x40/0xe8
do_el0_svc+0x20/0x2c
el0_svc+0x34/0x124
el0t_64_sync_handler+0xa0/0xe4
el0t_64_sync+0x198/0x19c
---[ end trace 0000000000000000 ]---
Cc: stable@vger.kernel.org
Fixes: eed4583bcf9a6 ("arm64: Kconfig: Enable HOTPLUG_SMT")
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
kernel/cpu.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/kernel/cpu.c b/kernel/cpu.c
index bc4f7a9ba64e..df725d92ad4f 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -2706,6 +2706,13 @@ int cpuhp_smt_enable(void)
cpu_maps_update_begin();
cpu_smt_control = CPU_SMT_ENABLED;
for_each_present_cpu(cpu) {
+ /*
+ * Skip CPUs that have not been registered in sysfs yet.
+ * This avoids triggering NULL kobject warnings for maxcpus.
+ */
+ if (!get_cpu_device(cpu))
+ continue;
+
/* Skip online CPUs and CPUs on offline nodes */
if (cpu_online(cpu) || !node_online(cpu_to_node(cpu)))
continue;
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] cpu/hotplug: Fix NULL kobject warning in cpuhp_smt_enable()
2026-04-17 7:55 [PATCH] cpu/hotplug: Fix NULL kobject warning in cpuhp_smt_enable() Jinjie Ruan
@ 2026-04-18 11:55 ` Catalin Marinas
2026-04-18 15:05 ` Catalin Marinas
0 siblings, 1 reply; 3+ messages in thread
From: Catalin Marinas @ 2026-04-18 11:55 UTC (permalink / raw)
To: Jinjie Ruan
Cc: tglx, peterz, sudeep.holla, yangyicong, dietmar.eggemann,
Jonathan.Cameron, linux-kernel, James Morse, linux-arm-kernel
+ James Morse, linux-arm-kernel
On Fri, Apr 17, 2026 at 03:55:34PM +0800, Jinjie Ruan wrote:
> When booting with `maxcpus` greater than the number of present CPUs (e.g.,
> QEMU -smp cpus=4,maxcpus=8), some CPUs are marked as 'present' but have not
> yet been registered via register_cpu(). Consequently, the per-cpu device
> objects for these CPUs are not yet initialized.
>
> In cpuhp_smt_enable(), the code iterates over all present CPUs. Calling
> _cpu_up() for these unregistered CPUs eventually leads to
> sysfs_create_group() being called with a NULL kobject (or a kobject
> without a directory), triggering the following warning in
> fs/sysfs/group.c:
>
> if (WARN_ON(!kobj || (!update && !kobj->sd)))
> return -EINVAL;
>
> Fix this by adding a check for get_cpu_device(cpu). This ensures that
> SMT is only enabled for CPUs that have successfully completed their
> base device registration in sysfs.
>
> How to reproduce:
>
> 1. echo off > /sys/devices/system/cpu/smt/control
> psci: CPU1 killed (polled 0 ms)
> psci: CPU3 killed (polled 0 ms)
>
> 2. echo 2 > /sys/devices/system/cpu/smt/control
>
> Detected PIPT I-cache on CPU1
> GICv3: CPU1: found redistributor 1 region 0:0x00000000080c0000
> CPU1: Booted secondary processor 0x0000000001 [0x410fd082]
> Detected PIPT I-cache on CPU3
> GICv3: CPU3: found redistributor 3 region 0:0x0000000008100000
> CPU3: Booted secondary processor 0x0000000003 [0x410fd082]
> ------------[ cut here ]------------
> WARNING: fs/sysfs/group.c:137 at internal_create_group+0x41c/0x4bc, CPU#2: sh/181
> Modules linked in:
> CPU: 2 UID: 0 PID: 181 Comm: sh Not tainted 7.0.0-rc1-00010-g8d13386c7624 #142 PREEMPT
> Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015
> pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : internal_create_group+0x41c/0x4bc
> lr : sysfs_create_group+0x18/0x24
> sp : ffff80008078ba40
> x29: ffff80008078ba40 x28: ffff296c980ad000 x27: ffff00007fb94128
> x26: 0000000000000054 x25: ffffd693e845f3f0 x24: 0000000000000001
> x23: 0000000000000001 x22: 0000000000000004 x21: 0000000000000000
> x20: ffffd693e845fc10 x19: 0000000000000004 x18: 00000000ffffffff
> x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
> x14: 0000000000000358 x13: 0000000000000007 x12: 0000000000000350
> x11: 0000000000000008 x10: 0000000000000407 x9 : 0000000000000400
> x8 : ffff00007fbf3b60 x7 : 0000000000000000 x6 : ffffd693e845f3f0
> x5 : ffff00007fb94128 x4 : 0000000000000000 x3 : ffff000000f4eac0
> x2 : ffffd693e7095a08 x1 : 0000000000000000 x0 : 0000000000000000
> Call trace:
> internal_create_group+0x41c/0x4bc (P)
> sysfs_create_group+0x18/0x24
> topology_add_dev+0x1c/0x28
> cpuhp_invoke_callback+0x104/0x20c
> __cpuhp_invoke_callback_range+0x94/0x11c
> _cpu_up+0x200/0x37c
> cpuhp_smt_enable+0xbc/0x114
> control_store+0xe8/0x1d4
> dev_attr_store+0x18/0x2c
> sysfs_kf_write+0x7c/0x94
> kernfs_fop_write_iter+0x128/0x1b8
> vfs_write+0x2b0/0x354
> ksys_write+0x68/0xfc
> __arm64_sys_write+0x1c/0x28
> invoke_syscall+0x48/0x10c
> el0_svc_common.constprop.0+0x40/0xe8
> do_el0_svc+0x20/0x2c
> el0_svc+0x34/0x124
> el0t_64_sync_handler+0xa0/0xe4
> el0t_64_sync+0x198/0x19c
> ---[ end trace 0000000000000000 ]---
>
> Cc: stable@vger.kernel.org
> Fixes: eed4583bcf9a6 ("arm64: Kconfig: Enable HOTPLUG_SMT")
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
> ---
> kernel/cpu.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/kernel/cpu.c b/kernel/cpu.c
> index bc4f7a9ba64e..df725d92ad4f 100644
> --- a/kernel/cpu.c
> +++ b/kernel/cpu.c
> @@ -2706,6 +2706,13 @@ int cpuhp_smt_enable(void)
> cpu_maps_update_begin();
> cpu_smt_control = CPU_SMT_ENABLED;
> for_each_present_cpu(cpu) {
> + /*
> + * Skip CPUs that have not been registered in sysfs yet.
> + * This avoids triggering NULL kobject warnings for maxcpus.
> + */
> + if (!get_cpu_device(cpu))
> + continue;
> +
> /* Skip online CPUs and CPUs on offline nodes */
> if (cpu_online(cpu) || !node_online(cpu_to_node(cpu)))
> continue;
I spent some time trying to understand how we can get into this
situation. It seems to be an ACPI only thing.
Since commit eba4675008a6 ("arm64: arch_register_cpu() variant to check
if an ACPI handle is now available.") as part of the virtual CPU hotplug
series, arch_register_cpu() can defer registering the CPU devices. IIUC
this is done later via acpi_processor_hotadd_init(). smp_prepare_cpus(),
however, still marks them as present.
cpuhp_smt_enable(), if triggered later, walks the present cpus and
attempts _cpu_up(). cpuhp_up_callbacks() will call topology_add_dev()
(registered as a CPUHP_TOPOLOGY_PREPARE callback) and warn since
get_cpu_device() returns NULL. I think this can't happen during early
_cpu_up() calls since smp_init() is called before the topology callback
has been registered (slightly later during do_basic_setup()).
I'm not sure what the best fix should be. If we go with something along
the lines of the above, I wonder whether we should instead return an
error in the topology_add_dev() callback if get_cpu_device() returns
NULL. It feels a bit wrong to add a check for sysfs in
cpuhp_smt_enable() just because of some callbacks attempted by
_cpu_up(). There's precedent in cpu_capacity_sysctl_add() returning
-ENOENT. However, this messes up the smt control enabling since
cpuhp_smt_enable() will bail out early and return an error.
Another option would have been to avoid marking such CPUs present but I
think this will break other things. Yet another option is to register
all CPU devices even if they never come up (like maxcpus greater than
actual CPUs).
Opinions? It might be an arm64+ACPI-only thing.
--
Catalin
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] cpu/hotplug: Fix NULL kobject warning in cpuhp_smt_enable()
2026-04-18 11:55 ` Catalin Marinas
@ 2026-04-18 15:05 ` Catalin Marinas
0 siblings, 0 replies; 3+ messages in thread
From: Catalin Marinas @ 2026-04-18 15:05 UTC (permalink / raw)
To: Jinjie Ruan
Cc: tglx, peterz, sudeep.holla, yangyicong, dietmar.eggemann,
Jonathan.Cameron, linux-kernel, James Morse, linux-arm-kernel
On Sat, Apr 18, 2026 at 12:55:22PM +0100, Catalin Marinas wrote:
> On Fri, Apr 17, 2026 at 03:55:34PM +0800, Jinjie Ruan wrote:
> > When booting with `maxcpus` greater than the number of present CPUs (e.g.,
> > QEMU -smp cpus=4,maxcpus=8), some CPUs are marked as 'present' but have not
> > yet been registered via register_cpu(). Consequently, the per-cpu device
> > objects for these CPUs are not yet initialized.
[...]
> Another option would have been to avoid marking such CPUs present but I
> think this will break other things. Yet another option is to register
> all CPU devices even if they never come up (like maxcpus greater than
> actual CPUs).
Something like below, untested (and I don't claim I properly understand
this code; just lots of tokens used trying to make sense of it ;))
------------------------8<-------------------------
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index a9d884fd1d00..4c0a5ed906ea 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -448,12 +448,14 @@ int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 apci_id,
return *pcpu;
}
+ set_cpu_present(*pcpu, true);
return 0;
}
EXPORT_SYMBOL(acpi_map_cpu);
int acpi_unmap_cpu(int cpu)
{
+ set_cpu_present(cpu, false);
return 0;
}
EXPORT_SYMBOL(acpi_unmap_cpu);
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 1aa324104afb..751a74d997e1 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -510,8 +510,10 @@ int arch_register_cpu(int cpu)
struct cpu *c = &per_cpu(cpu_devices, cpu);
if (!acpi_disabled && !acpi_handle &&
- IS_ENABLED(CONFIG_ACPI_HOTPLUG_CPU))
+ IS_ENABLED(CONFIG_ACPI_HOTPLUG_CPU)) {
+ set_cpu_present(cpu, false);
return -EPROBE_DEFER;
+ }
#ifdef CONFIG_ACPI_HOTPLUG_CPU
/* For now block anything that looks like physical CPU Hotplug */
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-04-18 15:05 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-17 7:55 [PATCH] cpu/hotplug: Fix NULL kobject warning in cpuhp_smt_enable() Jinjie Ruan
2026-04-18 11:55 ` Catalin Marinas
2026-04-18 15:05 ` Catalin Marinas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox