driver core: bus: move dev_root out of struct bus_type
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Mar 2023 18:29:04 +0000 (19:29 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 Mar 2023 12:20:36 +0000 (13:20 +0100)
Now that all accesses of dev_root is through the bus_get_dev_root()
call, move the pointer out of struct bus_type and into the private
dynamic structure, subsys_private.

With this change, there is no modifiable portions of struct bus_type so
it can be marked as a constant structure and moved to read-only memory.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Link: https://lore.kernel.org/r/20230313182918.1312597-22-gregkh@linuxfoundation.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/base/base.h
drivers/base/bus.c
include/linux/device/bus.h

index b055eba..f1034e2 100644 (file)
@@ -27,6 +27,7 @@
  *                 on this bus.
  * @bus - pointer back to the struct bus_type that this structure is associated
  *        with.
+ * @dev_root: Default device to use as the parent.
  *
  * @glue_dirs - "glue" directory to put in-between the parent device to
  *              avoid namespace conflicts
@@ -49,6 +50,7 @@ struct subsys_private {
        struct blocking_notifier_head bus_notifier;
        unsigned int drivers_autoprobe:1;
        struct bus_type *bus;
+       struct device *dev_root;
 
        struct kset glue_dirs;
        struct class *class;
index dd4b82d..91a6b6b 100644 (file)
@@ -935,8 +935,8 @@ void bus_unregister(const struct bus_type *bus)
                return;
 
        pr_debug("bus: '%s': unregistering\n", bus->name);
-       if (bus->dev_root)
-               device_unregister(bus->dev_root);
+       if (sp->dev_root)
+               device_unregister(sp->dev_root);
 
        bus_kobj = &sp->subsys.kobj;
        sysfs_remove_groups(bus_kobj, bus->bus_groups);
@@ -1198,6 +1198,7 @@ static int subsys_register(struct bus_type *subsys,
                           const struct attribute_group **groups,
                           struct kobject *parent_of_root)
 {
+       struct subsys_private *sp;
        struct device *dev;
        int err;
 
@@ -1205,6 +1206,12 @@ static int subsys_register(struct bus_type *subsys,
        if (err < 0)
                return err;
 
+       sp = bus_to_subsys(subsys);
+       if (!sp) {
+               err = -EINVAL;
+               goto err_sp;
+       }
+
        dev = kzalloc(sizeof(struct device), GFP_KERNEL);
        if (!dev) {
                err = -ENOMEM;
@@ -1223,7 +1230,8 @@ static int subsys_register(struct bus_type *subsys,
        if (err < 0)
                goto err_dev_reg;
 
-       subsys->dev_root = dev;
+       sp->dev_root = dev;
+       subsys_put(sp);
        return 0;
 
 err_dev_reg:
@@ -1232,6 +1240,8 @@ err_dev_reg:
 err_name:
        kfree(dev);
 err_dev:
+       subsys_put(sp);
+err_sp:
        bus_unregister(subsys);
        return err;
 }
@@ -1349,9 +1359,15 @@ bool bus_is_registered(const struct bus_type *bus)
  */
 struct device *bus_get_dev_root(const struct bus_type *bus)
 {
-       if (bus)
-               return get_device(bus->dev_root);
-       return NULL;
+       struct subsys_private *sp = bus_to_subsys(bus);
+       struct device *dev_root;
+
+       if (!sp)
+               return NULL;
+
+       dev_root = get_device(sp->dev_root);
+       subsys_put(sp);
+       return dev_root;
 }
 EXPORT_SYMBOL_GPL(bus_get_dev_root);
 
index 6ce32ef..c258e87 100644 (file)
@@ -26,7 +26,6 @@ struct fwnode_handle;
  *
  * @name:      The name of the bus.
  * @dev_name:  Used for subsystems to enumerate devices like ("foo%u", dev->id).
- * @dev_root:  Default device to use as the parent.
  * @bus_groups:        Default attributes of the bus.
  * @dev_groups:        Default attributes of the devices on the bus.
  * @drv_groups: Default attributes of the device drivers on the bus.
@@ -82,7 +81,6 @@ struct fwnode_handle;
 struct bus_type {
        const char              *name;
        const char              *dev_name;
-       struct device           *dev_root;
        const struct attribute_group **bus_groups;
        const struct attribute_group **dev_groups;
        const struct attribute_group **drv_groups;