mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2] driver core/ACPI: Introduce companion_bus_register()
@ 2026-09-09 16:41 Rafael J. Wysocki
  2026-09-16 18:45 ` Rafael J. Wysocki (Intel)
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Rafael J. Wysocki @ 2026-09-09 16:41 UTC (permalink / raw)
  To: Danilo Krummrich, Greg Kroah-Hartman
  Cc: Linux ACPI, LKML, Linux Driver Core Development

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

The ACPI bus type does not allow drivers to be registered, so the sysfs
attributes related to drivers created for it and its devices are
useless, and its drivers/ directory is always empty.  All of that is
confusing and wasteful.

To allow skipping the creation of those sysfs attributes, introduce a
"companion" bus type concept and add a special registration function for
registering "companion" bus types, companion_bus_register().

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

v1 -> v2:
   * Address Sashiko feedback regarding possible leaks of references in two
     places:

     https://sashiko.dev/#/patchset/8753121.T7Z3S40VBb%40rafael.j.wysocki

---
 drivers/acpi/bus.c         |    8 -----
 drivers/base/bus.c         |   72 ++++++++++++++++++++++++++++++++++-----------
 include/linux/device/bus.h |    1 
 3 files changed, 57 insertions(+), 24 deletions(-)

--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1120,11 +1120,6 @@ EXPORT_SYMBOL_GPL(acpi_driver_match_devi
                               ACPI Bus operations
    -------------------------------------------------------------------------- */
 
-static int acpi_bus_match(struct device *dev, const struct device_driver *drv)
-{
-	return 0;
-}
-
 static int acpi_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
 	return __acpi_device_uevent_modalias(to_acpi_device(dev), env);
@@ -1132,7 +1127,6 @@ static int acpi_device_uevent(const stru
 
 const struct bus_type acpi_bus_type = {
 	.name		= "acpi",
-	.match		= acpi_bus_match,
 	.uevent		= acpi_device_uevent,
 };
 
@@ -1451,7 +1445,7 @@ static int __init acpi_bus_init(void)
 	 */
 	acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
 
-	result = bus_register(&acpi_bus_type);
+	result = companion_bus_register(&acpi_bus_type);
 	if (!result)
 		return 0;
 
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -738,6 +738,11 @@ int bus_add_driver(struct device_driver
 	if (!sp)
 		return -EINVAL;
 
+	if (!sp->drivers_kset) {
+		error = -ENXIO;
+		goto out_put_bus;
+	}
+
 	/*
 	 * Reference in sp is now incremented and will be dropped when
 	 * the driver is removed from the bus
@@ -930,15 +935,7 @@ static ssize_t bus_uevent_store(const st
 static struct bus_attribute bus_attr_uevent = __ATTR(uevent, 0200, NULL,
 						     bus_uevent_store);
 
-/**
- * bus_register - register a driver-core subsystem
- * @bus: bus to register
- *
- * Once we have that, we register the bus with the kobject
- * infrastructure, then register the children subsystems it has:
- * the devices and drivers that belong to the subsystem.
- */
-int bus_register(const struct bus_type *bus)
+static int bus_register_internal(const struct bus_type *bus, bool use_drivers)
 {
 	int retval;
 	struct subsys_private *priv;
@@ -960,7 +957,7 @@ int bus_register(const struct bus_type *
 
 	bus_kobj->kset = bus_kset;
 	bus_kobj->ktype = &bus_ktype;
-	priv->drivers_autoprobe = 1;
+	priv->drivers_autoprobe = use_drivers;
 
 	retval = kset_register(&priv->subsys);
 	if (retval)
@@ -976,10 +973,12 @@ int bus_register(const struct bus_type *
 		goto bus_devices_fail;
 	}
 
-	priv->drivers_kset = kset_create_and_add("drivers", NULL, bus_kobj);
-	if (!priv->drivers_kset) {
-		retval = -ENOMEM;
-		goto bus_drivers_fail;
+	if (use_drivers) {
+		priv->drivers_kset = kset_create_and_add("drivers", NULL, bus_kobj);
+		if (!priv->drivers_kset) {
+			retval = -ENOMEM;
+			goto bus_drivers_fail;
+		}
 	}
 
 	INIT_LIST_HEAD(&priv->interfaces);
@@ -989,9 +988,11 @@ int bus_register(const struct bus_type *
 	klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
 	klist_init(&priv->klist_drivers, NULL, NULL);
 
-	retval = add_probe_files(bus);
-	if (retval)
-		goto bus_probe_files_fail;
+	if (use_drivers) {
+		retval = add_probe_files(bus);
+		if (retval)
+			goto bus_probe_files_fail;
+	}
 
 	retval = sysfs_create_groups(bus_kobj, bus->bus_groups);
 	if (retval)
@@ -1016,9 +1017,41 @@ out:
 	kfree(priv);
 	return retval;
 }
+
+/**
+ * bus_register - register a driver-core subsystem
+ * @bus: bus to register
+ *
+ * Once we have that, we register the bus with the kobject
+ * infrastructure, then register the children subsystems it has:
+ * the devices and drivers that belong to the subsystem.
+ */
+int bus_register(const struct bus_type *bus)
+{
+	return bus_register_internal(bus, true);
+}
 EXPORT_SYMBOL_GPL(bus_register);
 
 /**
+ * companion_bus_register - register a companion bus type
+ * @bus: companion bus to register
+ *
+ * A companion bus is a bus without drivers.  Devices that belong to it can be
+ * bound to other devices as their "companions" and represent interfaces that
+ * can be used by the drivers of those other devices.  They may also be used for
+ * the enumeration of those other devices.
+ *
+ * The ACPI bus is a specific example of a companion bus.
+ *
+ * Registering a companion bus is like registering a regular bus except that it
+ * skips the creation of sysfs interfaces related to drivers for @bus.
+ */
+int companion_bus_register(const struct bus_type *bus)
+{
+	return bus_register_internal(bus, false);
+}
+
+/**
  * bus_unregister - remove a bus from the system
  * @bus: bus.
  *
@@ -1415,6 +1448,11 @@ struct device_driver *driver_find(const
 	if (!sp)
 		return NULL;
 
+	if (!sp->drivers_kset) {
+		subsys_put(sp);
+		return NULL;
+	}
+
 	k = kset_find_obj(sp->drivers_kset, name);
 	subsys_put(sp);
 	if (!k)
--- a/include/linux/device/bus.h
+++ b/include/linux/device/bus.h
@@ -113,6 +113,7 @@ struct bus_type {
 	bool need_parent_lock;
 };
 
+int __must_check companion_bus_register(const struct bus_type *bus);
 int __must_check bus_register(const struct bus_type *bus);
 
 void bus_unregister(const struct bus_type *bus);




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

* Re: [PATCH v2] driver core/ACPI: Introduce companion_bus_register()
  2026-09-09 16:41 [PATCH v2] driver core/ACPI: Introduce companion_bus_register() Rafael J. Wysocki
@ 2026-09-16 18:45 ` Rafael J. Wysocki (Intel)
  2026-09-16 18:52   ` Greg Kroah-Hartman
  2026-09-16 18:51 ` Danilo Krummrich
  2026-09-23 17:05 ` Michael Kelley
  2 siblings, 1 reply; 14+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-09-16 18:45 UTC (permalink / raw)
  To: Danilo Krummrich, Greg Kroah-Hartman
  Cc: Linux ACPI, LKML, Linux Driver Core Development

On Wed, Sep 9, 2026 at 6:41 PM Rafael J. Wysocki <rafael@kernel.org> wrote:
>
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> The ACPI bus type does not allow drivers to be registered, so the sysfs
> attributes related to drivers created for it and its devices are
> useless, and its drivers/ directory is always empty.  All of that is
> confusing and wasteful.
>
> To allow skipping the creation of those sysfs attributes, introduce a
> "companion" bus type concept and add a special registration function for
> registering "companion" bus types, companion_bus_register().
>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

It's been a while since this was posted, so any feedback would be appreciated.

In the absence thereof, I'll trust Sashiko that there are no issues
with it and pick it up.

Thanks!

> ---
>
> v1 -> v2:
>    * Address Sashiko feedback regarding possible leaks of references in two
>      places:
>
>      https://sashiko.dev/#/patchset/8753121.T7Z3S40VBb%40rafael.j.wysocki
>
> ---
>  drivers/acpi/bus.c         |    8 -----
>  drivers/base/bus.c         |   72 ++++++++++++++++++++++++++++++++++-----------
>  include/linux/device/bus.h |    1
>  3 files changed, 57 insertions(+), 24 deletions(-)
>
> --- a/drivers/acpi/bus.c
> +++ b/drivers/acpi/bus.c
> @@ -1120,11 +1120,6 @@ EXPORT_SYMBOL_GPL(acpi_driver_match_devi
>                                ACPI Bus operations
>     -------------------------------------------------------------------------- */
>
> -static int acpi_bus_match(struct device *dev, const struct device_driver *drv)
> -{
> -       return 0;
> -}
> -
>  static int acpi_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
>         return __acpi_device_uevent_modalias(to_acpi_device(dev), env);
> @@ -1132,7 +1127,6 @@ static int acpi_device_uevent(const stru
>
>  const struct bus_type acpi_bus_type = {
>         .name           = "acpi",
> -       .match          = acpi_bus_match,
>         .uevent         = acpi_device_uevent,
>  };
>
> @@ -1451,7 +1445,7 @@ static int __init acpi_bus_init(void)
>          */
>         acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
>
> -       result = bus_register(&acpi_bus_type);
> +       result = companion_bus_register(&acpi_bus_type);
>         if (!result)
>                 return 0;
>
> --- a/drivers/base/bus.c
> +++ b/drivers/base/bus.c
> @@ -738,6 +738,11 @@ int bus_add_driver(struct device_driver
>         if (!sp)
>                 return -EINVAL;
>
> +       if (!sp->drivers_kset) {
> +               error = -ENXIO;
> +               goto out_put_bus;
> +       }
> +
>         /*
>          * Reference in sp is now incremented and will be dropped when
>          * the driver is removed from the bus
> @@ -930,15 +935,7 @@ static ssize_t bus_uevent_store(const st
>  static struct bus_attribute bus_attr_uevent = __ATTR(uevent, 0200, NULL,
>                                                      bus_uevent_store);
>
> -/**
> - * bus_register - register a driver-core subsystem
> - * @bus: bus to register
> - *
> - * Once we have that, we register the bus with the kobject
> - * infrastructure, then register the children subsystems it has:
> - * the devices and drivers that belong to the subsystem.
> - */
> -int bus_register(const struct bus_type *bus)
> +static int bus_register_internal(const struct bus_type *bus, bool use_drivers)
>  {
>         int retval;
>         struct subsys_private *priv;
> @@ -960,7 +957,7 @@ int bus_register(const struct bus_type *
>
>         bus_kobj->kset = bus_kset;
>         bus_kobj->ktype = &bus_ktype;
> -       priv->drivers_autoprobe = 1;
> +       priv->drivers_autoprobe = use_drivers;
>
>         retval = kset_register(&priv->subsys);
>         if (retval)
> @@ -976,10 +973,12 @@ int bus_register(const struct bus_type *
>                 goto bus_devices_fail;
>         }
>
> -       priv->drivers_kset = kset_create_and_add("drivers", NULL, bus_kobj);
> -       if (!priv->drivers_kset) {
> -               retval = -ENOMEM;
> -               goto bus_drivers_fail;
> +       if (use_drivers) {
> +               priv->drivers_kset = kset_create_and_add("drivers", NULL, bus_kobj);
> +               if (!priv->drivers_kset) {
> +                       retval = -ENOMEM;
> +                       goto bus_drivers_fail;
> +               }
>         }
>
>         INIT_LIST_HEAD(&priv->interfaces);
> @@ -989,9 +988,11 @@ int bus_register(const struct bus_type *
>         klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
>         klist_init(&priv->klist_drivers, NULL, NULL);
>
> -       retval = add_probe_files(bus);
> -       if (retval)
> -               goto bus_probe_files_fail;
> +       if (use_drivers) {
> +               retval = add_probe_files(bus);
> +               if (retval)
> +                       goto bus_probe_files_fail;
> +       }
>
>         retval = sysfs_create_groups(bus_kobj, bus->bus_groups);
>         if (retval)
> @@ -1016,9 +1017,41 @@ out:
>         kfree(priv);
>         return retval;
>  }
> +
> +/**
> + * bus_register - register a driver-core subsystem
> + * @bus: bus to register
> + *
> + * Once we have that, we register the bus with the kobject
> + * infrastructure, then register the children subsystems it has:
> + * the devices and drivers that belong to the subsystem.
> + */
> +int bus_register(const struct bus_type *bus)
> +{
> +       return bus_register_internal(bus, true);
> +}
>  EXPORT_SYMBOL_GPL(bus_register);
>
>  /**
> + * companion_bus_register - register a companion bus type
> + * @bus: companion bus to register
> + *
> + * A companion bus is a bus without drivers.  Devices that belong to it can be
> + * bound to other devices as their "companions" and represent interfaces that
> + * can be used by the drivers of those other devices.  They may also be used for
> + * the enumeration of those other devices.
> + *
> + * The ACPI bus is a specific example of a companion bus.
> + *
> + * Registering a companion bus is like registering a regular bus except that it
> + * skips the creation of sysfs interfaces related to drivers for @bus.
> + */
> +int companion_bus_register(const struct bus_type *bus)
> +{
> +       return bus_register_internal(bus, false);
> +}
> +
> +/**
>   * bus_unregister - remove a bus from the system
>   * @bus: bus.
>   *
> @@ -1415,6 +1448,11 @@ struct device_driver *driver_find(const
>         if (!sp)
>                 return NULL;
>
> +       if (!sp->drivers_kset) {
> +               subsys_put(sp);
> +               return NULL;
> +       }
> +
>         k = kset_find_obj(sp->drivers_kset, name);
>         subsys_put(sp);
>         if (!k)
> --- a/include/linux/device/bus.h
> +++ b/include/linux/device/bus.h
> @@ -113,6 +113,7 @@ struct bus_type {
>         bool need_parent_lock;
>  };
>
> +int __must_check companion_bus_register(const struct bus_type *bus);
>  int __must_check bus_register(const struct bus_type *bus);
>
>  void bus_unregister(const struct bus_type *bus);
>
>
>
>

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

* Re: [PATCH v2] driver core/ACPI: Introduce companion_bus_register()
  2026-09-09 16:41 [PATCH v2] driver core/ACPI: Introduce companion_bus_register() Rafael J. Wysocki
  2026-09-16 18:45 ` Rafael J. Wysocki (Intel)
