[PATCH v3 1/4] kernel: param: initialize module_kset on-demand

Shashank Balaji shashank.mahadasyam at sony.com
Wed Apr 22 02:49:03 PDT 2026


module_kset is initialized in param_sysfs_init(), a subsys_initcall. A number
of platform drivers register themselves prior to subsys_initcalls. With an
upcoming patch ("driver core: platform: set mod_name in driver registration")
that sets their mod_name in struct device_driver, lookup_or_create_module()
will be called for those drivers, which calls kset_find_object(module_kset, mod_name).
This fails because module_kset isn't alive yet.

Fix this by initializing module_kset on-demand in lookup_or_create_module().
Retain the param_sysfs_init() subsys_initcall to ensure that module_kset is
live after subsys_initcalls (assuming no OOM) for any users who may need it,
on the off chance that it wasn't init'd on-demand because of no
pre-subsys_initcall drivers.

This on-demand path can trigger before subsys_initcall. kset_create_and_add()
be should safe in those contexts because the allocator is up and running by then,
no userspace to start uevent helper or listen to a uevent socket.

Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Co-developed-by: Rahul Bukte <rahul.bukte at sony.com>
Signed-off-by: Rahul Bukte <rahul.bukte at sony.com>
Signed-off-by: Shashank Balaji <shashank.mahadasyam at sony.com>

---

Patch 3 depends on this patch.
---
 kernel/params.c | 41 +++++++++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/kernel/params.c b/kernel/params.c
index 74d620bc2521..f25d6fda159c 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -745,6 +745,26 @@ void module_param_sysfs_remove(struct module *mod)
 }
 #endif
 
+static int uevent_filter(const struct kobject *kobj)
+{
+	const struct kobj_type *ktype = get_ktype(kobj);
+
+	if (ktype == &module_ktype)
+		return 1;
+	return 0;
+}
+
+static const struct kset_uevent_ops module_uevent_ops = {
+	.filter = uevent_filter,
+};
+
+static struct kset *__init_or_module ensure_module_kset(void)
+{
+	if (!module_kset)
+		module_kset = kset_create_and_add("module", &module_uevent_ops, NULL);
+	return module_kset;
+}
+
 struct module_kobject * __init_or_module
 lookup_or_create_module_kobject(const char *name)
 {
@@ -752,6 +772,9 @@ lookup_or_create_module_kobject(const char *name)
 	struct kobject *kobj;
 	int err;
 
+	if (!ensure_module_kset())
+		return NULL;
+
 	kobj = kset_find_obj(module_kset, name);
 	if (kobj)
 		return to_module_kobject(kobj);
@@ -911,19 +934,6 @@ static const struct sysfs_ops module_sysfs_ops = {
 	.store = module_attr_store,
 };
 
-static int uevent_filter(const struct kobject *kobj)
-{
-	const struct kobj_type *ktype = get_ktype(kobj);
-
-	if (ktype == &module_ktype)
-		return 1;
-	return 0;
-}
-
-static const struct kset_uevent_ops module_uevent_ops = {
-	.filter = uevent_filter,
-};
-
 struct kset *module_kset;
 
 static void module_kobj_release(struct kobject *kobj)
@@ -940,7 +950,7 @@ const struct kobj_type module_ktype = {
 };
 
 /*
- * param_sysfs_init - create "module" kset
+ * param_sysfs_init - create module_kset if not already done
  *
  * This must be done before the initramfs is unpacked and
  * request_module() thus becomes possible, because otherwise the
@@ -948,8 +958,7 @@ const struct kobj_type module_ktype = {
  */
 static int __init param_sysfs_init(void)
 {
-	module_kset = kset_create_and_add("module", &module_uevent_ops, NULL);
-	if (!module_kset) {
+	if (!ensure_module_kset()) {
 		printk(KERN_WARNING "%s (%d): error creating kset\n",
 			__FILE__, __LINE__);
 		return -ENOMEM;

-- 
2.43.0




More information about the linux-arm-kernel mailing list