All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type
@ 2023-02-08 11:13 Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 01/21] driver core: add local subsys_get and subsys_put functions Greg Kroah-Hartman
                   ` (20 more replies)
  0 siblings, 21 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

In the quest to make all struct bus_type constant in the kernel,
allowing them to move into read-only memory, this patch series goes
through the steps in getting rid of the "private" pointer in struct
bus_type.  It does so primarily by relying on the already-present list
of subsystems in the driver core and looking up the struct bus_type from
that list when needed, or looking up the private structure from the bus
pointer, depending on what is needed.

Overall, more lines of code are added, but we now have the additional
safely that the internal subsystem private type is properly reference
counted.  We "got away" with not incrementing reference counts because
we relied on the caller of functions to have a valid reference when
calling into the core.  That's not really the proper way to handle
reference counts, so as part of the conversion, reference counts are now
correctly handled.

There are still some remaining steps to be able to have bus_type be
constant everywhere in the kernel, but this series is a great first step
and is the "hard part" of the work.  The rest involves changing the
callback sysfs file functions and handling the dev_root pointer
properly.  Those changes will be forthcoming after these as they involve
lots more minor driver changes all over the kernel.

This has been build-tested by the 0-day bot for a while, and is being
used by me right now to send this series out, so it "works for me!"

This series is based against my current driver-core-next branch that is
in linux-next.

Greg Kroah-Hartman (21):
  driver core: add local subsys_get and subsys_put functions
  driver core: bus: implement bus_get/put() without the private pointer
  driver core: bus: constantify the bus_find_* functions
  driver core: bus: convert bus_create/remove_file to be constant
  driver core: bus: sysfs function cleanups
  driver core: bus: bus_add/probe/remove_device() cleanups
  driver core: bus: bus_register/unregister() cleanups
  driver core: bus: subsys_interface_register/unregister() cleanups
  driver core: bus: bus_get_kset() cleanup
  driver core: bus: bus_register/unregister_notifier() cleanups
  driver core: bus: bus_add/remove_driver() cleanups
  driver core: bus: bus iterator cleanups
  driver core: bus: clean up bus_sort_breadthfirst()
  driver core: move driver_find() to bus.c
  driver core: bus: clean up driver_find()
  driver core: create bus_is_registered()
  driver core: remove private pointer from struct bus_type
  driver core: bus: constify bus_register/unregister_notifier()
  driver core: bus: constify bus_get_kset()
  driver core: bus: constify some internal functions
  driver core: bus: constify bus_unregister()

 drivers/base/base.h        |  14 ++
 drivers/base/bus.c         | 491 ++++++++++++++++++++++++++-----------
 drivers/base/driver.c      |  29 +--
 include/linux/device/bus.h |  37 ++-
 4 files changed, 375 insertions(+), 196 deletions(-)

-- 
2.39.1


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 01/21] driver core: add local subsys_get and subsys_put functions
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 02/21] driver core: bus: implement bus_get/put() without the private pointer Greg Kroah-Hartman
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

We need to control the reference count of the subsys private structure
instead of directly manipulating the kset reference count of it, so wrap
that logic up in a subsys_get() and subsys_put() function to make it more
obvious as to what is happening.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/base.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index 0e806f641079..9e06c18c7a64 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -57,6 +57,19 @@ struct subsys_private {
 };
 #define to_subsys_private(obj) container_of_const(obj, struct subsys_private, subsys.kobj)
 
+static inline struct subsys_private *subsys_get(struct subsys_private *sp)
+{
+	if (sp)
+		kset_get(&sp->subsys);
+	return sp;
+}
+
+static inline void subsys_put(struct subsys_private *sp)
+{
+	if (sp)
+		kset_put(&sp->subsys);
+}
+
 struct driver_private {
 	struct kobject kobj;
 	struct klist klist_devices;
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 02/21] driver core: bus: implement bus_get/put() without the private pointer
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 01/21] driver core: add local subsys_get and subsys_put functions Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 03/21] driver core: bus: constantify the bus_find_* functions Greg Kroah-Hartman
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

In the quest to make 'struct bus_type' constant and in read-only memory,
we need to stop using the private pointer to the subsys_private
structure.  First step in doing this is to create a helper function that
turns a 'struct bus_type' into 'struct subsys_private' called
bus_to_subsys().

bus_to_subsys() walks the list of registered busses in the system and
finds the matching one based on the pointer to the bus_type itself.  As
this is a short list, and this function is not on any fast path, it
should not be noticable.

Implement bus_get() and bus_put() using this new helper function.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c | 61 ++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 53 insertions(+), 8 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index aa70b3a7d778..d346afa4645c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -24,6 +24,9 @@
 /* /sys/devices/system */
 static struct kset *system_kset;
 
+/* /sys/bus */
+static struct kset *bus_kset;
+
 #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr)
 
 /*
@@ -39,19 +42,63 @@ static struct kset *system_kset;
 static int __must_check bus_rescan_devices_helper(struct device *dev,
 						void *data);
 
+/**
+ * bus_to_subsys - Turn a struct bus_type into a struct subsys_private
+ *
+ * @bus: pointer to the struct bus_type to look up
+ *
+ * The driver core internals needs to work on the subsys_private structure, not
+ * the external struct bus_type pointer.  This function walks the list of
+ * registered busses in the system and finds the matching one and returns the
+ * internal struct subsys_private that relates to that bus.
+ *
+ * Note, the reference count of the return value is INCREMENTED if it is not
+ * NULL.  A call to subsys_put() must be done when finished with the pointer in
+ * order for it to be properly freed.
+ */
+static struct subsys_private *bus_to_subsys(const struct bus_type *bus)
+{
+	struct subsys_private *sp = NULL;
+	struct kobject *kobj;
+
+	if (!bus)
+		return NULL;
+
+	spin_lock(&bus_kset->list_lock);
+
+	if (list_empty(&bus_kset->list))
+		goto done;
+
+	list_for_each_entry(kobj, &bus_kset->list, entry) {
+		struct kset *kset = container_of(kobj, struct kset, kobj);
+
+		sp = container_of_const(kset, struct subsys_private, subsys);
+		if (sp->bus == bus)
+			goto done;
+	}
+	sp = NULL;
+done:
+	sp = subsys_get(sp);
+	spin_unlock(&bus_kset->list_lock);
+	return sp;
+}
+
 static struct bus_type *bus_get(struct bus_type *bus)
 {
-	if (bus) {
-		kset_get(&bus->p->subsys);
+	struct subsys_private *sp = bus_to_subsys(bus);
+
+	if (sp)
 		return bus;
-	}
 	return NULL;
 }
 
-static void bus_put(struct bus_type *bus)
+static void bus_put(const struct bus_type *bus)
 {
-	if (bus)
-		kset_put(&bus->p->subsys);
+	struct subsys_private *sp = bus_to_subsys(bus);
+
+	/* two puts are required as the call to bus_to_subsys incremented it again */
+	subsys_put(sp);
+	subsys_put(sp);
 }
 
 static ssize_t drv_attr_show(struct kobject *kobj, struct attribute *attr,
@@ -177,8 +224,6 @@ static const struct kset_uevent_ops bus_uevent_ops = {
 	.filter = bus_uevent_filter,
 };
 
-static struct kset *bus_kset;
-
 /* Manually detach a device from its associated driver. */
 static ssize_t unbind_store(struct device_driver *drv, const char *buf,
 			    size_t count)
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 03/21] driver core: bus: constantify the bus_find_* functions
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 01/21] driver core: add local subsys_get and subsys_put functions Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 02/21] driver core: bus: implement bus_get/put() without the private pointer Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 04/21] driver core: bus: convert bus_create/remove_file to be constant Greg Kroah-Hartman
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

All of the bus find and iterator functions do not modify the struct
bus_type passed to them, so mark them as constant to enforce this rule.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c         |  6 +++---
 include/linux/device/bus.h | 20 ++++++++++----------
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d346afa4645c..7949302663f9 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -331,7 +331,7 @@ static struct device *next_device(struct klist_iter *i)
  * to retain this data, it should do so, and increment the reference
  * count in the supplied callback.
  */
-int bus_for_each_dev(struct bus_type *bus, struct device *start,
+int bus_for_each_dev(const struct bus_type *bus, struct device *start,
 		     void *data, int (*fn)(struct device *, void *))
 {
 	struct klist_iter i;
@@ -365,7 +365,7 @@ EXPORT_SYMBOL_GPL(bus_for_each_dev);
  * if it does.  If the callback returns non-zero, this function will
  * return to the caller and not iterate over any more devices.
  */
-struct device *bus_find_device(struct bus_type *bus,
+struct device *bus_find_device(const struct bus_type *bus,
 			       struct device *start, const void *data,
 			       int (*match)(struct device *dev, const void *data))
 {
@@ -416,7 +416,7 @@ static struct device_driver *next_driver(struct klist_iter *i)
  * in the callback. It must also be sure to increment the refcount
  * so it doesn't disappear before returning to the caller.
  */
-int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
+int bus_for_each_drv(const struct bus_type *bus, struct device_driver *start,
 		     void *data, int (*fn)(struct device_driver *, void *))
 {
 	struct klist_iter i;
diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h
index e3094db1e9fa..f0c8bf91b07a 100644
--- a/include/linux/device/bus.h
+++ b/include/linux/device/bus.h
@@ -149,9 +149,9 @@ int device_match_acpi_handle(struct device *dev, const void *handle);
 int device_match_any(struct device *dev, const void *unused);
 
 /* iterator helpers for buses */
-int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data,
+int bus_for_each_dev(const struct bus_type *bus, struct device *start, void *data,
 		     int (*fn)(struct device *dev, void *data));
-struct device *bus_find_device(struct bus_type *bus, struct device *start,
+struct device *bus_find_device(const struct bus_type *bus, struct device *start,
 			       const void *data,
 			       int (*match)(struct device *dev, const void *data));
 /**
@@ -161,7 +161,7 @@ struct device *bus_find_device(struct bus_type *bus, struct device *start,
  * @start: Device to begin with
  * @name: name of the device to match
  */
-static inline struct device *bus_find_device_by_name(struct bus_type *bus,
+static inline struct device *bus_find_device_by_name(const struct bus_type *bus,
 						     struct device *start,
 						     const char *name)
 {
@@ -175,7 +175,7 @@ static inline struct device *bus_find_device_by_name(struct bus_type *bus,
  * @np: of_node of the device to match.
  */
 static inline struct device *
-bus_find_device_by_of_node(struct bus_type *bus, const struct device_node *np)
+bus_find_device_by_of_node(const struct bus_type *bus, const struct device_node *np)
 {
 	return bus_find_device(bus, NULL, np, device_match_of_node);
 }
@@ -187,7 +187,7 @@ bus_find_device_by_of_node(struct bus_type *bus, const struct device_node *np)
  * @fwnode: fwnode of the device to match.
  */
 static inline struct device *
-bus_find_device_by_fwnode(struct bus_type *bus, const struct fwnode_handle *fwnode)
+bus_find_device_by_fwnode(const struct bus_type *bus, const struct fwnode_handle *fwnode)
 {
 	return bus_find_device(bus, NULL, fwnode, device_match_fwnode);
 }
@@ -198,7 +198,7 @@ bus_find_device_by_fwnode(struct bus_type *bus, const struct fwnode_handle *fwno
  * @bus: bus type
  * @devt: device type of the device to match.
  */
-static inline struct device *bus_find_device_by_devt(struct bus_type *bus,
+static inline struct device *bus_find_device_by_devt(const struct bus_type *bus,
 						     dev_t devt)
 {
 	return bus_find_device(bus, NULL, &devt, device_match_devt);
@@ -211,7 +211,7 @@ static inline struct device *bus_find_device_by_devt(struct bus_type *bus,
  * @cur: device to begin the search with.
  */
 static inline struct device *
-bus_find_next_device(struct bus_type *bus,struct device *cur)
+bus_find_next_device(const struct bus_type *bus,struct device *cur)
 {
 	return bus_find_device(bus, cur, NULL, device_match_any);
 }
@@ -226,19 +226,19 @@ struct acpi_device;
  * @adev: ACPI COMPANION device to match.
  */
 static inline struct device *
-bus_find_device_by_acpi_dev(struct bus_type *bus, const struct acpi_device *adev)
+bus_find_device_by_acpi_dev(const struct bus_type *bus, const struct acpi_device *adev)
 {
 	return bus_find_device(bus, NULL, adev, device_match_acpi_dev);
 }
 #else
 static inline struct device *
-bus_find_device_by_acpi_dev(struct bus_type *bus, const void *adev)
+bus_find_device_by_acpi_dev(const struct bus_type *bus, const void *adev)
 {
 	return NULL;
 }
 #endif
 
-int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
+int bus_for_each_drv(const struct bus_type *bus, struct device_driver *start,
 		     void *data, int (*fn)(struct device_driver *, void *));
 void bus_sort_breadthfirst(struct bus_type *bus,
 			   int (*compare)(const struct device *a,
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 04/21] driver core: bus: convert bus_create/remove_file to be constant
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (2 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 03/21] driver core: bus: constantify the bus_find_* functions Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 05/21] driver core: bus: sysfs function cleanups Greg Kroah-Hartman
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

bus_create_file() and bus_remove_file() can be made to take a constant
bus pointer, as it should not be modifying anything in the bus
structure.  Make this change and move the functions to use the internal
subsys_get/put() logic as well, to prevent the use of the back-pointer
in struct bus_type.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c         | 28 +++++++++++++++++-----------
 include/linux/device/bus.h |  5 ++---
 2 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 7949302663f9..8debbe00b4ca 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -175,24 +175,30 @@ static const struct sysfs_ops bus_sysfs_ops = {
 	.store	= bus_attr_store,
 };
 
-int bus_create_file(struct bus_type *bus, struct bus_attribute *attr)
+int bus_create_file(const struct bus_type *bus, struct bus_attribute *attr)
 {
+	struct subsys_private *sp = bus_to_subsys(bus);
 	int error;
-	if (bus_get(bus)) {
-		error = sysfs_create_file(&bus->p->subsys.kobj, &attr->attr);
-		bus_put(bus);
-	} else
-		error = -EINVAL;
+
+	if (!sp)
+		return -EINVAL;
+
+	error = sysfs_create_file(&sp->subsys.kobj, &attr->attr);
+
+	subsys_put(sp);
 	return error;
 }
 EXPORT_SYMBOL_GPL(bus_create_file);
 
-void bus_remove_file(struct bus_type *bus, struct bus_attribute *attr)
+void bus_remove_file(const struct bus_type *bus, struct bus_attribute *attr)
 {
-	if (bus_get(bus)) {
-		sysfs_remove_file(&bus->p->subsys.kobj, &attr->attr);
-		bus_put(bus);
-	}
+	struct subsys_private *sp = bus_to_subsys(bus);
+
+	if (!sp)
+		return;
+
+	sysfs_remove_file(&sp->subsys.kobj, &attr->attr);
+	subsys_put(sp);
 }
 EXPORT_SYMBOL_GPL(bus_remove_file);
 
diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h
index f0c8bf91b07a..f6537f5fc535 100644
--- a/include/linux/device/bus.h
+++ b/include/linux/device/bus.h
@@ -135,9 +135,8 @@ struct bus_attribute {
 #define BUS_ATTR_WO(_name) \
 	struct bus_attribute bus_attr_##_name = __ATTR_WO(_name)
 
-extern int __must_check bus_create_file(struct bus_type *,
-					struct bus_attribute *);
-extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
+int __must_check bus_create_file(const struct bus_type *bus, struct bus_attribute *attr);
+void bus_remove_file(const struct bus_type *bus, struct bus_attribute *attr);
 
 /* Generic device matching functions that all busses can use to match with */
 int device_match_name(struct device *dev, const void *name);
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 05/21] driver core: bus: sysfs function cleanups
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (3 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 04/21] driver core: bus: convert bus_create/remove_file to be constant Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 06/21] driver core: bus: bus_add/probe/remove_device() cleanups Greg Kroah-Hartman
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

Convert the drivers_autoprobe show/store and uevent sysfs callbacks to
use bus_to_subsys() and not use the back-pointer to the private
structure.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c | 35 +++++++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 8debbe00b4ca..f0d3ad41fd5e 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -277,16 +277,31 @@ static DRIVER_ATTR_IGNORE_LOCKDEP(bind, 0200, NULL, bind_store);
 
 static ssize_t drivers_autoprobe_show(struct bus_type *bus, char *buf)
 {
-	return sysfs_emit(buf, "%d\n", bus->p->drivers_autoprobe);
+	struct subsys_private *sp = bus_to_subsys(bus);
+	int ret;
+
+	if (!sp)
+		return -EINVAL;
+
+	ret = sysfs_emit(buf, "%d\n", sp->drivers_autoprobe);
+	subsys_put(sp);
+	return ret;
 }
 
 static ssize_t drivers_autoprobe_store(struct bus_type *bus,
 				       const char *buf, size_t count)
 {
+	struct subsys_private *sp = bus_to_subsys(bus);
+
+	if (!sp)
+		return -EINVAL;
+
 	if (buf[0] == '0')
-		bus->p->drivers_autoprobe = 0;
+		sp->drivers_autoprobe = 0;
 	else
-		bus->p->drivers_autoprobe = 1;
+		sp->drivers_autoprobe = 1;
+
+	subsys_put(sp);
 	return count;
 }
 
@@ -769,10 +784,18 @@ static void klist_devices_put(struct klist_node *n)
 static ssize_t bus_uevent_store(struct bus_type *bus,
 				const char *buf, size_t count)
 {
-	int rc;
+	struct subsys_private *sp = bus_to_subsys(bus);
+	int ret;
 
-	rc = kobject_synth_uevent(&bus->p->subsys.kobj, buf, count);
-	return rc ? rc : count;
+	if (!sp)
+		return -EINVAL;
+
+	ret = kobject_synth_uevent(&sp->subsys.kobj, buf, count);
+	subsys_put(sp);
+
+	if (ret)
+		return ret;
+	return count;
 }
 /*
  * "open code" the old BUS_ATTR() macro here.  We want to use BUS_ATTR_WO()
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 06/21] driver core: bus: bus_add/probe/remove_device() cleanups
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (4 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 05/21] driver core: bus: sysfs function cleanups Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 07/21] driver core: bus: bus_register/unregister() cleanups Greg Kroah-Hartman
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

Convert the bus_add_device(), bus_probe_device(), and
bus_remove_device() functions to use bus_to_subsys() and not use the
back-pointer to the private structure.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c | 87 ++++++++++++++++++++++++++++------------------
 1 file changed, 54 insertions(+), 33 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index f0d3ad41fd5e..f4e4efd81b29 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -466,32 +466,46 @@ EXPORT_SYMBOL_GPL(bus_for_each_drv);
  */
 int bus_add_device(struct device *dev)
 {
-	struct bus_type *bus = bus_get(dev->bus);
-	int error = 0;
+	struct subsys_private *sp = bus_to_subsys(dev->bus);
+	int error;
 
-	if (bus) {
-		pr_debug("bus: '%s': add device %s\n", bus->name, dev_name(dev));
-		error = device_add_groups(dev, bus->dev_groups);
-		if (error)
-			goto out_put;
-		error = sysfs_create_link(&bus->p->devices_kset->kobj,
-						&dev->kobj, dev_name(dev));
-		if (error)
-			goto out_groups;
-		error = sysfs_create_link(&dev->kobj,
-				&dev->bus->p->subsys.kobj, "subsystem");
-		if (error)
-			goto out_subsys;
-		klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
+	if (!sp) {
+		/*
+		 * This is a normal operation for many devices that do not
+		 * have a bus assigned to them, just say that all went
+		 * well.
+		 */
+		return 0;
 	}
+
+	/*
+	 * Reference in sp is now incremented and will be dropped when
+	 * the device is removed from the bus
+	 */
+
+	pr_debug("bus: '%s': add device %s\n", sp->bus->name, dev_name(dev));
+
+	error = device_add_groups(dev, sp->bus->dev_groups);
+	if (error)
+		goto out_put;
+
+	error = sysfs_create_link(&sp->devices_kset->kobj, &dev->kobj, dev_name(dev));
+	if (error)
+		goto out_groups;
+
+	error = sysfs_create_link(&dev->kobj, &sp->subsys.kobj, "subsystem");
+	if (error)
+		goto out_subsys;
+
+	klist_add_tail(&dev->p->knode_bus, &sp->klist_devices);
 	return 0;
 
 out_subsys:
-	sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev));
+	sysfs_remove_link(&sp->devices_kset->kobj, dev_name(dev));
 out_groups:
-	device_remove_groups(dev, bus->dev_groups);
+	device_remove_groups(dev, sp->bus->dev_groups);
 out_put:
-	bus_put(dev->bus);
+	subsys_put(sp);
 	return error;
 }
 
@@ -503,20 +517,21 @@ int bus_add_device(struct device *dev)
  */
 void bus_probe_device(struct device *dev)
 {
-	struct bus_type *bus = dev->bus;
+	struct subsys_private *sp = bus_to_subsys(dev->bus);
 	struct subsys_interface *sif;
 
-	if (!bus)
+	if (!sp)
 		return;
 
-	if (bus->p->drivers_autoprobe)
+	if (sp->drivers_autoprobe)
 		device_initial_probe(dev);
 
-	mutex_lock(&bus->p->mutex);
-	list_for_each_entry(sif, &bus->p->interfaces, node)
+	mutex_lock(&sp->mutex);
+	list_for_each_entry(sif, &sp->interfaces, node)
 		if (sif->add_dev)
 			sif->add_dev(dev, sif);
-	mutex_unlock(&bus->p->mutex);
+	mutex_unlock(&sp->mutex);
+	subsys_put(sp);
 }
 
 /**
@@ -531,21 +546,20 @@ void bus_probe_device(struct device *dev)
  */
 void bus_remove_device(struct device *dev)
 {
-	struct bus_type *bus = dev->bus;
+	struct subsys_private *sp = bus_to_subsys(dev->bus);
 	struct subsys_interface *sif;
 
-	if (!bus)
+	if (!sp)
 		return;
 
-	mutex_lock(&bus->p->mutex);
-	list_for_each_entry(sif, &bus->p->interfaces, node)
+	mutex_lock(&sp->mutex);
+	list_for_each_entry(sif, &sp->interfaces, node)
 		if (sif->remove_dev)
 			sif->remove_dev(dev, sif);
-	mutex_unlock(&bus->p->mutex);
+	mutex_unlock(&sp->mutex);
 
 	sysfs_remove_link(&dev->kobj, "subsystem");
-	sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
-			  dev_name(dev));
+	sysfs_remove_link(&sp->devices_kset->kobj, dev_name(dev));
 	device_remove_groups(dev, dev->bus->dev_groups);
 	if (klist_node_attached(&dev->p->knode_bus))
 		klist_del(&dev->p->knode_bus);
@@ -553,7 +567,14 @@ void bus_remove_device(struct device *dev)
 	pr_debug("bus: '%s': remove device %s\n",
 		 dev->bus->name, dev_name(dev));
 	device_release_driver(dev);
-	bus_put(dev->bus);
+
+	/*
+	 * Decrement the reference count twice, once for the bus_to_subsys()
+	 * call in the start of this function, and the second one from the
+	 * reference increment in bus_add_device()
+	 */
+	subsys_put(sp);
+	subsys_put(sp);
 }
 
 static int __must_check add_bind_files(struct device_driver *drv)
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 07/21] driver core: bus: bus_register/unregister() cleanups
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (5 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 06/21] driver core: bus: bus_add/probe/remove_device() cleanups Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 08/21] driver core: bus: subsys_interface_register/unregister() cleanups Greg Kroah-Hartman
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

Convert the bus_register() and bus_unregister() functions to use
bus_to_subsys() and not use the back-pointer to the private structure.

Because bus_add_groups() and bus_remove_groups() were only called in one
place, remove those one-line-wrapper functions and call the real sysfs
group function where it is needed instead, saving another layer of
indirection.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c | 54 ++++++++++++++++++++++------------------------
 1 file changed, 26 insertions(+), 28 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index f4e4efd81b29..549e55dfbfda 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -774,18 +774,6 @@ int device_reprobe(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(device_reprobe);
 
-static int bus_add_groups(struct bus_type *bus,
-			  const struct attribute_group **groups)
-{
-	return sysfs_create_groups(&bus->p->subsys.kobj, groups);
-}
-
-static void bus_remove_groups(struct bus_type *bus,
-			      const struct attribute_group **groups)
-{
-	sysfs_remove_groups(&bus->p->subsys.kobj, groups);
-}
-
 static void klist_devices_get(struct klist_node *n)
 {
 	struct device_private *dev_prv = to_device_private_bus(n);
@@ -839,6 +827,7 @@ int bus_register(struct bus_type *bus)
 {
 	int retval;
 	struct subsys_private *priv;
+	struct kobject *bus_kobj;
 	struct lock_class_key *key;
 
 	priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL);
@@ -850,12 +839,13 @@ int bus_register(struct bus_type *bus)
 
 	BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);
 
-	retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);
+	bus_kobj = &priv->subsys.kobj;
+	retval = kobject_set_name(bus_kobj, "%s", bus->name);
 	if (retval)
 		goto out;
 
-	priv->subsys.kobj.kset = bus_kset;
-	priv->subsys.kobj.ktype = &bus_ktype;
+	bus_kobj->kset = bus_kset;
+	bus_kobj->ktype = &bus_ktype;
 	priv->drivers_autoprobe = 1;
 
 	retval = kset_register(&priv->subsys);
@@ -866,15 +856,13 @@ int bus_register(struct bus_type *bus)
 	if (retval)
 		goto bus_uevent_fail;
 
-	priv->devices_kset = kset_create_and_add("devices", NULL,
-						 &priv->subsys.kobj);
+	priv->devices_kset = kset_create_and_add("devices", NULL, bus_kobj);
 	if (!priv->devices_kset) {
 		retval = -ENOMEM;
 		goto bus_devices_fail;
 	}
 
-	priv->drivers_kset = kset_create_and_add("drivers", NULL,
-						 &priv->subsys.kobj);
+	priv->drivers_kset = kset_create_and_add("drivers", NULL, bus_kobj);
 	if (!priv->drivers_kset) {
 		retval = -ENOMEM;
 		goto bus_drivers_fail;
@@ -891,7 +879,7 @@ int bus_register(struct bus_type *bus)
 	if (retval)
 		goto bus_probe_files_fail;
 
-	retval = bus_add_groups(bus, bus->bus_groups);
+	retval = sysfs_create_groups(bus_kobj, bus->bus_groups);
 	if (retval)
 		goto bus_groups_fail;
 
@@ -901,15 +889,15 @@ int bus_register(struct bus_type *bus)
 bus_groups_fail:
 	remove_probe_files(bus);
 bus_probe_files_fail:
-	kset_unregister(bus->p->drivers_kset);
+	kset_unregister(priv->drivers_kset);
 bus_drivers_fail:
-	kset_unregister(bus->p->devices_kset);
+	kset_unregister(priv->devices_kset);
 bus_devices_fail:
 	bus_remove_file(bus, &bus_attr_uevent);
 bus_uevent_fail:
-	kset_unregister(&bus->p->subsys);
+	kset_unregister(&priv->subsys);
 out:
-	kfree(bus->p);
+	kfree(priv);
 	bus->p = NULL;
 	return retval;
 }
@@ -924,15 +912,25 @@ EXPORT_SYMBOL_GPL(bus_register);
  */
 void bus_unregister(struct bus_type *bus)
 {
+	struct subsys_private *sp = bus_to_subsys(bus);
+	struct kobject *bus_kobj;
+
+	if (!sp)
+		return;
+
 	pr_debug("bus: '%s': unregistering\n", bus->name);
 	if (bus->dev_root)
 		device_unregister(bus->dev_root);
-	bus_remove_groups(bus, bus->bus_groups);
+
+	bus_kobj = &sp->subsys.kobj;
+	sysfs_remove_groups(bus_kobj, bus->bus_groups);
 	remove_probe_files(bus);
-	kset_unregister(bus->p->drivers_kset);
-	kset_unregister(bus->p->devices_kset);
 	bus_remove_file(bus, &bus_attr_uevent);
-	kset_unregister(&bus->p->subsys);
+
+	kset_unregister(sp->drivers_kset);
+	kset_unregister(sp->devices_kset);
+	kset_unregister(&sp->subsys);
+	subsys_put(sp);
 }
 EXPORT_SYMBOL_GPL(bus_unregister);
 
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 08/21] driver core: bus: subsys_interface_register/unregister() cleanups
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (6 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 07/21] driver core: bus: bus_register/unregister() cleanups Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 09/21] driver core: bus: bus_get_kset() cleanup Greg Kroah-Hartman
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

Convert the subsys_interface_register and subsys_interface_unregister()
functions to use bus_to_subsys() and not use the back-pointer to the
private structure.

This also requires changing the parameters on subsys_dev_iter_init() to
iterate over the list properly.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c | 45 +++++++++++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 16 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 549e55dfbfda..deed62509a62 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -1023,7 +1023,7 @@ struct subsys_dev_iter {
 /**
  * subsys_dev_iter_init - initialize subsys device iterator
  * @iter: subsys iterator to initialize
- * @subsys: the subsys we wanna iterate over
+ * @sp: the subsys private (i.e. bus) we wanna iterate over
  * @start: the device to start iterating from, if any
  * @type: device_type of the devices to iterate over, NULL for all
  *
@@ -1032,14 +1032,14 @@ struct subsys_dev_iter {
  * otherwise if it is NULL, the iteration starts at the beginning of
  * the list.
  */
-static void subsys_dev_iter_init(struct subsys_dev_iter *iter, struct bus_type *subsys,
+static void subsys_dev_iter_init(struct subsys_dev_iter *iter, struct subsys_private *sp,
 				 struct device *start, const struct device_type *type)
 {
 	struct klist_node *start_knode = NULL;
 
 	if (start)
 		start_knode = &start->p->knode_bus;
-	klist_iter_init_node(&subsys->p->klist_devices, &iter->ki, start_knode);
+	klist_iter_init_node(&sp->klist_devices, &iter->ki, start_knode);
 	iter->type = type;
 }
 
@@ -1084,26 +1084,31 @@ static void subsys_dev_iter_exit(struct subsys_dev_iter *iter)
 
 int subsys_interface_register(struct subsys_interface *sif)
 {
-	struct bus_type *subsys;
+	struct subsys_private *sp;
 	struct subsys_dev_iter iter;
 	struct device *dev;
 
 	if (!sif || !sif->subsys)
 		return -ENODEV;
 
-	subsys = bus_get(sif->subsys);
-	if (!subsys)
+	sp = bus_to_subsys(sif->subsys);
+	if (!sp)
 		return -EINVAL;
 
-	mutex_lock(&subsys->p->mutex);
-	list_add_tail(&sif->node, &subsys->p->interfaces);
+	/*
+	 * Reference in sp is now incremented and will be dropped when
+	 * the interface is removed from the bus
+	 */
+
+	mutex_lock(&sp->mutex);
+	list_add_tail(&sif->node, &sp->interfaces);
 	if (sif->add_dev) {
-		subsys_dev_iter_init(&iter, subsys, NULL, NULL);
+		subsys_dev_iter_init(&iter, sp, NULL, NULL);
 		while ((dev = subsys_dev_iter_next(&iter)))
 			sif->add_dev(dev, sif);
 		subsys_dev_iter_exit(&iter);
 	}
-	mutex_unlock(&subsys->p->mutex);
+	mutex_unlock(&sp->mutex);
 
 	return 0;
 }
@@ -1111,26 +1116,34 @@ EXPORT_SYMBOL_GPL(subsys_interface_register);
 
 void subsys_interface_unregister(struct subsys_interface *sif)
 {
-	struct bus_type *subsys;
+	struct subsys_private *sp;
 	struct subsys_dev_iter iter;
 	struct device *dev;
 
 	if (!sif || !sif->subsys)
 		return;
 
-	subsys = sif->subsys;
+	sp = bus_to_subsys(sif->subsys);
+	if (!sp)
+		return;
 
-	mutex_lock(&subsys->p->mutex);
+	mutex_lock(&sp->mutex);
 	list_del_init(&sif->node);
 	if (sif->remove_dev) {
-		subsys_dev_iter_init(&iter, subsys, NULL, NULL);
+		subsys_dev_iter_init(&iter, sp, NULL, NULL);
 		while ((dev = subsys_dev_iter_next(&iter)))
 			sif->remove_dev(dev, sif);
 		subsys_dev_iter_exit(&iter);
 	}
-	mutex_unlock(&subsys->p->mutex);
+	mutex_unlock(&sp->mutex);
 
-	bus_put(subsys);
+	/*
+	 * Decrement the reference count twice, once for the bus_to_subsys()
+	 * call in the start of this function, and the second one from the
+	 * reference increment in subsys_interface_register()
+	 */
+	subsys_put(sp);
+	subsys_put(sp);
 }
 EXPORT_SYMBOL_GPL(subsys_interface_unregister);
 
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 09/21] driver core: bus: bus_get_kset() cleanup
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (7 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 08/21] driver core: bus: subsys_interface_register/unregister() cleanups Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 10/21] driver core: bus: bus_register/unregister_notifier() cleanups Greg Kroah-Hartman
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

Convert the bus_get_kset() function function to use bus_to_subsys() and
not use the back-pointer to the private structure.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index deed62509a62..90627c68d02b 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -956,7 +956,16 @@ void bus_notify(struct device *dev, enum bus_notifier_event value)
 
 struct kset *bus_get_kset(struct bus_type *bus)
 {
-	return &bus->p->subsys;
+	struct subsys_private *sp = bus_to_subsys(bus);
+	struct kset *kset;
+
+	if (!sp)
+		return NULL;
+
+	kset = &sp->subsys;
+	subsys_put(sp);
+
+	return kset;
 }
 EXPORT_SYMBOL_GPL(bus_get_kset);
 
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 10/21] driver core: bus: bus_register/unregister_notifier() cleanups
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (8 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 09/21] driver core: bus: bus_get_kset() cleanup Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 11/21] driver core: bus: bus_add/remove_driver() cleanups Greg Kroah-Hartman
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

Convert the bus_register_notifier() and bus_unregister_notifier() public
functions to use bus_to_subsys() and not use the back-pointer to the
private structure as well as the bus_notify() function.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 90627c68d02b..f23c6f6306e2 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -936,22 +936,40 @@ EXPORT_SYMBOL_GPL(bus_unregister);
 
 int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb)
 {
-	return blocking_notifier_chain_register(&bus->p->bus_notifier, nb);
+	struct subsys_private *sp = bus_to_subsys(bus);
+	int retval;
+
+	if (!sp)
+		return -EINVAL;
+
+	retval = blocking_notifier_chain_register(&sp->bus_notifier, nb);
+	subsys_put(sp);
+	return retval;
 }
 EXPORT_SYMBOL_GPL(bus_register_notifier);
 
 int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb)
 {
-	return blocking_notifier_chain_unregister(&bus->p->bus_notifier, nb);
+	struct subsys_private *sp = bus_to_subsys(bus);
+	int retval;
+
+	if (!sp)
+		return -EINVAL;
+	retval = blocking_notifier_chain_unregister(&sp->bus_notifier, nb);
+	subsys_put(sp);
+	return retval;
 }
 EXPORT_SYMBOL_GPL(bus_unregister_notifier);
 
 void bus_notify(struct device *dev, enum bus_notifier_event value)
 {
-	struct bus_type *bus = dev->bus;
+	struct subsys_private *sp = bus_to_subsys(dev->bus);
 
-	if (bus)
-		blocking_notifier_call_chain(&bus->p->bus_notifier, value, dev);
+	if (!sp)
+		return;
+
+	blocking_notifier_call_chain(&sp->bus_notifier, value, dev);
+	subsys_put(sp);
 }
 
 struct kset *bus_get_kset(struct bus_type *bus)
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 11/21] driver core: bus: bus_add/remove_driver() cleanups
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (9 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 10/21] driver core: bus: bus_register/unregister_notifier() cleanups Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 12/21] driver core: bus: bus iterator cleanups Greg Kroah-Hartman
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

Convert the bus_add_driver() and bus_remove_driver() functions to use
bus_to_subsys() and not use the back-pointer to the private structure.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c | 39 ++++++++++++++++++++++++++-------------
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index f23c6f6306e2..b594804c716d 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -636,15 +636,18 @@ static DRIVER_ATTR_WO(uevent);
  */
 int bus_add_driver(struct device_driver *drv)
 {
-	struct bus_type *bus;
+	struct subsys_private *sp = bus_to_subsys(drv->bus);
 	struct driver_private *priv;
 	int error = 0;
 
-	bus = bus_get(drv->bus);
-	if (!bus)
+	if (!sp)
 		return -EINVAL;
 
-	pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);
+	/*
+	 * Reference in sp is now incremented and will be dropped when
+	 * the driver is removed from the bus
+	 */
+	pr_debug("bus: '%s': add driver %s\n", sp->bus->name, drv->name);
 
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv) {
@@ -654,14 +657,14 @@ int bus_add_driver(struct device_driver *drv)
 	klist_init(&priv->klist_devices, NULL, NULL);
 	priv->driver = drv;
 	drv->p = priv;
-	priv->kobj.kset = bus->p->drivers_kset;
+	priv->kobj.kset = sp->drivers_kset;
 	error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
 				     "%s", drv->name);
 	if (error)
 		goto out_unregister;
 
-	klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
-	if (drv->bus->p->drivers_autoprobe) {
+	klist_add_tail(&priv->knode_bus, &sp->klist_drivers);
+	if (sp->drivers_autoprobe) {
 		error = driver_attach(drv);
 		if (error)
 			goto out_del_list;
@@ -673,7 +676,7 @@ int bus_add_driver(struct device_driver *drv)
 		printk(KERN_ERR "%s: uevent attr (%s) failed\n",
 			__func__, drv->name);
 	}
-	error = driver_add_groups(drv, bus->drv_groups);
+	error = driver_add_groups(drv, sp->bus->drv_groups);
 	if (error) {
 		/* How the hell do we get out of this pickle? Give up */
 		printk(KERN_ERR "%s: driver_add_groups(%s) failed\n",
@@ -698,7 +701,7 @@ int bus_add_driver(struct device_driver *drv)
 	/* drv->p is freed in driver_release()  */
 	drv->p = NULL;
 out_put_bus:
-	bus_put(bus);
+	subsys_put(sp);
 	return error;
 }
 
@@ -712,19 +715,29 @@ int bus_add_driver(struct device_driver *drv)
  */
 void bus_remove_driver(struct device_driver *drv)
 {
-	if (!drv->bus)
+	struct subsys_private *sp = bus_to_subsys(drv->bus);
+
+	if (!sp)
 		return;
 
+	pr_debug("bus: '%s': remove driver %s\n", sp->bus->name, drv->name);
+
 	if (!drv->suppress_bind_attrs)
 		remove_bind_files(drv);
-	driver_remove_groups(drv, drv->bus->drv_groups);
+	driver_remove_groups(drv, sp->bus->drv_groups);
 	driver_remove_file(drv, &driver_attr_uevent);
 	klist_remove(&drv->p->knode_bus);
-	pr_debug("bus: '%s': remove driver %s\n", drv->bus->name, drv->name);
 	driver_detach(drv);
 	module_remove_driver(drv);
 	kobject_put(&drv->p->kobj);
-	bus_put(drv->bus);
+
+	/*
+	 * Decrement the reference count twice, once for the bus_to_subsys()
+	 * call in the start of this function, and the second one from the
+	 * reference increment in bus_add_driver()
+	 */
+	subsys_put(sp);
+	subsys_put(sp);
 }
 
 /* Helper for bus_rescan_devices's iter */
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 12/21] driver core: bus: bus iterator cleanups
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (10 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 11/21] driver core: bus: bus_add/remove_driver() cleanups Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-21 12:54   ` Geert Uytterhoeven
  2023-02-08 11:13 ` [PATCH 13/21] driver core: bus: clean up bus_sort_breadthfirst() Greg Kroah-Hartman
                   ` (8 subsequent siblings)
  20 siblings, 1 reply; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