@ 2026-09-16 18:51 ` Danilo Krummrich
  2026-09-23 17:05 ` Michael Kelley
  2 siblings, 0 replies; 14+ messages in thread
From: Danilo Krummrich @ 2026-09-16 18:51 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Greg Kroah-Hartman, Linux ACPI, LKML, Linux Driver Core Development

On 9/9/26 6:41 PM, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> The ACPI bus type does not allow drivers to be registered, so the sysfs
> attributes related to drivers created for it and its devices are
> useless, and its drivers/ directory is always empty.  All of that is
> confusing and wasteful.
> 
> To allow skipping the creation of those sysfs attributes, introduce a
> "companion" bus type concept and add a special registration function for
> registering "companion" bus types, companion_bus_register().
> 
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


Reviewed-by: Danilo Krummrich <dakr@kernel.org>


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

* Re: [PATCH v2] driver core/ACPI: Introduce companion_bus_register()
  2026-09-16 18:45 ` Rafael J. Wysocki (Intel)
@ 2026-09-16 18:52   ` Greg Kroah-Hartman
  0 siblings, 0 replies; 14+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-16 18:52 UTC (permalink / raw)
  To: Rafael J. Wysocki (Intel)
  Cc: Danilo Krummrich, Linux ACPI, LKML, Linux Driver Core Development

On Wed, Sep 16, 2026 at 08:45:50PM +0200, Rafael J. Wysocki (Intel) wrote:
> On Wed, Sep 9, 2026 at 6:41 PM Rafael J. Wysocki <rafael@kernel.org> wrote:
> >
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > The ACPI bus type does not allow drivers to be registered, so the sysfs
> > attributes related to drivers created for it and its devices are
> > useless, and its drivers/ directory is always empty.  All of that is
> > confusing and wasteful.
> >
> > To allow skipping the creation of those sysfs attributes, introduce a
> > "companion" bus type concept and add a special registration function for
> > registering "companion" bus types, companion_bus_register().
> >
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> It's been a while since this was posted, so any feedback would be appreciated.
> 
> In the absence thereof, I'll trust Sashiko that there are no issues
> with it and pick it up.

Looks sane:

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

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

