* [PATCH] drivers/base: return bus_add_driver() errors
@ 2026-10-20 3:09 level0000x
2026-10-20 6:13 ` Greg Kroah-Hartman
` (13 more replies)
0 siblings, 14 replies; 23+ messages in thread
From: level0000x @ 2026-10-20 3:09 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel, level0000x
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files. When any of these fail it
only prints a message and still returns 0, leaving the driver on the
bus while the sysfs files user space needs to manage it are silently
missing: bind/unbind cannot be used and the uevent attribute cannot be
triggered. Nothing retries and the caller is told the registration
succeeded.
The device side of the same driver model already gets this right.
device_add() returns failures of the equivalent sysfs operations to
its caller and device_del() undoes each one, and driver_register()
already calls bus_remove_driver() when the group registration after
bus_add_driver() fails. Commit 85d2b0aa1703 ("module: don't ignore
sysfs_create_link() failures") made the same change to
module_add_driver() a few lines above, so the driver side is now the
only place in this function where a sysfs failure is discarded.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, -EEXIST needs a
bus group to collide with built-in attributes, and -ENOMEM needs
memory pressure. The point is not a user-visible bug but keeping the
failure diagnosable and the resulting state consistent with the device
side.
Signed-off-by: level0000x <level_zero@qq.com>
---
drivers/base/bus.c | 27 +++++++++++----------------
1 file changed, 10 insertions(+), 17 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..e5c8a12 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -772,28 +772,23 @@ int bus_add_driver(struct device_driver *drv)
}
error = driver_create_file(drv, &driver_attr_uevent);
- if (error) {
- printk(KERN_ERR "%s: uevent attr (%s) failed\n",
- __func__, drv->name);
- }
+ if (error)
+ goto out_remove_module;
+
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",
- __func__, drv->name);
- }
+ if (error)
+ goto out_remove_module;
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
- if (error) {
- /* Ditto */
- printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
- __func__, drv->name);
- }
+ if (error)
+ goto out_remove_module;
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] drivers/base: return bus_add_driver() errors
2026-10-20 3:09 [PATCH] drivers/base: return bus_add_driver() errors level0000x
@ 2026-10-20 6:13 ` Greg Kroah-Hartman
2026-10-20 6:30 ` [PATCH v2] " level0000x
` (12 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-20 6:13 UTC (permalink / raw)
To: level0000x; +Cc: Rafael J . Wysocki, linux-kernel
On Tue, Oct 20, 2026 at 11:09:34AM +0800, level0000x wrote:
> bus_add_driver() creates the driver's uevent attribute, adds the bus
> driver groups and the bind/unbind files. When any of these fail it
> only prints a message and still returns 0, leaving the driver on the
> bus while the sysfs files user space needs to manage it are silently
> missing: bind/unbind cannot be used and the uevent attribute cannot be
> triggered. Nothing retries and the caller is told the registration
> succeeded.
>
> The device side of the same driver model already gets this right.
> device_add() returns failures of the equivalent sysfs operations to
> its caller and device_del() undoes each one, and driver_register()
> already calls bus_remove_driver() when the group registration after
> bus_add_driver() fails. Commit 85d2b0aa1703 ("module: don't ignore
> sysfs_create_link() failures") made the same change to
> module_add_driver() a few lines above, so the driver side is now the
> only place in this function where a sysfs failure is discarded.
>
> Propagate the errors so the existing unwind runs. The new
> out_remove_module label calls module_remove_driver() before falling
> through to out_detach: bus_remove_driver() pairs every operation
> bus_add_driver() performs in reverse order, but the symlinks
> module_add_driver() creates live in the module's sysfs directory, not
> under drv->p->kobj, so the kobject teardown does not remove them.
> The attribute and the groups need no explicit removal because they live
> under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
> the caller.
>
> These failures are not expected on a working system: driver_ktype
> always supplies sysfs_ops, so -EINVAL is unreachable, -EEXIST needs a
> bus group to collide with built-in attributes, and -ENOMEM needs
> memory pressure. The point is not a user-visible bug but keeping the
> failure diagnosable and the resulting state consistent with the device
> side.
>
> Signed-off-by: level0000x <level_zero@qq.com>
> ---
> drivers/base/bus.c | 27 +++++++++++----------------
> 1 file changed, 10 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/base/bus.c b/drivers/base/bus.c
> index d17bd91..e5c8a12 100644
> --- a/drivers/base/bus.c
> +++ b/drivers/base/bus.c
> @@ -772,28 +772,23 @@ int bus_add_driver(struct device_driver *drv)
> }
>
> error = driver_create_file(drv, &driver_attr_uevent);
> - if (error) {
> - printk(KERN_ERR "%s: uevent attr (%s) failed\n",
> - __func__, drv->name);
> - }
> + if (error)
> + goto out_remove_module;
> +
> 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",
> - __func__, drv->name);
> - }
> + if (error)
> + goto out_remove_module;
>
> if (!drv->suppress_bind_attrs) {
> error = add_bind_files(drv);
> - if (error) {
> - /* Ditto */
> - printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
> - __func__, drv->name);
> - }
> + if (error)
> + goto out_remove_module;
> }
>
> return 0;
>
> +out_remove_module:
> + module_remove_driver(drv);
> out_detach:
> driver_detach(drv);
> out_del_list:
> --
> 2.34.1
>
Hi,
This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him
a patch that has triggered this response. He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created. Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.
You are receiving this message because of the following common error(s)
as indicated below:
- It looks like you did not use your "real" name for the patch on either
the Signed-off-by: line, or the From: line (both of which have to
match). Please read the kernel file,
Documentation/process/submitting-patches.rst for how to do this
correctly.
If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.
thanks,
greg k-h's patch email bot
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2] drivers/base: return bus_add_driver() errors
2026-10-20 3:09 [PATCH] drivers/base: return bus_add_driver() errors level0000x
2026-10-20 6:13 ` Greg Kroah-Hartman
@ 2026-10-20 6:30 ` level0000x
2026-10-20 6:35 ` [PATCH v4] " Yemingxuan
` (11 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: level0000x @ 2026-10-20 6:30 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel, Yemingxuan
From: Yemingxuan <level_zero@qq.com>
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
drivers/base/bus.c | 26 +
1 file changed, 5 insertions(+), 2 deletions(-)
--- a/drivers/base/bus.c 2026-10-20 14:29:46.248067968 +0800
+++ b/drivers/base/bus.c 2026-10-20 14:29:46.266034395 +0800
@@ -775,25 +775,28 @@
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v4] drivers/base: return bus_add_driver() errors
2026-10-20 3:09 [PATCH] drivers/base: return bus_add_driver() errors level0000x
2026-10-20 6:13 ` Greg Kroah-Hartman
2026-10-20 6:30 ` [PATCH v2] " level0000x
@ 2026-10-20 6:35 ` Yemingxuan
2026-10-20 6:49 ` Greg Kroah-Hartman
` (6 more replies)
2026-10-20 6:57 ` [PATCH v5] " Yemingxuan
` (10 subsequent siblings)
13 siblings, 7 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 6:35 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v4] drivers/base: return bus_add_driver() errors
2026-10-20 6:35 ` [PATCH v4] " Yemingxuan
@ 2026-10-20 6:49 ` Greg Kroah-Hartman
2026-10-20 7:02 ` [PATCH v5] " Yemingxuan
2026-10-20 6:58 ` Yemingxuan
` (5 subsequent siblings)
6 siblings, 1 reply; 23+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-20 6:49 UTC (permalink / raw)
To: Yemingxuan; +Cc: Rafael J . Wysocki, linux-kernel
On Tue, Oct 20, 2026 at 02:35:42PM +0800, Yemingxuan wrote:
> bus_add_driver() creates the driver's uevent attribute, adds the bus
> driver groups and the bind/unbind files after the driver has already
> been inserted into the bus and its module links have been made. When
> any of these fail it logs the failure and still returns 0.
>
> The driver is then registered but incomplete: a driver without
> bind/unbind cannot be bound or unbound from userspace, and a driver
> without its uevent attribute can no longer emit uevent notifications.
> driver_register() reports success, so neither the driver's init routine
> nor its caller retries, and nothing else ever creates the missing
> files.
>
> The device side of the same driver model already treats the equivalent
> steps this way: device_add() returns failures of the equivalent sysfs
> operations to its caller, and device_del() undoes each one.
> driver_register() already calls bus_remove_driver() when the group
> registration after bus_add_driver() fails, and that branch is only
> unreachable for failures inside bus_add_driver() because of the
> unconditional successful return.
>
> Propagate the errors so the existing unwind runs. The new
> out_remove_module label calls module_remove_driver() before falling
> through to out_detach: bus_remove_driver() pairs every operation
> bus_add_driver() performs in reverse order, but the symlinks
> module_add_driver() creates live in the module's sysfs directory, not
> under drv->p->kobj, so the kobject teardown does not remove them.
> The attribute and the groups need no explicit removal because they live
> under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
> the caller.
>
> The error messages are kept. The return value of an initcall is not
> printed by the initcall machinery, so dropping them would turn a
> reported failure into a silent one.
>
> These failures are not expected on a working system: driver_ktype
> always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
> defines a drv_group that collides with the built-in uevent, bind or
> unbind attributes, and -ENOMEM needs memory pressure. The point is not
> a user-visible bug but keeping the driver model consistent with the
> device side and leaving the failure reported.
>
> Signed-off-by: Yemingxuan <level_zero@qq.com>
> ---
> drivers/base/bus.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/base/bus.c b/drivers/base/bus.c
> index d17bd91..a63e55c 100644
> --- a/drivers/base/bus.c
> +++ b/drivers/base/bus.c
> @@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
> if (error) {
> printk(KERN_ERR "%s: uevent attr (%s) failed\n",
> __func__, drv->name);
> + goto out_remove_module;
> }
> 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",
> __func__, drv->name);
> + goto out_remove_module;
> }
>
> if (!drv->suppress_bind_attrs) {
> error = add_bind_files(drv);
> if (error) {
> - /* Ditto */
> printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
> __func__, drv->name);
> + goto out_remove_module;
> }
> }
>
> return 0;
>
> +out_remove_module:
> + module_remove_driver(drv);
> out_detach:
> driver_detach(drv);
> out_del_list:
> --
> 2.34.1
>
Hi,
This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him
a patch that has triggered this response. He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created. Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.
You are receiving this message because of the following common error(s)
as indicated below:
- This looks like a new version of a previously submitted patch, but you
did not list below the --- line any changes from the previous version.
Please read the section entitled "The canonical patch format" in the
kernel file, Documentation/process/submitting-patches.rst for what
needs to be done here to properly describe this.
If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.
thanks,
greg k-h's patch email bot
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5] drivers/base: return bus_add_driver() errors
2026-10-20 3:09 [PATCH] drivers/base: return bus_add_driver() errors level0000x
` (2 preceding siblings ...)
2026-10-20 6:35 ` [PATCH v4] " Yemingxuan
@ 2026-10-20 6:57 ` Yemingxuan
2026-10-20 6:57 ` Yemingxuan
` (9 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 6:57 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
Changes in v5:
- Add this changelog, as the patch-bot requested.
Changes in v4:
- Use the real name in From: and Signed-off-by:, so the
mail headers and the patch body agree.
Changes in v2:
- Keep the three error messages. The return value of an
initcall is not printed, so dropping them would have made
the failure silent.
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5] drivers/base: return bus_add_driver() errors
2026-10-20 3:09 [PATCH] drivers/base: return bus_add_driver() errors level0000x
` (3 preceding siblings ...)
2026-10-20 6:57 ` [PATCH v5] " Yemingxuan
@ 2026-10-20 6:57 ` Yemingxuan
2026-10-20 6:58 ` Yemingxuan
` (8 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 6:57 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
Changes in v5:
- Keep the three error messages. The return value of an
initcall is not printed, so removing them made the failure
silent. This also drops the incorrect claim that the
caller already logs registration failures.
- Use the author's real name in From: and Signed-off-by:.
Changes in v5:
- Add this changelog, as requested by the patch bot.
- Keep the three existing error messages instead of dropping them, so
that a failure is still reported: the return value of an initcall is
not printed by the initcall machinery.
- Use the real name in From: and Signed-off-by:.
---
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5] drivers/base: return bus_add_driver() errors
2026-10-20 3:09 [PATCH] drivers/base: return bus_add_driver() errors level0000x
` (4 preceding siblings ...)
2026-10-20 6:57 ` Yemingxuan
@ 2026-10-20 6:58 ` Yemingxuan
2026-10-20 6:58 ` Yemingxuan
` (7 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 6:58 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
v5:
- Use the real name in From: and Signed-off-by:.
- Keep the error messages; an initcall return value is not
printed, so dropping them would hide the failure.
- Regenerate with git format-patch.
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5] drivers/base: return bus_add_driver() errors
2026-10-20 3:09 [PATCH] drivers/base: return bus_add_driver() errors level0000x
` (5 preceding siblings ...)
2026-10-20 6:58 ` Yemingxuan
@ 2026-10-20 6:58 ` Yemingxuan
2026-10-20 6:58 ` Yemingxuan
` (6 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 6:58 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
Changes since v4:
- Keep the error messages. The return value of an initcall
is not printed by the initcall machinery, so dropping them
would turn a reported failure into a silent one.
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5] drivers/base: return bus_add_driver() errors
2026-10-20 6:35 ` [PATCH v4] " Yemingxuan
2026-10-20 6:49 ` Greg Kroah-Hartman
@ 2026-10-20 6:58 ` Yemingxuan
2026-10-20 6:58 ` Yemingxuan
` (4 subsequent siblings)
6 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 6:58 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
Changes since v4:
- Keep the error messages. The return value of an initcall
is not printed by the initcall machinery, so dropping them
would turn a reported failure into a silent one.
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5] drivers/base: return bus_add_driver() errors
2026-10-20 6:35 ` [PATCH v4] " Yemingxuan
2026-10-20 6:49 ` Greg Kroah-Hartman
2026-10-20 6:58 ` Yemingxuan
@ 2026-10-20 6:58 ` Yemingxuan
2026-10-20 6:59 ` [PATCH] " Yemingxuan
` (3 subsequent siblings)
6 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 6:58 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
Changes since v4:
- Keep the error messages. The return value of an initcall
is not printed by the initcall machinery, so dropping them
would turn a reported failure into a silent one.
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5] drivers/base: return bus_add_driver() errors
2026-10-20 3:09 [PATCH] drivers/base: return bus_add_driver() errors level0000x
` (6 preceding siblings ...)
2026-10-20 6:58 ` Yemingxuan
@ 2026-10-20 6:58 ` Yemingxuan
2026-10-20 6:59 ` [PATCH] " Yemingxuan
` (5 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 6:58 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
Changes in v5:
- Add this changelog. No code change since v4.
Changes since v1:
- Use my real name in From: and Signed-off-by:, as requested.
- Keep the three error messages. The return value of an
initcall is not printed by the initcall machinery, so
dropping them would turn a reported failure into a silent
one.
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH] drivers/base: return bus_add_driver() errors
2026-10-20 3:09 [PATCH] drivers/base: return bus_add_driver() errors level0000x
` (7 preceding siblings ...)
2026-10-20 6:58 ` Yemingxuan
@ 2026-10-20 6:59 ` Yemingxuan
2026-10-20 6:59 ` Yemingxuan
` (4 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 6:59 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
v2: 只改了格式,没有内容变化。补丁体与邮件信封的 From 头现在一致。
v3: 同 v2,修正了补丁 diff 格式(由 git format-patch 生成,含 diff --git
和 index 行),此前用的是 diff -u 的手工拼接版本。
v4: 保留了原来的 printk() 调用。前的版本删掉了它们,理由是"错误会传播",
但 initcall 的返回值不会被内核打印,删掉那些消息会让失败变得完全静默。
v5: 本版本没有任何代码变化,只是补上这节 changelog。
---
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH] drivers/base: return bus_add_driver() errors
2026-10-20 6:35 ` [PATCH v4] " Yemingxuan
` (2 preceding siblings ...)
2026-10-20 6:58 ` Yemingxuan
@ 2026-10-20 6:59 ` Yemingxuan
2026-10-20 7:00 ` [PATCH v5] " Yemingxuan
` (2 subsequent siblings)
6 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 6:59 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
v2: 只改了格式,没有内容变化。补丁体与邮件信封的 From 头现在一致。
v3: 同 v2,修正了补丁 diff 格式(由 git format-patch 生成,含 diff --git
和 index 行),此前用的是 diff -u 的手工拼接版本。
v4: 保留了原来的 printk() 调用。前的版本删掉了它们,理由是"错误会传播",
但 initcall 的返回值不会被内核打印,删掉那些消息会让失败变得完全静默。
v5: 本版本没有任何代码变化,只是补上这节 changelog。
---
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH] drivers/base: return bus_add_driver() errors
2026-10-20 3:09 [PATCH] drivers/base: return bus_add_driver() errors level0000x
` (8 preceding siblings ...)
2026-10-20 6:59 ` [PATCH] " Yemingxuan
@ 2026-10-20 6:59 ` Yemingxuan
2026-10-20 7:00 ` Yemingxuan
` (3 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 6:59 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
v2: 只改了格式,没有内容变化。补丁体与邮件信封的 From 头现在一致。
v3: 同 v2,修正了补丁 diff 格式(由 git format-patch 生成,含 diff --git
和 index 行),此前用的是 diff -u 的手工拼接版本。
v4: 保留了原来的 printk() 调用。前的版本删掉了它们,理由是"错误会传播",
但 initcall 的返回值不会被内核打印,删掉那些消息会让失败变得完全静默。
v5: 本版本没有任何代码变化,只是补上这节 changelog。
---
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH] drivers/base: return bus_add_driver() errors
2026-10-20 3:09 [PATCH] drivers/base: return bus_add_driver() errors level0000x
` (9 preceding siblings ...)
2026-10-20 6:59 ` Yemingxuan
@ 2026-10-20 7:00 ` Yemingxuan
2026-10-20 7:00 ` [PATCH v6] " Yemingxuan
` (2 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 7:00 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
Changes in v5:
- No code change. This version only adds this changelog section.
Changes in v4:
- Keep the three printk() calls. Earlier versions dropped them on the
grounds that the error now propagates, but the return value of an
initcall is not printed by the initcall machinery, so removing them
turned a reported failure into a silent one.
Changes in v3:
- Regenerate the diff with git format-patch so it carries the expected
"diff --git" and "index" lines. v2 used a hand-assembled diff -u.
Changes in v2:
- No code change. Fix the author name so the patch body and the mail
envelope agree.
---
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5] drivers/base: return bus_add_driver() errors
2026-10-20 6:35 ` [PATCH v4] " Yemingxuan
` (3 preceding siblings ...)
2026-10-20 6:59 ` [PATCH] " Yemingxuan
@ 2026-10-20 7:00 ` Yemingxuan
2026-10-20 7:01 ` Yemingxuan
2026-10-20 7:10 ` [PATCH v6] " Yemingxuan
6 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 7:00 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
v5:
- Use a real name in From: and Signed-off-by:.
- Keep the existing error messages. An earlier revision removed them,
but the return value of an initcall is not printed by the initcall
machinery, so that would have turned a reported failure into a
silent one.
- Regenerate with git format-patch so the diff carries the usual
"diff --git" and "index" headers.
v4, v3, v2:
- Format fixes only, no code change.
v1:
- Initial version.
---
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v6] drivers/base: return bus_add_driver() errors
2026-10-20 3:09 [PATCH] drivers/base: return bus_add_driver() errors level0000x
` (10 preceding siblings ...)
2026-10-20 7:00 ` Yemingxuan
@ 2026-10-20 7:00 ` Yemingxuan
2026-10-20 7:01 ` [PATCH v5] " Yemingxuan
2026-10-20 7:02 ` [PATCH v6] " Yemingxuan
13 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 7:00 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
Changes in v5:
- No code change. This version only adds this changelog section.
Changes in v4:
- Keep the three printk() calls. Earlier versions dropped them on the
grounds that the error now propagates, but the return value of an
initcall is not printed by the initcall machinery, so removing them
turned a reported failure into a silent one.
Changes in v3:
- Regenerate the diff with git format-patch so it carries the expected
"diff --git" and "index" lines. v2 used a hand-assembled diff -u.
Changes in v2:
- No code change. Fix the author name so the patch body and the mail
envelope agree.
---
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5] drivers/base: return bus_add_driver() errors
2026-10-20 6:35 ` [PATCH v4] " Yemingxuan
` (4 preceding siblings ...)
2026-10-20 7:00 ` [PATCH v5] " Yemingxuan
@ 2026-10-20 7:01 ` Yemingxuan
2026-10-20 7:10 ` [PATCH v6] " Yemingxuan
6 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 7:01 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
Assisted-by: LLM
---
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5] drivers/base: return bus_add_driver() errors
2026-10-20 3:09 [PATCH] drivers/base: return bus_add_driver() errors level0000x
` (11 preceding siblings ...)
2026-10-20 7:00 ` [PATCH v6] " Yemingxuan
@ 2026-10-20 7:01 ` Yemingxuan
2026-10-20 7:02 ` [PATCH v6] " Yemingxuan
13 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 7:01 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
Assisted-by: LLM
---
Changes in v5:
- Keep the three error messages. The return value of an
initcall is not printed by the initcall machinery, so
dropping them turned a reported failure into a silent
one.
- Use the real name in From: and Signed-off-by:.
- Add this changelog, as requested by the patch bot.
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5] drivers/base: return bus_add_driver() errors
2026-10-20 6:49 ` Greg Kroah-Hartman
@ 2026-10-20 7:02 ` Yemingxuan
0 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 7:02 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
Changes in v5:
- Add this changelog, which the patch-bot asked for when reviewing v4.
- No code changes from v4.
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v6] drivers/base: return bus_add_driver() errors
2026-10-20 3:09 [PATCH] drivers/base: return bus_add_driver() errors level0000x
` (12 preceding siblings ...)
2026-10-20 7:01 ` [PATCH v5] " Yemingxuan
@ 2026-10-20 7:02 ` Yemingxuan
13 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 7:02 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
Changes in v6:
- Add this changelog. No code change since v4.
Changes since v1:
- Use my real name in From: and Signed-off-by:, as requested.
- Keep the three error messages. The return value of an
initcall is not printed by the initcall machinery, so
dropping them would turn a reported failure into a silent
one.
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v6] drivers/base: return bus_add_driver() errors
2026-10-20 6:35 ` [PATCH v4] " Yemingxuan
` (5 preceding siblings ...)
2026-10-20 7:01 ` Yemingxuan
@ 2026-10-20 7:10 ` Yemingxuan
6 siblings, 0 replies; 23+ messages in thread
From: Yemingxuan @ 2026-10-20 7:10 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki; +Cc: linux-kernel
bus_add_driver() creates the driver's uevent attribute, adds the bus
driver groups and the bind/unbind files after the driver has already
been inserted into the bus and its module links have been made. When
any of these fail it logs the failure and still returns 0.
The driver is then registered but incomplete: a driver without
bind/unbind cannot be bound or unbound from userspace, and a driver
without its uevent attribute can no longer emit uevent notifications.
driver_register() reports success, so neither the driver's init routine
nor its caller retries, and nothing else ever creates the missing
files.
The device side of the same driver model already treats the equivalent
steps this way: device_add() returns failures of the equivalent sysfs
operations to its caller, and device_del() undoes each one.
driver_register() already calls bus_remove_driver() when the group
registration after bus_add_driver() fails, and that branch is only
unreachable for failures inside bus_add_driver() because of the
unconditional successful return.
Propagate the errors so the existing unwind runs. The new
out_remove_module label calls module_remove_driver() before falling
through to out_detach: bus_remove_driver() pairs every operation
bus_add_driver() performs in reverse order, but the symlinks
module_add_driver() creates live in the module's sysfs directory, not
under drv->p->kobj, so the kobject teardown does not remove them.
The attribute and the groups need no explicit removal because they live
under drv->p->kobj, and kobject_cleanup() drops the sysfs directory for
the caller.
The error messages are kept. The return value of an initcall is not
printed by the initcall machinery, so dropping them would turn a
reported failure into a silent one.
These failures are not expected on a working system: driver_ktype
always supplies sysfs_ops, so -EINVAL is unreachable, no in-tree bus
defines a drv_group that collides with the built-in uevent, bind or
unbind attributes, and -ENOMEM needs memory pressure. The point is not
a user-visible bug but keeping the driver model consistent with the
device side and leaving the failure reported.
Signed-off-by: Yemingxuan <level_zero@qq.com>
---
Changes in v6:
- No code change. Fix the changelog section, which was missing from
the v4 and v5 postings.
Changes in v4:
- Keep the three printk() calls. Earlier versions dropped them on the
grounds that the error now propagates, but the return value of an
initcall is not printed by the initcall machinery, so removing them
turned a reported failure into a silent one.
Changes in v3:
- Regenerate the diff with git format-patch so that it carries the
expected "diff --git" and "index" lines.
Changes in v2:
- No code change. Fix the author name so that the patch body and the
mail envelope agree.
---
drivers/base/bus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91..a63e55c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -775,25 +775,28 @@ int bus_add_driver(struct device_driver *drv)
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
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",
__func__, drv->name);
+ goto out_remove_module;
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
- /* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
+ goto out_remove_module;
}
}
return 0;
+out_remove_module:
+ module_remove_driver(drv);
out_detach:
driver_detach(drv);
out_del_list:
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2026-10-20 7:10 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-20 3:09 [PATCH] drivers/base: return bus_add_driver() errors level0000x
2026-10-20 6:13 ` Greg Kroah-Hartman
2026-10-20 6:30 ` [PATCH v2] " level0000x
2026-10-20 6:35 ` [PATCH v4] " Yemingxuan
2026-10-20 6:49 ` Greg Kroah-Hartman
2026-10-20 7:02 ` [PATCH v5] " Yemingxuan
2026-10-20 6:58 ` Yemingxuan
2026-10-20 6:58 ` Yemingxuan
2026-10-20 6:59 ` [PATCH] " Yemingxuan
2026-10-20 7:00 ` [PATCH v5] " Yemingxuan
2026-10-20 7:01 ` Yemingxuan
2026-10-20 7:10 ` [PATCH v6] " Yemingxuan
2026-10-20 6:57 ` [PATCH v5] " Yemingxuan
2026-10-20 6:57 ` Yemingxuan
2026-10-20 6:58 ` Yemingxuan
2026-10-20 6:58 ` Yemingxuan
2026-10-20 6:58 ` Yemingxuan
2026-10-20 6:59 ` [PATCH] " Yemingxuan
2026-10-20 6:59 ` Yemingxuan
2026-10-20 7:00 ` Yemingxuan
2026-10-20 7:00 ` [PATCH v6] " Yemingxuan
2026-10-20 7:01 ` [PATCH v5] " Yemingxuan
2026-10-20 7:02 ` [PATCH v6] " Yemingxuan
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®