Convert the bus_for_each_dev(), bus_find_device, and bus_for_each_drv()
functions to use bus_to_subsys() and not use the back-pointer to the
private structure.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index b594804c716d..c007524151d2 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -355,18 +355,20 @@ static struct device *next_device(struct klist_iter *i)
 int bus_for_each_dev(const struct bus_type *bus, struct device *start,
 		     void *data, int (*fn)(struct device *, void *))
 {
+	struct subsys_private *sp = bus_to_subsys(bus);
 	struct klist_iter i;
 	struct device *dev;
 	int error = 0;
 
-	if (!bus || !bus->p)
+	if (!sp)
 		return -EINVAL;
 
-	klist_iter_init_node(&bus->p->klist_devices, &i,
+	klist_iter_init_node(&sp->klist_devices, &i,
 			     (start ? &start->p->knode_bus : NULL));
 	while (!error && (dev = next_device(&i)))
 		error = fn(dev, data);
 	klist_iter_exit(&i);
+	subsys_put(sp);
 	return error;
 }
 EXPORT_SYMBOL_GPL(bus_for_each_dev);
@@ -390,18 +392,20 @@ struct device *bus_find_device(const struct bus_type *bus,
 			       struct device *start, const void *data,
 			       int (*match)(struct device *dev, const void *data))
 {
+	struct subsys_private *sp = bus_to_subsys(bus);
 	struct klist_iter i;
 	struct device *dev;
 
-	if (!bus || !bus->p)
+	if (!sp)
 		return NULL;
 
-	klist_iter_init_node(&bus->p->klist_devices, &i,
+	klist_iter_init_node(&sp->klist_devices, &i,
 			     (start ? &start->p->knode_bus : NULL));
 	while ((dev = next_device(&i)))
 		if (match(dev, data) && get_device(dev))
 			break;
 	klist_iter_exit(&i);
+	subsys_put(sp);
 	return dev;
 }
 EXPORT_SYMBOL_GPL(bus_find_device);
@@ -440,18 +444,20 @@ static struct device_driver *next_driver(struct klist_iter *i)
 int bus_for_each_drv(const struct bus_type *bus, struct device_driver *start,
 		     void *data, int (*fn)(struct device_driver *, void *))
 {
+	struct subsys_private *sp = bus_to_subsys(bus);
 	struct klist_iter i;
 	struct device_driver *drv;
 	int error = 0;
 
-	if (!bus)
+	if (!sp)
 		return -EINVAL;
 
-	klist_iter_init_node(&bus->p->klist_drivers, &i,
+	klist_iter_init_node(&sp->klist_drivers, &i,
 			     start ? &start->p->knode_bus : NULL);
 	while ((drv = next_driver(&i)) && !error)
 		error = fn(drv, data);
 	klist_iter_exit(&i);
+	subsys_put(sp);
 	return error;
 }
 EXPORT_SYMBOL_GPL(bus_for_each_drv);
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 13/21] driver core: bus: clean up bus_sort_breadthfirst()
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (11 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 12/21] driver core: bus: bus iterator cleanups Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 14/21] driver core: move driver_find() to bus.c Greg Kroah-Hartman
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

Convert the bus_sort_breadthfirst() function to use bus_to_subsys() and
not use the back-pointer to the private structure.

This also allows us to get rid of bus_get_device_klist() which was only
being used by this one internal function.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index c007524151d2..87e21aafe6e6 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -1006,11 +1006,6 @@ struct kset *bus_get_kset(struct bus_type *bus)
 }
 EXPORT_SYMBOL_GPL(bus_get_kset);
 