* RE: [PATCH v2] driver core/ACPI: Introduce companion_bus_register()
  2026-09-09 16:41 [PATCH v2] driver core/ACPI: Introduce companion_bus_register() Rafael J. Wysocki
  2026-09-16 18:45 ` Rafael J. Wysocki (Intel)
  2026-09-16 18:51 ` Danilo Krummrich
@ 2026-09-23 17:05 ` Michael Kelley
  2026-09-23 17:32   ` Rafael J. Wysocki (Intel)
  2026-09-24 18:23   ` Michael Kelley
  2 siblings, 2 replies; 14+ messages in thread
From: Michael Kelley @ 2026-09-23 17:05 UTC (permalink / raw)
  To: Rafael J. Wysocki, Danilo Krummrich, Greg Kroah-Hartman,
	Linux on Hyper-V List
  Cc: Linux ACPI, LKML, Linux Driver Core Development

From: Rafael J. Wysocki <rafael@kernel.org> Sent: Wednesday, September 9, 2026 9:41 AM
> 
> The ACPI bus type does not allow drivers to be registered, so the sysfs
> attributes related to drivers created for it and its devices are
> useless, and its drivers/ directory is always empty.  All of that is
> confusing and wasteful.
> 
> To allow skipping the creation of those sysfs attributes, introduce a
> "companion" bus type concept and add a special registration function for
> registering "companion" bus types, companion_bus_register().
> 
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

As a heads up, this patch breaks Linux guests booting on Hyper-V.
Something goes wrong in the VMBus driver getting loaded and
initialized (drivers/hv/vmbus_drv.c). It may be that the VMBus
driver is doing something wrong or making an invalid assumption.
I'll debug the problem today or tomorrow, but any insight you can
offer would be appreciated. I'm working with linux-next20260921.

Michael

> ---
> 
> v1 -> v2:
>    * Address Sashiko feedback regarding possible leaks of references in two
>      places:
> 
>      https://sashiko.dev/#/patchset/8753121.T7Z3S40VBb%40rafael.j.wysocki
> 
> ---
>  drivers/acpi/bus.c         |    8 -----
>  drivers/base/bus.c         |   72 ++++++++++++++++++++++++++++++++++-----------
>  include/linux/device/bus.h |    1
>  3 files changed, 57 insertions(+), 24 deletions(-)
> 
> --- a/drivers/acpi/bus.c
> +++ b/drivers/acpi/bus.c
> @@ -1120,11 +1120,6 @@ EXPORT_SYMBOL_GPL(acpi_driver_match_devi
>                                ACPI Bus operations
>     -------------------------------------------------------------------------- */
> 
> -static int acpi_bus_match(struct device *dev, const struct device_driver *drv)
> -{
> -	return 0;
> -}
> -
>  static int acpi_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
>  	return __acpi_device_uevent_modalias(to_acpi_device(dev), env);
> @@ -1132,7 +1127,6 @@ static int acpi_device_uevent(const stru
> 
>  const struct bus_type acpi_bus_type = {
>  	.name		= "acpi",
> -	.match		= acpi_bus_match,
>  	.uevent		= acpi_device_uevent,
>  };
> 
> @@ -1451,7 +1445,7 @@ static int __init acpi_bus_init(void)
>  	 */
>  	acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
> 
> -	result = bus_register(&acpi_bus_type);
> +	result = companion_bus_register(&acpi_bus_type);
>  	if (!result)
>  		return 0;
> 
> --- a/drivers/base/bus.c
> +++ b/drivers/base/bus.c
> @@ -738,6 +738,11 @@ int bus_add_driver(struct device_driver
>  	if (!sp)
>  		return -EINVAL;
> 
> +	if (!sp->drivers_kset) {
> +		error = -ENXIO;
> +		goto out_put_bus;
> +	}
> +
>  	/*
>  	 * Reference in sp is now incremented and will be dropped when
>  	 * the driver is removed from the bus
> @@ -930,15 +935,7 @@ static ssize_t bus_uevent_store(const st
>  static struct bus_attribute bus_attr_uevent = __ATTR(uevent, 0200, NULL,
>  						     bus_uevent_store);
> 
> -/**
> - * bus_register - register a driver-core subsystem
> - * @bus: bus to register
> - *
> - * Once we have that, we register the bus with the kobject
> - * infrastructure, then register the children subsystems it has:
> - * the devices and drivers that belong to the subsystem.
> - */
> -int bus_register(const struct bus_type *bus)
> +static int bus_register_internal(const struct bus_type *bus, bool use_drivers)
>  {
>  	int retval;
>  	struct subsys_private *priv;
> @@ -960,7 +957,7 @@ int bus_register(const struct bus_type *
> 
>  	bus_kobj->kset = bus_kset;
>  	bus_kobj->ktype = &bus_ktype;
> -	priv->drivers_autoprobe = 1;
> +	priv->drivers_autoprobe = use_drivers;
> 
>  	retval = kset_register(&priv->subsys);
>  	if (retval)
> @@ -976,10 +973,12 @@ int bus_register(const struct bus_type *
>  		goto bus_devices_fail;
>  	}
> 
> -	priv->drivers_kset = kset_create_and_add("drivers", NULL, bus_kobj);
> -	if (!priv->drivers_kset) {
> -		retval = -ENOMEM;
> -		goto bus_drivers_fail;
> +	if (use_drivers) {
> +		priv->drivers_kset = kset_create_and_add("drivers", NULL, bus_kobj);
> +		if (!priv->drivers_kset) {
> +			retval = -ENOMEM;
> +			goto bus_drivers_fail;
> +		}
>  	}
> 
>  	INIT_LIST_HEAD(&priv->interfaces);
> @@ -989,9 +988,11 @@ int bus_register(const struct bus_type *
>  	klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
>  	klist_init(&priv->klist_drivers, NULL, NULL);
> 
> -	retval = add_probe_files(bus);
> -	if (retval)
> -		goto bus_probe_files_fail;
> +	if (use_drivers) {
> +		retval = add_probe_files(bus);
> +		if (retval)
> +			goto bus_probe_files_fail;
> +	}
> 
>  	retval = sysfs_create_groups(bus_kobj, bus->bus_groups);
>  	if (retval)
> @@ -1016,9 +1017,41 @@ out:
>  	kfree(priv);
>  	return retval;
>  }
> +
> +/**
> + * bus_register - register a driver-core subsystem
> + * @bus: bus to register
> + *
> + * Once we have that, we register the bus with the kobject
> + * infrastructure, then register the children subsystems it has:
> + * the devices and drivers that belong to the subsystem.
> + */
> +int bus_register(const struct bus_type *bus)
> +{
> +	return bus_register_internal(bus, true);
> +}
>  EXPORT_SYMBOL_GPL(bus_register);
> 
>  /**
> + * companion_bus_register - register a companion bus type
> + * @bus: companion bus to register
> + *
> + * A companion bus is a bus without drivers.  Devices that belong to it can be
> + * bound to other devices as their "companions" and represent interfaces that
> + * can be used by the drivers of those other devices.  They may also be used for
> + * the enumeration of those other devices.
> + *
> + * The ACPI bus is a specific example of a companion bus.
> + *
> + * Registering a companion bus is like registering a regular bus except that it
> + * skips the creation of sysfs interfaces related to drivers for @bus.
> + */
> +int companion_bus_register(const struct bus_type *bus)
> +{
> +	return bus_register_internal(bus, false);
> +}
> +
> +/**
>   * bus_unregister - remove a bus from the system
>   * @bus: bus.
>   *
> @@ -1415,6 +1448,11 @@ struct device_driver *driver_find(const
>  	if (!sp)
>  		return NULL;
> 
> +	if (!sp->drivers_kset) {
> +		subsys_put(sp);
> +		return NULL;
> +	}
> +
>  	k = kset_find_obj(sp->drivers_kset, name);
>  	subsys_put(sp);
>  	if (!k)
> --- a/include/linux/device/bus.h
> +++ b/include/linux/device/bus.h
> @@ -113,6 +113,7 @@ struct bus_type {
>  	bool need_parent_lock;
>  };
> 
> +int __must_check companion_bus_register(const struct bus_type *bus);
>  int __must_check bus_register(const struct bus_type *bus);
> 
>  void bus_unregister(const struct bus_type *bus);
> 
> 
> 


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

* Re: [PATCH v2] driver core/ACPI: Introduce companion_bus_register()
  2026-09-23 17:05 ` Michael Kelley
