[PATCH 6/9] driver core: async device shutdown infrastructure
sashiko-bot at kernel.org
sashiko-bot at kernel.org
Tue Oct 20 10:19:17 PDT 2026
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] driver core: premature completion in kill_device() races with device_del()
- [Low] driver core: missing kernel-doc for DEV_FLAG_ASYNC_SHUTDOWN
--
commit 82979b053d4cad6e7ae5134feb8f79f9f979e23e
Author: David Jeffery <djeffery at redhat.com>
driver core: async device shutdown infrastructure
This commit introduces asynchronous device shutdown support, allowing
devices flagged with DEV_FLAG_ASYNC_SHUTDOWN to execute their shutdown
callbacks in parallel after waiting for their child and consumer
dependencies to finish shutting down.
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index 93605698affcc..7fee6043dd375 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
[ ... ]
> @@ -3925,6 +3932,7 @@ bool kill_device(struct device *dev)
> if (dev->p->dead)
> return false;
> dev->p->dead = true;
> + complete_all(&dev->p->complete);
> return true;
> }
> EXPORT_SYMBOL_GPL(kill_device);
[Severity: High]
Does signaling dev->p->complete in kill_device() wake parent and supplier
devices too early when a child or consumer device is concurrently removed
via device_del()?
In device_del(), kill_device() is called right at the start before dropping
device_lock(dev), while the actual driver unbinding and resource release
happen later:
drivers/base/core.c:device_del() {
device_lock(dev);
kill_device(dev);
device_unlock(dev);
...
list_for_each_entry(class_intf, &sp->interfaces, node)
if (class_intf->remove_dev)
class_intf->remove_dev(dev);
...
bus_remove_device(dev);
device_pm_remove(dev);
...
devres_release_all(dev);
}
During device_shutdown(), parent and supplier devices wait for child and
consumer devices in wait_for_shutdown_dependencies() ->
wait_for_device_shutdown(), which only waits on dev->p->complete:
if (async || wants_async_shutdown(dev))
wait_for_completion(&dev->p->complete);
Meanwhile, __shutdown_one_device() returns immediately without waiting if
dev->p->dead is set:
if (!dev->p || dev->p->dead)
return;
Before this change, a deleting child or consumer stayed on
devices_kset->list until kobject_del() at the end of device_del(), and
shutdown_one_device() serialized on device_lock(dev) against
bus_remove_device() -> device_release_driver() before device_shutdown()
moved on to the parent or supplier. Similarly, for async suspend,
device_pm_remove() does not call complete_all(&dev->power.completion) until
after bus_remove_device() has completed.
By completing dev->p->complete inside kill_device(), can a parent or
supplier proceed with its ->shutdown() callback and shut down a bus or
controller while its child or consumer is still executing
class_intf->remove_dev(), ->remove(), or devres_release_all()?
[ ... ]
> diff --git a/include/linux/device.h b/include/linux/device.h
> index aee79fd6b32b4..1ebafa7984621 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -612,6 +612,7 @@ enum struct_device_flags {
> DEV_FLAG_OF_NODE_REUSED = 7,
> DEV_FLAG_OFFLINE_DISABLED = 8,
> DEV_FLAG_OFFLINE = 9,
> + DEV_FLAG_ASYNC_SHUTDOWN = 10,
>
> DEV_FLAG_COUNT
> };
[Severity: Low]
enum struct_device_flags has a kernel-doc comment immediately above it (which
is parsed via the :internal: directive in
Documentation/driver-api/infrastructure.rst). Should an entry for
@DEV_FLAG_ASYNC_SHUTDOWN be added to that comment to avoid a kernel-doc
warning?
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261020164435.80499-1-djeffery@redhat.com?part=6
More information about the kexec
mailing list