-static struct klist *bus_get_device_klist(struct bus_type *bus)
-{
-	return &bus->p->klist_devices;
-}
-
 /*
  * Yes, this forcibly breaks the klist abstraction temporarily.  It
  * just wants to sort the klist, not change reference counts and
@@ -1042,13 +1037,16 @@ void bus_sort_breadthfirst(struct bus_type *bus,
 			   int (*compare)(const struct device *a,
 					  const struct device *b))
 {
+	struct subsys_private *sp = bus_to_subsys(bus);
 	LIST_HEAD(sorted_devices);
 	struct klist_node *n, *tmp;
 	struct device_private *dev_prv;
 	struct device *dev;
 	struct klist *device_klist;
 
-	device_klist = bus_get_device_klist(bus);
+	if (!sp)
+		return;
+	device_klist = &sp->klist_devices;
 
 	spin_lock(&device_klist->k_lock);
 	list_for_each_entry_safe(n, tmp, &device_klist->k_list, n_node) {
@@ -1058,6 +1056,7 @@ void bus_sort_breadthfirst(struct bus_type *bus,
 	}
 	list_splice(&sorted_devices, &device_klist->k_list);
 	spin_unlock(&device_klist->k_lock);
+	subsys_put(sp);
 }
 EXPORT_SYMBOL_GPL(bus_sort_breadthfirst);
 
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 14/21] driver core: move driver_find() to bus.c
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (12 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 13/21] driver core: bus: clean up bus_sort_breadthfirst() Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 15/21] driver core: bus: clean up driver_find() Greg Kroah-Hartman
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

This function really is a bus function, not a driver one, so move it
from driver.c to bus.c so that we can clean up some internal bus logic
easier.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c    | 27 +++++++++++++++++++++++++++
 drivers/base/driver.c | 27 ---------------------------
 2 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 87e21aafe6e6..727de4c36d59 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -1288,6 +1288,33 @@ int subsys_virtual_register(struct bus_type *subsys,
 }
 EXPORT_SYMBOL_GPL(subsys_virtual_register);
 
+/**
+ * driver_find - locate driver on a bus by its name.
+ * @name: name of the driver.
+ * @bus: bus to scan for the driver.
+ *
+ * Call kset_find_obj() to iterate over list of drivers on
+ * a bus to find driver by name. Return driver if found.
+ *
+ * This routine provides no locking to prevent the driver it returns
+ * from being unregistered or unloaded while the caller is using it.
+ * The caller is responsible for preventing this.
+ */
+struct device_driver *driver_find(const char *name, struct bus_type *bus)
+{
+	struct kobject *k = kset_find_obj(bus->p->drivers_kset, name);
+	struct driver_private *priv;
+
+	if (k) {
+		/* Drop reference added by kset_find_obj() */
+		kobject_put(k);
+		priv = to_driver(k);
+		return priv->driver;
+	}
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(driver_find);
+
 int __init buses_init(void)
 {
 	bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 676b6275d5b5..aa5e5166a671 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -274,30 +274,3 @@ void driver_unregister(struct device_driver *drv)
 	bus_remove_driver(drv);
 }
 EXPORT_SYMBOL_GPL(driver_unregister);
-
-/**
- * driver_find - locate driver on a bus by its name.
- * @name: name of the driver.
- * @bus: bus to scan for the driver.
- *
- * Call kset_find_obj() to iterate over list of drivers on
- * a bus to find driver by name. Return driver if found.
- *
- * This routine provides no locking to prevent the driver it returns
- * from being unregistered or unloaded while the caller is using it.
- * The caller is responsible for preventing this.
- */
-struct device_driver *driver_find(const char *name, struct bus_type *bus)
-{
-	struct kobject *k = kset_find_obj(bus->p->drivers_kset, name);
-	struct driver_private *priv;
-
-	if (k) {
-		/* Drop reference added by kset_find_obj() */
-		kobject_put(k);
-		priv = to_driver(k);
-		return priv->driver;
-	}
-	return NULL;
-}
-EXPORT_SYMBOL_GPL(driver_find);
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 15/21] driver core: bus: clean up driver_find()
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (13 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 14/21] driver core: move driver_find() to bus.c Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 16/21] driver core: create bus_is_registered() Greg Kroah-Hartman
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