@ 2026-09-23 17:32   ` Rafael J. Wysocki (Intel)
  2026-09-23 18:31     ` Rafael J. Wysocki (Intel)
  2026-09-24 18:23   ` Michael Kelley
  1 sibling, 1 reply; 14+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-09-23 17:32 UTC (permalink / raw)
  To: Michael Kelley
  Cc: Rafael J. Wysocki, Danilo Krummrich, Greg Kroah-Hartman,
	Linux on Hyper-V List, Linux ACPI, LKML,
	Linux Driver Core Development

On Wed, Sep 23, 2026 at 7:06 PM Michael Kelley <mhklinux@outlook.com> wrote:
>
> From: Rafael J. Wysocki <rafael@kernel.org> Sent: Wednesday, September 9, 2026 9:41 AM
> >
> > The ACPI bus type does not allow drivers to be registered, so the sysfs
> > attributes related to drivers created for it and its devices are
> > useless, and its drivers/ directory is always empty.  All of that is
> > confusing and wasteful.
> >
> > To allow skipping the creation of those sysfs attributes, introduce a
> > "companion" bus type concept and add a special registration function for
> > registering "companion" bus types, companion_bus_register().
> >
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> As a heads up, this patch breaks Linux guests booting on Hyper-V.
> Something goes wrong in the VMBus driver getting loaded and
> initialized (drivers/hv/vmbus_drv.c).

This patch doesn't affect anything except for bus registration and
driver addition and lookup for the ACPI bus type.

> It may be that the VMBus
> driver is doing something wrong or making an invalid assumption.
> I'll debug the problem today or tomorrow, but any insight you can
> offer would be appreciated. I'm working with linux-next20260921.

No idea what's going on.

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

* Re: [PATCH v2] driver core/ACPI: Introduce companion_bus_register()
  2026-09-23 17:32   ` Rafael J. Wysocki (Intel)
@ 2026-09-23 18:31     ` Rafael J. Wysocki (Intel)
  2026-09-23 18:50       ` Rafael J. Wysocki (Intel)
  0 siblings, 1 reply; 14+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-09-23 18:31 UTC (permalink / raw)
  To: Michael Kelley
  Cc: Danilo Krummrich, Greg Kroah-Hartman, Linux on Hyper-V List,
	Linux ACPI, LKML, Linux Driver Core Development

On Wed, Sep 23, 2026 at 7:32 PM Rafael J. Wysocki (Intel)
<rafael@kernel.org> wrote:
>
> On Wed, Sep 23, 2026 at 7:06 PM Michael Kelley <mhklinux@outlook.com> wrote:
> >
> > From: Rafael J. Wysocki <rafael@kernel.org> Sent: Wednesday, September 9, 2026 9:41 AM
> > >
> > > The ACPI bus type does not allow drivers to be registered, so the sysfs
> > > attributes related to drivers created for it and its devices are
> > > useless, and its drivers/ directory is always empty.  All of that is
> > > confusing and wasteful.
> > >
> > > To allow skipping the creation of those sysfs attributes, introduce a
> > > "companion" bus type concept and add a special registration function for
> > > registering "companion" bus types, companion_bus_register().
> > >
> > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > As a heads up, this patch breaks Linux guests booting on Hyper-V.
> > Something goes wrong in the VMBus driver getting loaded and
> > initialized (drivers/hv/vmbus_drv.c).
>
> This patch doesn't affect anything except for bus registration and
> driver addition and lookup for the ACPI bus type.
>
> > It may be that the VMBus
> > driver is doing something wrong or making an invalid assumption.
> > I'll debug the problem today or tomorrow, but any insight you can
> > offer would be appreciated. I'm working with linux-next20260921.
>
> No idea what's going on.

Actually, you may try to restore the stub .match() callback for
acpi_bus_type because the lack of it causes 1 to be returned by
driver_match_device(), so if any driver points to acpi_bus_type as its
bus by mistake, the check will now succeed.

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

* Re: [PATCH v2] driver core/ACPI: Introduce companion_bus_register()
  2026-09-23 18:31     ` Rafael J. Wysocki (Intel)
@ 2026-09-23 18:50       ` Rafael J. Wysocki (Intel)
  2026-09-23 19:11         ` Rafael J. Wysocki (Intel)
  0 siblings, 1 reply; 14+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-09-23 18:50 UTC (permalink / raw)
  To: Michael Kelley
  Cc: Danilo Krummrich, Greg Kroah-Hartman, Linux on Hyper-V List,
	Linux ACPI, LKML, Linux Driver Core Development

On Wed, Sep 23, 2026 at 8:31 PM Rafael J. Wysocki (Intel)
<rafael@kernel.org> wrote:
>
> On Wed, Sep 23, 2026 at 7:32 PM Rafael J. Wysocki (Intel)
> <rafael@kernel.org> wrote:
> >
> > On Wed, Sep 23, 2026 at 7:06 PM Michael Kelley <mhklinux@outlook.com> wrote:
> > >
> > > From: Rafael J. Wysocki <rafael@kernel.org> Sent: Wednesday, September 9, 2026 9:41 AM
> > > >
> > > > The ACPI bus type does not allow drivers to be registered, so the sysfs
> > > > attributes related to drivers created for it and its devices are
> > > > useless, and its drivers/ directory is always empty.  All of that is
> > > > confusing and wasteful.
> > > >
> > > > To allow skipping the creation of those sysfs attributes, introduce a
> > > > "companion" bus type concept and add a special registration function for
> > > > registering "companion" bus types, companion_bus_register().
> > > >
> > > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > >
> > > As a heads up, this patch breaks Linux guests booting on Hyper-V.
> > > Something goes wrong in the VMBus driver getting loaded and
> > > initialized (drivers/hv/vmbus_drv.c).
> >
> > This patch doesn't affect anything except for bus registration and
> > driver addition and lookup for the ACPI bus type.
> >
> > > It may be that the VMBus
> > > driver is doing something wrong or making an invalid assumption.
> > > I'll debug the problem today or tomorrow, but any insight you can
> > > offer would be appreciated. I'm working with linux-next20260921.
> >
> > No idea what's going on.
>
> Actually, you may try to restore the stub .match() callback for
> acpi_bus_type because the lack of it causes 1 to be returned by
> driver_match_device(), so if any driver points to acpi_bus_type as its
> bus by mistake, the check will now succeed.

Which shouldn't matter though because driver_match_device() is only
called in 3 places and none of them is reachable for acpi_bus_type
after the $subject patch AFAICS.

So still no idea what can be going on, sorry.

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

* Re: [PATCH v2] driver core/ACPI: Introduce companion_bus_register()
  2026-09-23 18:50       ` Rafael J. Wysocki (Intel)
