summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-03-13 19:29:04 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-03-23 13:20:36 +0100
commit9cc61e5fbd619eea0401f519e7bac72fe3d4d1e8 (patch)
treece3743bdf6965397a8b5129653edc52c1b922cdb
parentbf6479dbe743ca343fa122aaffbe9dcb1de80a51 (diff)
driver core: bus: move dev_root out of struct bus_type
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>
-rw-r--r--drivers/base/base.h2
-rw-r--r--drivers/base/bus.c28
-rw-r--r--include/linux/device/bus.h2
3 files changed, 24 insertions, 8 deletions
diff --git a/drivers/base/base.h b/drivers/base/base.h
index b055eba1ec30..f1034e27e651 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -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;
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index dd4b82d7510f..91a6b6b1fc49 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -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);
diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h
index 6ce32ef4b8fd..c258e8770285 100644
--- a/include/linux/device/bus.h
+++ b/include/linux/device/bus.h
@@ -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;