Convert the driver_find() function to use bus_to_subsys() and not use
the back-pointer to the private structure.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 727de4c36d59..951d63c8e885 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -1302,16 +1302,23 @@ EXPORT_SYMBOL_GPL(subsys_virtual_register);
  */
 struct device_driver *driver_find(const char *name, struct bus_type *bus)
 {
-	struct kobject *k = kset_find_obj(bus->p->drivers_kset, name);
+	struct subsys_private *sp = bus_to_subsys(bus);
+	struct kobject *k;
 	struct driver_private *priv;
 
-	if (k) {
-		/* Drop reference added by kset_find_obj() */
-		kobject_put(k);
-		priv = to_driver(k);
-		return priv->driver;
-	}
-	return NULL;
+	if (!sp)
+		return NULL;
+
+	k = kset_find_obj(sp->drivers_kset, name);
+	subsys_put(sp);
+	if (!k)
+		return NULL;
+
+	priv = to_driver(k);
+
+	/* Drop reference added by kset_find_obj() */
+	kobject_put(k);
+	return priv->driver;
 }
 EXPORT_SYMBOL_GPL(driver_find);
 
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 16/21] driver core: create bus_is_registered()
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (14 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 15/21] driver core: bus: clean up driver_find() Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 17/21] driver core: remove private pointer from struct bus_type Greg Kroah-Hartman
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