@ 2026-09-23 19:11         ` Rafael J. Wysocki (Intel)
  0 siblings, 0 replies; 14+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-09-23 19:11 UTC (permalink / raw)
  To: Michael Kelley
  Cc: Danilo Krummrich, Greg Kroah-Hartman, Linux on Hyper-V List,
	Linux ACPI, LKML, Linux Driver Core Development

On Wed, Sep 23, 2026 at 8:50 PM Rafael J. Wysocki (Intel)
<rafael@kernel.org> wrote:
>
> On Wed, Sep 23, 2026 at 8:31 PM Rafael J. Wysocki (Intel)
> <rafael@kernel.org> wrote:
> >
> > On Wed, Sep 23, 2026 at 7:32 PM Rafael J. Wysocki (Intel)
> > <rafael@kernel.org> wrote:
> > >
> > > On Wed, Sep 23, 2026 at 7:06 PM Michael Kelley <mhklinux@outlook.com> wrote:
> > > >
> > > > From: Rafael J. Wysocki <rafael@kernel.org> Sent: Wednesday, September 9, 2026 9:41 AM
> > > > >
> > > > > The ACPI bus type does not allow drivers to be registered, so the sysfs
> > > > > attributes related to drivers created for it and its devices are
> > > > > useless, and its drivers/ directory is always empty.  All of that is
> > > > > confusing and wasteful.
> > > > >
> > > > > To allow skipping the creation of those sysfs attributes, introduce a
> > > > > "companion" bus type concept and add a special registration function for
> > > > > registering "companion" bus types, companion_bus_register().
> > > > >
> > > > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > > >
> > > > As a heads up, this patch breaks Linux guests booting on Hyper-V.
> > > > Something goes wrong in the VMBus driver getting loaded and
> > > > initialized (drivers/hv/vmbus_drv.c).
> > >
> > > This patch doesn't affect anything except for bus registration and
> > > driver addition and lookup for the ACPI bus type.
> > >
> > > > It may be that the VMBus
> > > > driver is doing something wrong or making an invalid assumption.
> > > > I'll debug the problem today or tomorrow, but any insight you can
> > > > offer would be appreciated. I'm working with linux-next20260921.
> > >
> > > No idea what's going on.
> >
> > Actually, you may try to restore the stub .match() callback for
> > acpi_bus_type because the lack of it causes 1 to be returned by
> > driver_match_device(), so if any driver points to acpi_bus_type as its
> > bus by mistake, the check will now succeed.
>
> Which shouldn't matter though because driver_match_device() is only
> called in 3 places and none of them is reachable for acpi_bus_type
> after the $subject patch AFAICS.

Well, not quite.

If a driver with an incorrect bus is passed to driver_attach(), it
will iterate over devices on that bus and call __driver_attach() for
each of them.  If driver_match_device() succeeds then, the device will
be passed to driver_probe_device() and it will not be good.

So it may be worth checking after all.

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

* RE: [PATCH v2] driver core/ACPI: Introduce companion_bus_register()
  2026-09-23 17:05 ` Michael Kelley
  2026-09-23 17:32   ` Rafael J. Wysocki (Intel)
@ 2026-09-24 18:23   ` Michael Kelley
  2026-09-24 18:44     ` Rafael J. Wysocki (Intel)
  1 sibling, 1 reply; 14+ messages in thread
From: Michael Kelley @ 2026-09-24 18:23 UTC (permalink / raw)
  To: Rafael J. Wysocki, Danilo Krummrich, Greg Kroah-Hartman,
	Linux on Hyper-V List
  Cc: Linux ACPI, LKML, Linux Driver Core Development

From: Michael Kelley <mhklinux@outlook.com> Sent: Wednesday, September 23, 2026 10:06 AM
> 
> From: Rafael J. Wysocki <rafael@kernel.org> Sent: Wednesday, September 9, 2026 9:41 AM
> >
> > The ACPI bus type does not allow drivers to be registered, so the sysfs
> > attributes related to drivers created for it and its devices are
> > useless, and its drivers/ directory is always empty.  All of that is
> > confusing and wasteful.
> >
> > To allow skipping the creation of those sysfs attributes, introduce a
> > "companion" bus type concept and add a special registration function for
> > registering "companion" bus types, companion_bus_register().
> >
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> As a heads up, this patch breaks Linux guests booting on Hyper-V.
> Something goes wrong in the VMBus driver getting loaded and
> initialized (drivers/hv/vmbus_drv.c). It may be that the VMBus
> driver is doing something wrong or making an invalid assumption.
> I'll debug the problem today or tomorrow, but any insight you can
> offer would be appreciated. I'm working with linux-next20260921.

Here's what I've learned so far:

1) The problem is apparently due to systemd-udevd being unable
to load modules with the VMBus bus driver or any of the
individual drivers for VMBus devices.

2) I'm testing on Ubuntu 20.04 with systemd version 245. The
problem reproduces on a different 20.04 instance. But everything
works correctly on Ubuntu 24.04 with systemd version 255.

3) If the VMBus bus driver and key VMBus device drivers are
compiled as built-in instead of as modules, the Ubuntu 20.04 system
will boot.

4) If I keep your patch, but change companion_bus_register() to 
pass "true" as the second argument instead of "false", then the
/sys/bus/acpi/drivers directory is created as before, and everything
works. Also, only adding back the .match function as you suggested
does not make any difference.

5) The VMBus bus is enumerated in the ACPI DSDT. The individual
synthetic devices that are logically on VMBus are not -- they are
"offered" by Hyper-V to the guest at runtime via a custom protocol.
The synthetic devices end up with paths like:

/sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0004:00/MSFT1000:00/<some GUID>

My conclusion is that for some reason, the older system-udevd has
a dependency on the /sys/bus/acpi/drivers directory being present.
This isn't a kernel problem per se, but there's an implicit ABI of sorts
that assumes the existence of the "drivers" directory.

To confirm all this more precisely, I'm trying to find a clever way
to get an strace of systemd-udevd when it errors out due to the
missing "drivers" directory, and somehow relate that back to the
git history of systemd-udevd.

Thoughts?

Michael

> > ---
> >
> > v1 -> v2:
> >    * Address Sashiko feedback regarding possible leaks of references in two
> >      places:
> >
> >      https://sashiko.dev/#/patchset/8753121.T7Z3S40VBb%40rafael.j.wysocki
> >
> > ---
> >  drivers/acpi/bus.c         |    8 -----
> >  drivers/base/bus.c         |   72 ++++++++++++++++++++++++++++++++++-----------
> >  include/linux/device/bus.h |    1
> >  3 files changed, 57 insertions(+), 24 deletions(-)
> >
> > --- a/drivers/acpi/bus.c
> > +++ b/drivers/acpi/bus.c
> > @@ -1120,11 +1120,6 @@ EXPORT_SYMBOL_GPL(acpi_driver_match_devi
> >                                ACPI Bus operations
> >     -------------------------------------------------------------------------- */
> >
> > -static int acpi_bus_match(struct device *dev, const struct device_driver *drv)
> > -{
> > -	return 0;
> > -}
> > -
> >  static int acpi_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
> >  {
> >  	return __acpi_device_uevent_modalias(to_acpi_device(dev), env);
> > @@ -1132,7 +1127,6 @@ static int acpi_device_uevent(const stru
> >
> >  const struct bus_type acpi_bus_type = {
> >  	.name		= "acpi",
> > -	.match		= acpi_bus_match,
> >  	.uevent		= acpi_device_uevent,
> >  };
> >
> > @@ -1451,7 +1445,7 @@ static int __init acpi_bus_init(void)
> >  	 */
> >  	acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
> >
> > -	result = bus_register(&acpi_bus_type);
> > +	result = companion_bus_register(&acpi_bus_type);
> >  	if (!result)
> >  		return 0;
> >
> > --- a/drivers/base/bus.c
> > +++ b/drivers/base/bus.c
> > @@ -738,6 +738,11 @@ int bus_add_driver(struct device_driver
> >  	if (!sp)
> >  		return -EINVAL;
> >
> > +	if (!sp->drivers_kset) {
> > +		error = -ENXIO;
> > +		goto out_put_bus;
> > +	}
> > +
> >  	/*
> >  	 * Reference in sp is now incremented and will be dropped when
> >  	 * the driver is removed from the bus
> > @@ -930,15 +935,7 @@ static ssize_t bus_uevent_store(const st
> >  static struct bus_attribute bus_attr_uevent = __ATTR(uevent, 0200, NULL,
> >  						     bus_uevent_store);
> >
> > -/**
> > - * bus_register - register a driver-core subsystem
> > - * @bus: bus to register
> > - *
> > - * Once we have that, we register the bus with the kobject
> > - * infrastructure, then register the children subsystems it has:
> > - * the devices and drivers that belong to the subsystem.
> > - */
> > -int bus_register(const struct bus_type *bus)
> > +static int bus_register_internal(const struct bus_type *bus, bool use_drivers)
> >  {
> >  	int retval;
> >  	struct subsys_private *priv;
> > @@ -960,7 +957,7 @@ int bus_register(const struct bus_type *
> >
> >  	bus_kobj->kset = bus_kset;
> >  	bus_kobj->ktype = &bus_ktype;
> > -	priv->drivers_autoprobe = 1;
> > +	priv->drivers_autoprobe = use_drivers;
> >
> >  	retval = kset_register(&priv->subsys);
> >  	if (retval)
> > @@ -976,10 +973,12 @@ int bus_register(const struct bus_type *
> >  		goto bus_devices_fail;
> >  	}
> >
> > -	priv->drivers_kset = kset_create_and_add("drivers", NULL, bus_kobj);
> > -	if (!priv->drivers_kset) {
> > -		retval = -ENOMEM;
> > -		goto bus_drivers_fail;
> > +	if (use_drivers) {
> > +		priv->drivers_kset = kset_create_and_add("drivers", NULL, bus_kobj);
> > +		if (!priv->drivers_kset) {
> > +			retval = -ENOMEM;
> > +			goto bus_drivers_fail;
> > +		}
> >  	}
> >
> >  	INIT_LIST_HEAD(&priv->interfaces);
> > @@ -989,9 +988,11 @@ int bus_register(const struct bus_type *
> >  	klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
> >  	klist_init(&priv->klist_drivers, NULL, NULL);
> >
> > -	retval = add_probe_files(bus);
> > -	if (retval)
> > -		goto bus_probe_files_fail;
> > +	if (use_drivers) {
> > +		retval = add_probe_files(bus);
> > +		if (retval)
> > +			goto bus_probe_files_fail;
> > +	}
> >
> >  	retval = sysfs_create_groups(bus_kobj, bus->bus_groups);
> >  	if (retval)
> > @@ -1016,9 +1017,41 @@ out:
> >  	kfree(priv);
> >  	return retval;
> >  }
> > +
> > +/**
> > + * bus_register - register a driver-core subsystem
> > + * @bus: bus to register
> > + *
> > + * Once we have that, we register the bus with the kobject
> > + * infrastructure, then register the children subsystems it has:
> > + * the devices and drivers that belong to the subsystem.
> > + */
> > +int bus_register(const struct bus_type *bus)
> > +{
> > +	return bus_register_internal(bus, true);
> > +}
> >  EXPORT_SYMBOL_GPL(bus_register);
> >
> >  /**
> > + * companion_bus_register - register a companion bus type
> > + * @bus: companion bus to register
> > + *
> > + * A companion bus is a bus without drivers.  Devices that belong to it can be
> > + * bound to other devices as their "companions" and represent interfaces that
> > + * can be used by the drivers of those other devices.  They may also be used for
> > + * the enumeration of those other devices.
> > + *
> > + * The ACPI bus is a specific example of a companion bus.
> > + *
> > + * Registering a companion bus is like registering a regular bus except that it
> > + * skips the creation of sysfs interfaces related to drivers for @bus.
> > + */
> > +int companion_bus_register(const struct bus_type *bus)
> > +{
> > +	return bus_register_internal(bus, false);
> > +}
> > +
> > +/**
> >   * bus_unregister - remove a bus from the system
> >   * @bus: bus.
> >   *
> > @@ -1415,6 +1448,11 @@ struct device_driver *driver_find(const
> >  	if (!sp)
> >  		return NULL;
> >
> > +	if (!sp->drivers_kset) {
> > +		subsys_put(sp);
> > +		return NULL;
> > +	}
> > +
> >  	k = kset_find_obj(sp->drivers_kset, name);
> >  	subsys_put(sp);
> >  	if (!k)
> > --- a/include/linux/device/bus.h
> > +++ b/include/linux/device/bus.h
> > @@ -113,6 +113,7 @@ struct bus_type {
> >  	bool need_parent_lock;
> >  };
> >
> > +int __must_check companion_bus_register(const struct bus_type *bus);
> >  int __must_check bus_register(const struct bus_type *bus);
> >
> >  void bus_unregister(const struct bus_type *bus);
> >
> >
> >


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

* Re: [PATCH v2] driver core/ACPI: Introduce companion_bus_register()
  2026-09-24 18:23   ` Michael Kelley
