Software nodes depend on kernel_kobj which is initialized pretty late
into the boot process - as a core_initcall(). Ahead of moving the
software node initialization to driver_init() we must first make
kernel_kobj available before it.
Make ksysfs_init() visible in the kobject.h header and call it in
do_basic_setup() right before driver_init().
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
include/linux/kobject.h | 2 ++
init/main.c | 1 +
kernel/ksysfs.c | 8 +++-----
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index c8219505a79f98bc370e52997efc8af51833cfda..71b9086621c35b7e4ef99b9d3b6707db23faf58c 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -219,4 +219,6 @@ int kobject_synth_uevent(struct kobject *kobj, const char *buf, size_t count);
__printf(2, 3)
int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...);
+void ksysfs_init(void);
+
#endif /* _KOBJECT_H_ */
diff --git a/init/main.c b/init/main.c
index 8b7633b7ab720b9c13a231d64291d35d3852602c..1a9046b563e469057cca72ce39a0701c9c4d49e1 100644
--- a/init/main.c
+++ b/init/main.c
@@ -1482,6 +1482,7 @@ static void __init do_initcalls(void)
static void __init do_basic_setup(void)
{
cpuset_init_smp();
+ ksysfs_init();
driver_init();
init_irq_proc();
do_ctors();
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index a9e6354d9e2579317d3b1bcb54223432d3ce0950..ac546562a6a1202a752de2d36719c6a193520a79 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -213,7 +213,7 @@ static const struct attribute_group kernel_attr_group = {
.attrs = kernel_attrs,
};
-static int __init ksysfs_init(void)
+void __init ksysfs_init(void)
{
int error;
@@ -234,14 +234,12 @@ static int __init ksysfs_init(void)
goto group_exit;
}
- return 0;
+ return;
group_exit:
sysfs_remove_group(kernel_kobj, &kernel_attr_group);
kset_exit:
kobject_put(kernel_kobj);
exit:
- return error;
+ pr_err("failed to initialize the kernel kobject: %d\n", error);
}
-
-core_initcall(ksysfs_init);
--
2.47.3
On Mon Mar 30, 2026 at 2:40 PM CEST, Bartosz Golaszewski wrote: > diff --git a/include/linux/kobject.h b/include/linux/kobject.h > index c8219505a79f98bc370e52997efc8af51833cfda..71b9086621c35b7e4ef99b9d3b6707db23faf58c 100644 > --- a/include/linux/kobject.h > +++ b/include/linux/kobject.h > @@ -219,4 +219,6 @@ int kobject_synth_uevent(struct kobject *kobj, const char *buf, size_t count); > __printf(2, 3) > int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...); > > +void ksysfs_init(void); NIT: I'm aware there's also all the core kobjects in include/linux/kobject.h, but maybe a separate header would be a better fit.
On Mon, Mar 30, 2026 at 3:47 PM Danilo Krummrich <dakr@kernel.org> wrote: > > On Mon Mar 30, 2026 at 2:40 PM CEST, Bartosz Golaszewski wrote: > > diff --git a/include/linux/kobject.h b/include/linux/kobject.h > > index c8219505a79f98bc370e52997efc8af51833cfda..71b9086621c35b7e4ef99b9d3b6707db23faf58c 100644 > > --- a/include/linux/kobject.h > > +++ b/include/linux/kobject.h > > @@ -219,4 +219,6 @@ int kobject_synth_uevent(struct kobject *kobj, const char *buf, size_t count); > > __printf(2, 3) > > int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...); > > > > +void ksysfs_init(void); > > NIT: I'm aware there's also all the core kobjects in include/linux/kobject.h, > but maybe a separate header would be a better fit. Do you mean moving all the top-level kobject declarations (kernel_kobj, firmware_kobj, etc.) out of kobject.h into this new header (ksysfs.h?) along with their init functions? Bart
On Mon Mar 30, 2026 at 4:19 PM CEST, Bartosz Golaszewski wrote: > On Mon, Mar 30, 2026 at 3:47 PM Danilo Krummrich <dakr@kernel.org> wrote: >> >> On Mon Mar 30, 2026 at 2:40 PM CEST, Bartosz Golaszewski wrote: >> > diff --git a/include/linux/kobject.h b/include/linux/kobject.h >> > index c8219505a79f98bc370e52997efc8af51833cfda..71b9086621c35b7e4ef99b9d3b6707db23faf58c 100644 >> > --- a/include/linux/kobject.h >> > +++ b/include/linux/kobject.h >> > @@ -219,4 +219,6 @@ int kobject_synth_uevent(struct kobject *kobj, const char *buf, size_t count); >> > __printf(2, 3) >> > int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...); >> > >> > +void ksysfs_init(void); >> >> NIT: I'm aware there's also all the core kobjects in include/linux/kobject.h, >> but maybe a separate header would be a better fit. > > Do you mean moving all the top-level kobject declarations > (kernel_kobj, firmware_kobj, etc.) out of kobject.h into this new > header (ksysfs.h?) along with their init functions? I think the top-level kobjects are fine; it's just ksysfs_init() that somehow feels odd to me being placed in kobject.h. The top-level kobject do make sense as they are the base for a lot of other kobjects being created by other core code. Whereas ksysfs_init() is a ksysfs specific thing that is only ever used by init/main.c, i.e. other than the top-level kobjects, it has nothing to do with the kobject API itself.
© 2016 - 2026 Red Hat, Inc.