A local function to the driver core to determine if a bus really is
registered with the kernel or not.  To be used only by the driver core
code, as part of the driver registration path as it's not really "safe"
because the bus could be unregistered instantly after being called.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/base.h   |  1 +
 drivers/base/bus.c    | 16 ++++++++++++++++
 drivers/base/driver.c |  2 +-
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index 9e06c18c7a64..726a12a244c0 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -146,6 +146,7 @@ extern int bus_add_device(struct device *dev);
 extern void bus_probe_device(struct device *dev);
 extern void bus_remove_device(struct device *dev);
 void bus_notify(struct device *dev, enum bus_notifier_event value);
+bool bus_is_registered(const struct bus_type *bus);
 
 extern int bus_add_driver(struct device_driver *drv);
 extern void bus_remove_driver(struct device_driver *drv);
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 951d63c8e885..481fb3f41a42 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -1322,6 +1322,22 @@ struct device_driver *driver_find(const char *name, struct bus_type *bus)
 }
 EXPORT_SYMBOL_GPL(driver_find);
 
+/*
+ * Warning, the value could go to "removed" instantly after calling this function, so be very
+ * careful when calling it...
+ */
+bool bus_is_registered(const struct bus_type *bus)
+{
+	struct subsys_private *sp = bus_to_subsys(bus);
+	bool is_initialized = false;
+
+	if (sp) {
+		is_initialized = true;
+		subsys_put(sp);
+	}
+	return is_initialized;
+}
+
 int __init buses_init(void)
 {
 	bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index aa5e5166a671..c8436c26ed6a 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -224,7 +224,7 @@ int driver_register(struct device_driver *drv)
 	int ret;
 	struct device_driver *other;
 
-	if (!drv->bus->p) {
+	if (!bus_is_registered(drv->bus)) {
 		pr_err("Driver '%s' was unable to register with bus_type '%s' because the bus was not initialized.\n",
 			   drv->name, drv->bus->name);
 		return -EINVAL;
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 17/21] driver core: remove private pointer from struct bus_type
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (15 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 16/21] driver core: create bus_is_registered() Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 18/21] driver core: bus: constify bus_register/unregister_notifier() Greg Kroah-Hartman
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

Now that the driver code has been refactored to not rely on the pointer
from a struct bus_type to the private structure it can be safely removed
from the structure entirely.

This will allow most bus_type structures to now be marked as const.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c         | 4 ----
 include/linux/device/bus.h | 4 ----
 2 files changed, 8 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 481fb3f41a42..76cfe9cbf3bd 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -205,11 +205,9 @@ EXPORT_SYMBOL_GPL(bus_remove_file);
 static void bus_release(struct kobject *kobj)
 {
 	struct subsys_private *priv = to_subsys_private(kobj);
-	struct bus_type *bus = priv->bus;
 
 	lockdep_unregister_key(&priv->lock_key);
 	kfree(priv);
-	bus->p = NULL;
 }
 
 static struct kobj_type bus_ktype = {
@@ -854,7 +852,6 @@ int bus_register(struct bus_type *bus)
 		return -ENOMEM;
 
 	priv->bus = bus;
-	bus->p = priv;
 
 	BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);
 
@@ -917,7 +914,6 @@ int bus_register(struct bus_type *bus)
 	kset_unregister(&priv->subsys);
 out:
 	kfree(priv);
-	bus->p = NULL;
 	return retval;
 }
 EXPORT_SYMBOL_GPL(bus_register);
diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h
index f6537f5fc535..22bf63469275 100644
--- a/include/linux/device/bus.h
+++ b/include/linux/device/bus.h
@@ -66,8 +66,6 @@ struct fwnode_handle;
  * @iommu_ops:  IOMMU specific operations for this bus, used to attach IOMMU
  *              driver implementations to a bus and allow the driver to do
  *              bus-specific setup
- * @p:		The private data of the driver core, only the driver core can
- *		touch this.
  * @lock_key:	Lock class key for use by the lock validator
  * @need_parent_lock:	When probing or removing a device on this bus, the
  *			device core should lock the device's parent.
@@ -111,8 +109,6 @@ struct bus_type {
 
 	const struct iommu_ops *iommu_ops;
 
-	struct subsys_private *p;
-
 	bool need_parent_lock;
 };
 
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 18/21] driver core: bus: constify bus_register/unregister_notifier()
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (16 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 17/21] driver core: remove private pointer from struct bus_type Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 19/21] driver core: bus: constify bus_get_kset() Greg Kroah-Hartman
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

The bus_register_notifier() and bus_unregister_notifier() functions
should be taking a const * to bus_type, not just a * so fix that up.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c         | 4 ++--
 include/linux/device/bus.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 76cfe9cbf3bd..e6043a2d9feb 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -949,7 +949,7 @@ void bus_unregister(struct bus_type *bus)
 }
 EXPORT_SYMBOL_GPL(bus_unregister);
 