@ 2026-09-24 18:44     ` Rafael J. Wysocki (Intel)
  2026-09-24 21:47       ` Michael Kelley
  0 siblings, 1 reply; 14+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-09-24 18:44 UTC (permalink / raw)
  To: Michael Kelley
  Cc: Rafael J. Wysocki, Danilo Krummrich, Greg Kroah-Hartman,
	Linux on Hyper-V List, Linux ACPI, LKML,
	Linux Driver Core Development

On Thu, Sep 24, 2026 at 8:23 PM Michael Kelley <mhklinux@outlook.com> wrote:
>
> From: Michael Kelley <mhklinux@outlook.com> Sent: Wednesday, September 23, 2026 10:06 AM
> >
> > From: Rafael J. Wysocki <rafael@kernel.org> Sent: Wednesday, September 9, 2026 9:41 AM
> > >
> > > The ACPI bus type does not allow drivers to be registered, so the sysfs
> > > attributes related to drivers created for it and its devices are
> > > useless, and its drivers/ directory is always empty.  All of that is
> > > confusing and wasteful.
> > >
> > > To allow skipping the creation of those sysfs attributes, introduce a
> > > "companion" bus type concept and add a special registration function for
> > > registering "companion" bus types, companion_bus_register().
> > >
> > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > As a heads up, this patch breaks Linux guests booting on Hyper-V.
> > Something goes wrong in the VMBus driver getting loaded and
> > initialized (drivers/hv/vmbus_drv.c). It may be that the VMBus
> > driver is doing something wrong or making an invalid assumption.
> > I'll debug the problem today or tomorrow, but any insight you can
> > offer would be appreciated. I'm working with linux-next20260921.
>
> Here's what I've learned so far:
>
> 1) The problem is apparently due to systemd-udevd being unable
> to load modules with the VMBus bus driver or any of the
> individual drivers for VMBus devices.
>
> 2) I'm testing on Ubuntu 20.04 with systemd version 245. The
> problem reproduces on a different 20.04 instance. But everything
> works correctly on Ubuntu 24.04 with systemd version 255.
>
> 3) If the VMBus bus driver and key VMBus device drivers are
> compiled as built-in instead of as modules, the Ubuntu 20.04 system
> will boot.
>
> 4) If I keep your patch, but change companion_bus_register() to
> pass "true" as the second argument instead of "false", then the
> /sys/bus/acpi/drivers directory is created as before, and everything
> works. Also, only adding back the .match function as you suggested
> does not make any difference.
>
> 5) The VMBus bus is enumerated in the ACPI DSDT. The individual
> synthetic devices that are logically on VMBus are not -- they are
> "offered" by Hyper-V to the guest at runtime via a custom protocol.
> The synthetic devices end up with paths like:
>
> /sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0004:00/MSFT1000:00/<some GUID>

Which is rather unfortunate.

They should appear under the MSFT1000:00 platform device corresponding
to the ACPI device with the same name.

Anyway, it looks like older systemd may be thinking that they are ACPI
devices and may be looking for drivers in /sys/bus/acpi/drivers/.

To kind of check that this is the case, can you replace "use_drivers"
with "true" in the first check in bus_register_internal() only (with
the $subject patch applied, of course)?  That would leave the
"drivers" directory in place, but it would skip the creation of the
probe files.

> My conclusion is that for some reason, the older system-udevd has
> a dependency on the /sys/bus/acpi/drivers directory being present.
> This isn't a kernel problem per se, but there's an implicit ABI of sorts
> that assumes the existence of the "drivers" directory.
>
> To confirm all this more precisely, I'm trying to find a clever way
> to get an strace of systemd-udevd when it errors out due to the
> missing "drivers" directory, and somehow relate that back to the
> git history of systemd-udevd.
>
> Thoughts?

Well, the fact of life is that it can't cope with the changes made by
the $subject patch, but maybe we can get away with a simpler one, so
please check the above.

I'll drop the $subject patch from linux-next at least for now.

BTW, do you know why vmbus_acpi_add() does this:

ACPI_COMPANION_SET(&device->dev, device);

which essentially attempts to make an ACPI device become an ACPI
companion of itself and is useless and broken?

If this is done to work around something, there may be a design issue
in that driver.

Thanks!

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