-int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb)
+int bus_register_notifier(const struct bus_type *bus, struct notifier_block *nb)
 {
 	struct subsys_private *sp = bus_to_subsys(bus);
 	int retval;
@@ -963,7 +963,7 @@ int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb)
 }
 EXPORT_SYMBOL_GPL(bus_register_notifier);
 
-int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb)
+int bus_unregister_notifier(const struct bus_type *bus, struct notifier_block *nb)
 {
 	struct subsys_private *sp = bus_to_subsys(bus);
 	int retval;
diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h
index 22bf63469275..c0a034ff59b7 100644
--- a/include/linux/device/bus.h
+++ b/include/linux/device/bus.h
@@ -246,9 +246,9 @@ void bus_sort_breadthfirst(struct bus_type *bus,
  */
 struct notifier_block;
 
-extern int bus_register_notifier(struct bus_type *bus,
+extern int bus_register_notifier(const struct bus_type *bus,
 				 struct notifier_block *nb);
-extern int bus_unregister_notifier(struct bus_type *bus,
+extern int bus_unregister_notifier(const struct bus_type *bus,
 				   struct notifier_block *nb);
 
 /**
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 19/21] driver core: bus: constify bus_get_kset()
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (17 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 18/21] driver core: bus: constify bus_register/unregister_notifier() Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 20/21] driver core: bus: constify some internal functions Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 21/21] driver core: bus: constify bus_unregister() Greg Kroah-Hartman
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

The bus_get_kset() function should be taking a const * to bus_type, not
just a * so fix that up.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c         | 2 +-
 include/linux/device/bus.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index e6043a2d9feb..815638bf63db 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -987,7 +987,7 @@ void bus_notify(struct device *dev, enum bus_notifier_event value)
 	subsys_put(sp);
 }
 
-struct kset *bus_get_kset(struct bus_type *bus)
+struct kset *bus_get_kset(const struct bus_type *bus)
 {
 	struct subsys_private *sp = bus_to_subsys(bus);
 	struct kset *kset;
diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h
index c0a034ff59b7..425d79d6cf69 100644
--- a/include/linux/device/bus.h
+++ b/include/linux/device/bus.h
@@ -281,6 +281,6 @@ enum bus_notifier_event {
 	BUS_NOTIFY_DRIVER_NOT_BOUND,
 };
 
-extern struct kset *bus_get_kset(struct bus_type *bus);
+extern struct kset *bus_get_kset(const struct bus_type *bus);
 
 #endif
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 20/21] driver core: bus: constify some internal functions
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (18 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 19/21] driver core: bus: constify bus_get_kset() Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  2023-02-08 11:13 ` [PATCH 21/21] driver core: bus: constify bus_unregister() Greg Kroah-Hartman
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

The functions add_probe_files() and remove_probe_files() should be
taking a const * to bus_type, not just a *, so fix that up.  These
functions should really be removed entirely and an attribute group used
instead, but for now, make this change so that other const work can
continue.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 815638bf63db..a7aada8817ce 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -603,7 +603,7 @@ static void remove_bind_files(struct device_driver *drv)
 static BUS_ATTR_WO(drivers_probe);
 static BUS_ATTR_RW(drivers_autoprobe);
 
-static int add_probe_files(struct bus_type *bus)
+static int add_probe_files(const struct bus_type *bus)
 {
 	int retval;
 
@@ -618,7 +618,7 @@ static int add_probe_files(struct bus_type *bus)
 	return retval;
 }
 
-static void remove_probe_files(struct bus_type *bus)
+static void remove_probe_files(const struct bus_type *bus)
 {
 	bus_remove_file(bus, &bus_attr_drivers_autoprobe);
 	bus_remove_file(bus, &bus_attr_drivers_probe);
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 21/21] driver core: bus: constify bus_unregister()
  2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
                   ` (19 preceding siblings ...)
  2023-02-08 11:13 ` [PATCH 20/21] driver core: bus: constify some internal functions Greg Kroah-Hartman
@ 2023-02-08 11:13 ` Greg Kroah-Hartman
  20 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2023-02-08 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

The bus_unregister() function can now take a const * to bus_type, not
just a * so fix that up.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/bus.c         | 2 +-
 include/linux/device/bus.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index a7aada8817ce..4c85d264113a 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -925,7 +925,7 @@ EXPORT_SYMBOL_GPL(bus_register);
  * Unregister the child subsystems and the bus itself.
  * Finally, we call bus_put() to release the refcount
  */
-void bus_unregister(struct bus_type *bus)
+void bus_unregister(const struct bus_type *bus)
 {
 	struct subsys_private *sp = bus_to_subsys(bus);
 	struct kobject *bus_kobj;
diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h
index 425d79d6cf69..31be18608f83 100644
--- a/include/linux/device/bus.h
+++ b/include/linux/device/bus.h
@@ -114,7 +114,7 @@ struct bus_type {
 
 extern int __must_check bus_register(struct bus_type *bus);
 
-extern void bus_unregister(struct bus_type *bus);
+extern void bus_unregister(const struct bus_type *bus);
 
 extern int __must_check bus_rescan_devices(struct bus_type *bus);
 
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH 12/21] driver core: bus: bus iterator cleanups
  2023-02-08 11:13 ` [PATCH 12/21] driver core: bus: bus iterator cleanups Greg Kroah-Hartman
@ 2023-02-21 12:54   ` Geert Uytterhoeven
  0 siblings, 0 replies; 23+ messages in thread
From: Geert Uytterhoeven @ 2023-02-21 12:54 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: linux-kernel, Rafael J. Wysocki, Linux-Renesas

Hi Greg,

On Wed, Feb 8, 2023 at 12:15 PM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
> Convert the bus_for_each_dev(), bus_find_device, and bus_for_each_drv()
> functions to use bus_to_subsys() and not use the back-pointer to the
> private structure.
>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Thanks for your patch, which is now commit 83b9148df2c95e23 ("driver
core: bus: bus iterator cleanups") in driver-core-next.

I have bisected an early kernel crash on the Renesas Salvator-XS
board to this commit:

    Unable to handle kernel NULL pointer dereference at virtual
address 0000000000000028
    ...
    Call trace:
     __lock_acquire+0x530/0x20f0
     lock_acquire.part.0+0xc8/0x210
     lock_acquire+0x64/0x80
     _raw_spin_lock+0x4c/0x60
     bus_to_subsys+0x24/0xac
     bus_for_each_dev+0x30/0xcc
     soc_device_match+0x4c/0xe0
     r8a7795_sysc_init+0x18/0x60
     rcar_sysc_pd_init+0xb0/0x33c
     do_one_initcall+0x128/0x2bc

> --- a/drivers/base/bus.c
> +++ b/drivers/base/bus.c
> @@ -355,18 +355,20 @@ static struct device *next_device(struct klist_iter *i)
>  int bus_for_each_dev(const struct bus_type *bus, struct device *start,
>                      void *data, int (*fn)(struct device *, void *))
>  {
> +       struct subsys_private *sp = bus_to_subsys(bus);

If bus_to_subsys() is called from an early_initcall(), bus_kset is
still NULL, causing a crash.

>         struct klist_iter i;
>         struct device *dev;
>         int error = 0;
>
> -       if (!bus || !bus->p)

Before, the !bus->sp check prevented the crash...

> +       if (!sp)
>                 return -EINVAL;

... and instructed soc_device_match() to go into
early_soc_dev_attr mode.

I have sent a fix
"[PATCH] driver core: bus: Handle early calls to bus_to_subsys()"
https://lore.kernel.org/r/0a92979f6e790737544638e8a4c19b0564e660a2.1676983596.git.geert+renesas@glider.be

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2023-02-21 12:54 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-08 11:13 [PATCH 00/21] driver core: bus: remove private "backpointer" from struct bus_type Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 01/21] driver core: add local subsys_get and subsys_put functions Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 02/21] driver core: bus: implement bus_get/put() without the private pointer Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 03/21] driver core: bus: constantify the bus_find_* functions Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 04/21] driver core: bus: convert bus_create/remove_file to be constant Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 05/21] driver core: bus: sysfs function cleanups Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 06/21] driver core: bus: bus_add/probe/remove_device() cleanups Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 07/21] driver core: bus: bus_register/unregister() cleanups Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 08/21] driver core: bus: subsys_interface_register/unregister() cleanups Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 09/21] driver core: bus: bus_get_kset() cleanup Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 10/21] driver core: bus: bus_register/unregister_notifier() cleanups Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 11/21] driver core: bus: bus_add/remove_driver() cleanups Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 12/21] driver core: bus: bus iterator cleanups Greg Kroah-Hartman
2023-02-21 12:54   ` Geert Uytterhoeven
2023-02-08 11:13 ` [PATCH 13/21] driver core: bus: clean up bus_sort_breadthfirst() Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 14/21] driver core: move driver_find() to bus.c Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 15/21] driver core: bus: clean up driver_find() Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 16/21] driver core: create bus_is_registered() Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 17/21] driver core: remove private pointer from struct bus_type Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 18/21] driver core: bus: constify bus_register/unregister_notifier() Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 19/21] driver core: bus: constify bus_get_kset() Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 20/21] driver core: bus: constify some internal functions Greg Kroah-Hartman
2023-02-08 11:13 ` [PATCH 21/21] driver core: bus: constify bus_unregister() Greg Kroah-Hartman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.