* RE: [PATCH v2] driver core/ACPI: Introduce companion_bus_register()
  2026-09-24 18:44     ` Rafael J. Wysocki (Intel)
@ 2026-09-24 21:47       ` Michael Kelley
  2026-09-25  9:08         ` Rafael J. Wysocki (Intel)
  0 siblings, 1 reply; 14+ messages in thread
From: Michael Kelley @ 2026-09-24 21:47 UTC (permalink / raw)
  To: Rafael J. Wysocki (Intel)
  Cc: Danilo Krummrich, Greg Kroah-Hartman, Linux on Hyper-V List,
	Linux ACPI, LKML, Linux Driver Core Development

From: Rafael J. Wysocki (Intel) <rafael@kernel.org> Sent: Thursday, September 24, 2026 11:45 AM
> 
> On Thu, Sep 24, 2026 at 8:23 PM Michael Kelley <mhklinux@outlook.com> wrote:
> >
> > From: Michael Kelley <mhklinux@outlook.com> Sent: Wednesday, September 23, 2026 10:06 AM
> > >
> > > From: Rafael J. Wysocki <rafael@kernel.org> Sent: Wednesday, September 9, 2026 9:41 AM
> > > >
> > > > The ACPI bus type does not allow drivers to be registered, so the sysfs
> > > > attributes related to drivers created for it and its devices are
> > > > useless, and its drivers/ directory is always empty.  All of that is
> > > > confusing and wasteful.
> > > >
> > > > To allow skipping the creation of those sysfs attributes, introduce a
> > > > "companion" bus type concept and add a special registration function for
> > > > registering "companion" bus types, companion_bus_register().
> > > >
> > > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > >
> > > As a heads up, this patch breaks Linux guests booting on Hyper-V.
> > > Something goes wrong in the VMBus driver getting loaded and
> > > initialized (drivers/hv/vmbus_drv.c). It may be that the VMBus
> > > driver is doing something wrong or making an invalid assumption.
> > > I'll debug the problem today or tomorrow, but any insight you can
> > > offer would be appreciated. I'm working with linux-next20260921.
> >
> > Here's what I've learned so far:
> >
> > 1) The problem is apparently due to systemd-udevd being unable
> > to load modules with the VMBus bus driver or any of the
> > individual drivers for VMBus devices.
> >
> > 2) I'm testing on Ubuntu 20.04 with systemd version 245. The
> > problem reproduces on a different 20.04 instance. But everything
> > works correctly on Ubuntu 24.04 with systemd version 255.
> >
> > 3) If the VMBus bus driver and key VMBus device drivers are
> > compiled as built-in instead of as modules, the Ubuntu 20.04 system
> > will boot.
> >
> > 4) If I keep your patch, but change companion_bus_register() to
> > pass "true" as the second argument instead of "false", then the
> > /sys/bus/acpi/drivers directory is created as before, and everything
> > works. Also, only adding back the .match function as you suggested
> > does not make any difference.
> >
> > 5) The VMBus bus is enumerated in the ACPI DSDT. The individual
> > synthetic devices that are logically on VMBus are not -- they are
> > "offered" by Hyper-V to the guest at runtime via a custom protocol.
> > The synthetic devices end up with paths like:
> >
> > /sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0004:00/MSFT1000:00/<some GUID>
> 
> Which is rather unfortunate.
> 
> They should appear under the MSFT1000:00 platform device corresponding
> to the ACPI device with the same name.

Hmmm. In the path above MSFT1000:00 is the VMBus bus device from
the DSDT. Its "path" value is "\_SB_.VMOD.VMBS", which matches the
DSDT.

Under /sys/devices/platform, there is no entry for MSFT1000:00.
And under /sys/bus/platform/devices, MSFT1000:00 is a symlink to

../../../devices/system/container/ACPI0004:00/MSFT1000:00

Can you provide any more detail on how this should be? And am I
correct that these paths are governed by the parent relationships
of the "struct device"s?

> 
> Anyway, it looks like older systemd may be thinking that they are ACPI
> devices and may be looking for drivers in /sys/bus/acpi/drivers/.
> 
> To kind of check that this is the case, can you replace "use_drivers"
> with "true" in the first check in bus_register_internal() only (with
> the $subject patch applied, of course)?  That would leave the
> "drivers" directory in place, but it would skip the creation of the
> probe files.

The VM boots properly with that change. Just to confirm, under
/sys/bus/acpi, the "devices" and "drivers" directories are there,
along with "uevent". And of course, "drivers" is empty. But
drivers_autoprobe and drivers_probe are not present.

> 
> > My conclusion is that for some reason, the older system-udevd has
> > a dependency on the /sys/bus/acpi/drivers directory being present.
> > This isn't a kernel problem per se, but there's an implicit ABI of sorts
> > that assumes the existence of the "drivers" directory.
> >
> > To confirm all this more precisely, I'm trying to find a clever way
> > to get an strace of systemd-udevd when it errors out due to the
> > missing "drivers" directory, and somehow relate that back to the
> > git history of systemd-udevd.
> >
> > Thoughts?
> 
> Well, the fact of life is that it can't cope with the changes made by
> the $subject patch, but maybe we can get away with a simpler one, so
> please check the above.
> 
> I'll drop the $subject patch from linux-next at least for now.
> 
> BTW, do you know why vmbus_acpi_add() does this:
> 
> ACPI_COMPANION_SET(&device->dev, device);
> 
> which essentially attempts to make an ACPI device become an ACPI
> companion of itself and is useless and broken?

Indeed, that looks useless and broken. I need to go study the
history. I added that line originally when making sure the ACPI
_CCA setting in the VMBus entry of the DSDT was propagated
to the synthetic devices on the VMBus. But that was before
the VMBus driver was modified to model it as a platform device.
Thanks for pointing that out, and I'll follow up.

Michael

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

* Re: [PATCH v2] driver core/ACPI: Introduce companion_bus_register()
  2026-09-24 21:47       ` Michael Kelley
@ 2026-09-25  9:08         ` Rafael J. Wysocki (Intel)
  2026-09-29  3:51           ` Michael Kelley
  0 siblings, 1 reply; 14+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-09-25  9:08 UTC (permalink / raw)
  To: Michael Kelley
  Cc: Rafael J. Wysocki (Intel),
	Danilo Krummrich, Greg Kroah-Hartman, Linux on Hyper-V List,
	Linux ACPI, LKML, Linux Driver Core Development

On Thu, Sep 24, 2026 at 11:47 PM Michael Kelley <mhklinux@outlook.com> wrote:
>
> From: Rafael J. Wysocki (Intel) <rafael@kernel.org> Sent: Thursday, September 24, 2026 11:45 AM
> >
> > On Thu, Sep 24, 2026 at 8:23 PM Michael Kelley <mhklinux@outlook.com> wrote:
> > >
> > > From: Michael Kelley <mhklinux@outlook.com> Sent: Wednesday, September 23, 2026 10:06 AM
> > > >
> > > > From: Rafael J. Wysocki <rafael@kernel.org> Sent: Wednesday, September 9, 2026 9:41 AM
> > > > >
> > > > > The ACPI bus type does not allow drivers to be registered, so the sysfs
> > > > > attributes related to drivers created for it and its devices are
> > > > > useless, and its drivers/ directory is always empty.  All of that is
> > > > > confusing and wasteful.
> > > > >
> > > > > To allow skipping the creation of those sysfs attributes, introduce a
> > > > > "companion" bus type concept and add a special registration function for
> > > > > registering "companion" bus types, companion_bus_register().
> > > > >
> > > > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > > >
> > > > As a heads up, this patch breaks Linux guests booting on Hyper-V.
> > > > Something goes wrong in the VMBus driver getting loaded and
> > > > initialized (drivers/hv/vmbus_drv.c). It may be that the VMBus
> > > > driver is doing something wrong or making an invalid assumption.
> > > > I'll debug the problem today or tomorrow, but any insight you can
> > > > offer would be appreciated. I'm working with linux-next20260921.
> > >
> > > Here's what I've learned so far:
> > >
> > > 1) The problem is apparently due to systemd-udevd being unable
> > > to load modules with the VMBus bus driver or any of the
> > > individual drivers for VMBus devices.
> > >
> > > 2) I'm testing on Ubuntu 20.04 with systemd version 245. The
> > > problem reproduces on a different 20.04 instance. But everything
> > > works correctly on Ubuntu 24.04 with systemd version 255.
> > >
> > > 3) If the VMBus bus driver and key VMBus device drivers are
> > > compiled as built-in instead of as modules, the Ubuntu 20.04 system
> > > will boot.
> > >
> > > 4) If I keep your patch, but change companion_bus_register() to
> > > pass "true" as the second argument instead of "false", then the
> > > /sys/bus/acpi/drivers directory is created as before, and everything
> > > works. Also, only adding back the .match function as you suggested
> > > does not make any difference.
> > >
> > > 5) The VMBus bus is enumerated in the ACPI DSDT. The individual
> > > synthetic devices that are logically on VMBus are not -- they are
> > > "offered" by Hyper-V to the guest at runtime via a custom protocol.
> > > The synthetic devices end up with paths like:
> > >
> > > /sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0004:00/MSFT1000:00/<some GUID>
> >
> > Which is rather unfortunate.
> >
> > They should appear under the MSFT1000:00 platform device corresponding
> > to the ACPI device with the same name.
>
> Hmmm. In the path above MSFT1000:00 is the VMBus bus device from
> the DSDT. Its "path" value is "\_SB_.VMOD.VMBS", which matches the
> DSDT.
>
> Under /sys/devices/platform, there is no entry for MSFT1000:00.

/sys/devices/platform/ contains platform devices that were created
without parents.  MSFT1000:00 has a parent, so it is not there.

> And under /sys/bus/platform/devices, MSFT1000:00 is a symlink to
>
> ../../../devices/system/container/ACPI0004:00/MSFT1000:00
>
> Can you provide any more detail on how this should be? And am I
> correct that these paths are governed by the parent relationships
> of the "struct device"s?

Yes, you are, and this is the platform device I'm talking about.  The
firmware_node symbolic link under it should point to
/sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0004:00/MSFT1000:00/.

The idea is that the objects under /sys/devices/LNXSYSTM:00/
correspond to nodes in the ACPI namespace and they may or may not
correspond to physical pieces of hardware.  They are referred to as
"ACPI devices", but in fact they represent platform firmware
interfaces that can be associated with devices - that's where the
firmware_node and physical_node symlinks come into play.

Accordingly, adding children that do not correspond to nodes in the
ACPI namespace is confusing and generally questionable.  Children
should be added under devices pointed to by their physical_node
symlinks.

> >
> > Anyway, it looks like older systemd may be thinking that they are ACPI
> > devices and may be looking for drivers in /sys/bus/acpi/drivers/.
> >
> > To kind of check that this is the case, can you replace "use_drivers"
> > with "true" in the first check in bus_register_internal() only (with
> > the $subject patch applied, of course)?  That would leave the
> > "drivers" directory in place, but it would skip the creation of the
> > probe files.
>
> The VM boots properly with that change. Just to confirm, under
> /sys/bus/acpi, the "devices" and "drivers" directories are there,
> along with "uevent". And of course, "drivers" is empty. But
> drivers_autoprobe and drivers_probe are not present.

Yes, that's as expected, thanks for checking!

I'll send a new version of the $subject patch based on this observation.

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

* RE: [PATCH v2] driver core/ACPI: Introduce companion_bus_register()
  2026-09-25  9:08         ` Rafael J. Wysocki (Intel)
@ 2026-09-29  3:51           ` Michael Kelley
  0 siblings, 0 replies; 14+ messages in thread
From: Michael Kelley @ 2026-09-29  3:51 UTC (permalink / raw)
  To: Rafael J. Wysocki (Intel)
  Cc: Danilo Krummrich, Greg Kroah-Hartman, Linux on Hyper-V List,
	Linux ACPI, LKML, Linux Driver Core Development

From: Rafael J. Wysocki (Intel) <rafael@kernel.org> Sent: Friday, September 25, 2026 2:08 AM
> 
> On Thu, Sep 24, 2026 at 11:47 PM Michael Kelley <mhklinux@outlook.com> wrote:
> >
> > From: Rafael J. Wysocki (Intel) <rafael@kernel.org> Sent: Thursday, September 24, 2026 11:45 AM
> > >
> > > On Thu, Sep 24, 2026 at 8:23 PM Michael Kelley <mhklinux@outlook.com> wrote:
> > > >
> > > > From: Michael Kelley <mhklinux@outlook.com> Sent: Wednesday, September 23, 2026 10:06 AM
> > > >
> > > > Here's what I've learned so far:
> > > >
> > > > 1) The problem is apparently due to systemd-udevd being unable
> > > > to load modules with the VMBus bus driver or any of the
> > > > individual drivers for VMBus devices.
> > > >
> > > > 2) I'm testing on Ubuntu 20.04 with systemd version 245. The
> > > > problem reproduces on a different 20.04 instance. But everything
> > > > works correctly on Ubuntu 24.04 with systemd version 255.
> > > >
> > > > 3) If the VMBus bus driver and key VMBus device drivers are
> > > > compiled as built-in instead of as modules, the Ubuntu 20.04 system
> > > > will boot.
> > > >
> > > > 4) If I keep your patch, but change companion_bus_register() to
> > > > pass "true" as the second argument instead of "false", then the
> > > > /sys/bus/acpi/drivers directory is created as before, and everything
> > > > works. Also, only adding back the .match function as you suggested
> > > > does not make any difference.
> > > >
> > > > 5) The VMBus bus is enumerated in the ACPI DSDT. The individual
> > > > synthetic devices that are logically on VMBus are not -- they are
> > > > "offered" by Hyper-V to the guest at runtime via a custom protocol.
> > > > The synthetic devices end up with paths like:
> > > >
> > > > /sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0004:00/MSFT1000:00/<some GUID>
> > >
> > > Which is rather unfortunate.
> > >
> > > They should appear under the MSFT1000:00 platform device corresponding
> > > to the ACPI device with the same name.
> >
> > Hmmm. In the path above MSFT1000:00 is the VMBus bus device from
> > the DSDT. Its "path" value is "\_SB_.VMOD.VMBS", which matches the
> > DSDT.
> >
> > Under /sys/devices/platform, there is no entry for MSFT1000:00.
> 
> /sys/devices/platform/ contains platform devices that were created
> without parents.  MSFT1000:00 has a parent, so it is not there.
> 
> > And under /sys/bus/platform/devices, MSFT1000:00 is a symlink to
> >
> > ../../../devices/system/container/ACPI0004:00/MSFT1000:00
> >
> > Can you provide any more detail on how this should be? And am I
> > correct that these paths are governed by the parent relationships
> > of the "struct device"s?
> 
> Yes, you are, and this is the platform device I'm talking about.  The
> firmware_node symbolic link under it should point to
> /sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0004:00/MSFT1000:00/.
> 
> The idea is that the objects under /sys/devices/LNXSYSTM:00/
> correspond to nodes in the ACPI namespace and they may or may not
> correspond to physical pieces of hardware.  They are referred to as
> "ACPI devices", but in fact they represent platform firmware
> interfaces that can be associated with devices - that's where the
> firmware_node and physical_node symlinks come into play.
> 
> Accordingly, adding children that do not correspond to nodes in the
> ACPI namespace is confusing and generally questionable.  Children
> should be added under devices pointed to by their physical_node
> symlinks.
> 

To follow up on your observations about the parenting of the
VMBus synthetic devices, it's a relatively easy fix to parent them
to the VMBus platform device. Then they appear as:

/sys/devices/system/container/ACPI0004:00/MSFT1000:00/<some GUID>

/sys/devices/platform still does *not* contain MSFT1000:00. I read
your previous comment to mean that this is correct since
MSFT1000:00 has a parent.

/sys/bus/platform/devices/MSFT1000:00 is a symlink to
../../../devices/system/container/ACPI0004:00/MSFT1000:00, just
as before. And this is also presumably correct.

FWIW, even with these devices correctly parented, removing
/sys/bus/acpi/drivers still causes system-udevd v245 to not load
the driver modules. All along, there has been this error message:

     Failed to scan subsystems: No such file or directory

that I can now attribute to system-udevd, based on looking
at its source code. The code is a bit hard to understand in a
quick perusal, but presumably "No such file or directory" is
referring to /sys/bus/acpi/drivers.

Finally, vmbus_acpi_add() doing

    ACPI_COMPANION_SET(&device->dev, device);

is intentional and needed in a perverse sort of way when
VMBus's main identity is its ACPI device instead of its
platform device. It's needed to make device_get_dma_attr()
work, as it finds the ACPI companion of its argument.
When the ACPI device itself passed as the argument to
device_get_dma_attr(), the loopback makes it properly
get the DMA coherence attribute specified for VMBus in
the DSDT. But if the VMBus driver instead uses the platform
device as the main identity for VMBus, the loopback
behavior is no longer needed.

I intend to submit a patch to make the parenting change,
and remove the ACPI_COMPANION_SET(). But before doing
so, I need to work out a parenting issue in the Hyper-V virtual
PCI driver.

Question: Do you have knowledge of any user space
utilities that might break if the VMBus synthetic devices
are now at a different path under /sys? I don't know what
utilities might be reading this stuff. There are Hyper-V
specific utilities, but everything they look at is under
/sys/bus/vmbus, and its structure isn't changing (though
the synthetic device symlinks correctly point to the new
location).

I appreciate your help and consultation. I've learned
something. :-)

Michael

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

end of thread, other threads:[~2026-09-29  3:51 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-09 16:41 [PATCH v2] driver core/ACPI: Introduce companion_bus_register() Rafael J. Wysocki
2026-09-16 18:45 ` Rafael J. Wysocki (Intel)
2026-09-16 18:52   ` Greg Kroah-Hartman
2026-09-16 18:51 ` Danilo Krummrich
2026-09-23 17:05 ` Michael Kelley
2026-09-23 17:32   ` Rafael J. Wysocki (Intel)
2026-09-23 18:31     ` Rafael J. Wysocki (Intel)
2026-09-23 18:50       ` Rafael J. Wysocki (Intel)
2026-09-23 19:11         ` Rafael J. Wysocki (Intel)
2026-09-24 18:23   ` Michael Kelley
2026-09-24 18:44     ` Rafael J. Wysocki (Intel)
2026-09-24 21:47       ` Michael Kelley
2026-09-25  9:08         ` Rafael J. Wysocki (Intel)
2026-09-29  3:51           ` Michael Kelley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®