* [PATCH 4/5] pci: enable async shutdown support
2026-03-11 17:12 [PATCH 1/5] driver core: do not always lock parent in shutdown David Jeffery
@ 2026-03-11 17:12 ` David Jeffery
2026-03-11 23:08 ` Bjorn Helgaas
2026-03-12 5:09 ` Greg Kroah-Hartman
0 siblings, 2 replies; 26+ messages in thread
From: David Jeffery @ 2026-03-11 17:12 UTC (permalink / raw)
To: linux-kernel, driver-core, linux-pci, linux-scsi,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich
Cc: Tarun Sahu, Pasha Tatashin, Michał Cłapiński,
Jordan Richards, Ewan Milne, John Meneghini, Lombardi, Maurizio,
David Jeffery, Stuart Hayes, Laurence Oberman
Like its async suspend support, allow pci device shutdown to be performed
asynchronously to improve shutdown time.
Signed-off-by: David Jeffery <djeffery@redhat.com>
Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Tested-by: Laurence Oberman <loberman@redhat.com>
---
drivers/pci/probe.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index bccc7a4bdd79..4d98bab2163d 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1040,6 +1040,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
bus->bridge = get_device(&bridge->dev);
device_enable_async_suspend(bus->bridge);
+ device_enable_async_shutdown(bus->bridge);
pci_set_bus_of_node(bus);
pci_set_bus_msi_domain(bus);
if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) &&
@@ -2749,6 +2750,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
pci_reassigndev_resource_alignment(dev);
pci_init_capabilities(dev);
+ device_enable_async_shutdown(&dev->dev);
/*
* Add the device to our list of discovered devices
--
2.53.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH 4/5] pci: enable async shutdown support
2026-03-11 17:12 ` [PATCH 4/5] pci: enable async shutdown support David Jeffery
@ 2026-03-11 23:08 ` Bjorn Helgaas
2026-03-12 13:46 ` David Jeffery
2026-03-12 5:09 ` Greg Kroah-Hartman
1 sibling, 1 reply; 26+ messages in thread
From: Bjorn Helgaas @ 2026-03-11 23:08 UTC (permalink / raw)
To: David Jeffery
Cc: linux-kernel, driver-core, linux-pci, linux-scsi,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Tarun Sahu, Pasha Tatashin, Michał Cłapiński,
Jordan Richards, Ewan Milne, John Meneghini, Lombardi, Maurizio,
Stuart Hayes, Laurence Oberman
In subject, to match history:
PCI: Enable async shutdown support
On Wed, Mar 11, 2026 at 01:12:08PM -0400, David Jeffery wrote:
> Like its async suspend support, allow pci device shutdown to be performed
> asynchronously to improve shutdown time.
s/pci/PCI/
s/improve/reduce/
I like how simple this looks, so I hope it all works out.
BTW, something seems messed up in your post threading. I assume this
series is supposed to go with the cover letter at
https://lore.kernel.org/all/20260311170956.9146-1-djeffery@redhat.com,
but the patches don't seem to be replies to the cover letter.
> drivers/pci/probe.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index bccc7a4bdd79..4d98bab2163d 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1040,6 +1040,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
>
> bus->bridge = get_device(&bridge->dev);
> device_enable_async_suspend(bus->bridge);
> + device_enable_async_shutdown(bus->bridge);
> pci_set_bus_of_node(bus);
> pci_set_bus_msi_domain(bus);
> if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) &&
> @@ -2749,6 +2750,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
> pci_reassigndev_resource_alignment(dev);
>
> pci_init_capabilities(dev);
> + device_enable_async_shutdown(&dev->dev);
>
> /*
> * Add the device to our list of discovered devices
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 4/5] pci: enable async shutdown support
2026-03-11 17:12 ` [PATCH 4/5] pci: enable async shutdown support David Jeffery
2026-03-11 23:08 ` Bjorn Helgaas
@ 2026-03-12 5:09 ` Greg Kroah-Hartman
2026-03-12 13:54 ` David Jeffery
1 sibling, 1 reply; 26+ messages in thread
From: Greg Kroah-Hartman @ 2026-03-12 5:09 UTC (permalink / raw)
To: David Jeffery
Cc: linux-kernel, driver-core, linux-pci, linux-scsi,
Rafael J. Wysocki, Danilo Krummrich, Tarun Sahu, Pasha Tatashin,
Michał Cłapiński, Jordan Richards, Ewan Milne,
John Meneghini, Lombardi, Maurizio, Stuart Hayes,
Laurence Oberman
On Wed, Mar 11, 2026 at 01:12:08PM -0400, David Jeffery wrote:
> Like its async suspend support, allow pci device shutdown to be performed
> asynchronously to improve shutdown time.
>
> Signed-off-by: David Jeffery <djeffery@redhat.com>
> Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
> Tested-by: Laurence Oberman <loberman@redhat.com>
> ---
> drivers/pci/probe.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index bccc7a4bdd79..4d98bab2163d 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1040,6 +1040,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
>
> bus->bridge = get_device(&bridge->dev);
> device_enable_async_suspend(bus->bridge);
> + device_enable_async_shutdown(bus->bridge);
> pci_set_bus_of_node(bus);
> pci_set_bus_msi_domain(bus);
> if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) &&
> @@ -2749,6 +2750,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
> pci_reassigndev_resource_alignment(dev);
>
> pci_init_capabilities(dev);
> + device_enable_async_shutdown(&dev->dev);
For all PCI devices? Are you sure this is ok? That feels like it is
going to be ripe with race conditions...
How was this tested?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 4/5] pci: enable async shutdown support
2026-03-11 23:08 ` Bjorn Helgaas
@ 2026-03-12 13:46 ` David Jeffery
0 siblings, 0 replies; 26+ messages in thread
From: David Jeffery @ 2026-03-12 13:46 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-kernel, driver-core, linux-pci, linux-scsi,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Tarun Sahu, Pasha Tatashin, Michał Cłapiński,
Jordan Richards, Ewan Milne, John Meneghini, Lombardi, Maurizio,
Stuart Hayes, Laurence Oberman
On Wed, Mar 11, 2026 at 7:09 PM Bjorn Helgaas <helgaas@kernel.org> wrote:
>
> In subject, to match history:
>
> PCI: Enable async shutdown support
>
> On Wed, Mar 11, 2026 at 01:12:08PM -0400, David Jeffery wrote:
> > Like its async suspend support, allow pci device shutdown to be performed
> > asynchronously to improve shutdown time.
>
> s/pci/PCI/
> s/improve/reduce/
Sure, I can clean up the wording.
> I like how simple this looks, so I hope it all works out.
>
> BTW, something seems messed up in your post threading. I assume this
> series is supposed to go with the cover letter at
> https://lore.kernel.org/all/20260311170956.9146-1-djeffery@redhat.com,
> but the patches don't seem to be replies to the cover letter.
This was from an email issue I should have handled better. For some
reason, send-email hit an error with smtp after sending the cover
letter and failed to send the rest. When I then sent the rest
separately, I failed to consider the threading and didn't think to use
the option to force it to work as a reply to an ID from the already
sent cover letter.
> > drivers/pci/probe.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> > index bccc7a4bdd79..4d98bab2163d 100644
> > --- a/drivers/pci/probe.c
> > +++ b/drivers/pci/probe.c
> > @@ -1040,6 +1040,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
> >
> > bus->bridge = get_device(&bridge->dev);
> > device_enable_async_suspend(bus->bridge);
> > + device_enable_async_shutdown(bus->bridge);
> > pci_set_bus_of_node(bus);
> > pci_set_bus_msi_domain(bus);
> > if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) &&
> > @@ -2749,6 +2750,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
> > pci_reassigndev_resource_alignment(dev);
> >
> > pci_init_capabilities(dev);
> > + device_enable_async_shutdown(&dev->dev);
> >
> > /*
> > * Add the device to our list of discovered devices
> > --
> > 2.53.0
> >
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 4/5] pci: enable async shutdown support
2026-03-12 5:09 ` Greg Kroah-Hartman
@ 2026-03-12 13:54 ` David Jeffery
0 siblings, 0 replies; 26+ messages in thread
From: David Jeffery @ 2026-03-12 13:54 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-kernel, driver-core, linux-pci, linux-scsi,
Rafael J. Wysocki, Danilo Krummrich, Tarun Sahu, Pasha Tatashin,
Michał Cłapiński, Jordan Richards, Ewan Milne,
John Meneghini, Lombardi, Maurizio, Stuart Hayes,
Laurence Oberman
On Thu, Mar 12, 2026 at 1:09 AM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> On Wed, Mar 11, 2026 at 01:12:08PM -0400, David Jeffery wrote:
> > Like its async suspend support, allow pci device shutdown to be performed
> > asynchronously to improve shutdown time.
> >
> > Signed-off-by: David Jeffery <djeffery@redhat.com>
> > Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
> > Tested-by: Laurence Oberman <loberman@redhat.com>
> > ---
> > drivers/pci/probe.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> > index bccc7a4bdd79..4d98bab2163d 100644
> > --- a/drivers/pci/probe.c
> > +++ b/drivers/pci/probe.c
> > @@ -1040,6 +1040,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
> >
> > bus->bridge = get_device(&bridge->dev);
> > device_enable_async_suspend(bus->bridge);
> > + device_enable_async_shutdown(bus->bridge);
> > pci_set_bus_of_node(bus);
> > pci_set_bus_msi_domain(bus);
> > if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) &&
> > @@ -2749,6 +2750,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
> > pci_reassigndev_resource_alignment(dev);
> >
> > pci_init_capabilities(dev);
> > + device_enable_async_shutdown(&dev->dev);
>
> For all PCI devices? Are you sure this is ok? That feels like it is
> going to be ripe with race conditions...
I did not see or find any issues. PCI already enables async suspend on
all devices, it just does so in a power management specific function
so I didn't put device_enable_async_shutdown next to the
device_enable_async_suspend call.
> How was this tested?
It has been running on various VMs and x86_64 physical machines.
> thanks,
>
> greg k-h
>
David Jeffery
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 4/5] PCI: enable async shutdown support
2026-03-19 14:11 [PATCH v12 0/5] shut down devices asynchronously David Jeffery
@ 2026-03-19 14:11 ` David Jeffery
0 siblings, 0 replies; 26+ messages in thread
From: David Jeffery @ 2026-03-19 14:11 UTC (permalink / raw)
To: linux-kernel, driver-core, linux-pci, linux-scsi,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich
Cc: Tarun Sahu, Pasha Tatashin, Michał Cłapiński,
Jordan Richards, Ewan Milne, John Meneghini, Lombardi, Maurizio,
Stuart Hayes, Laurence Oberman, Bart Van Assche, Bjorn Helgaas,
David Jeffery
Like its async suspend support, allow PCI device shutdown to be performed
asynchronously to reduce shutdown time.
Signed-off-by: David Jeffery <djeffery@redhat.com>
Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Tested-by: Laurence Oberman <loberman@redhat.com>
---
drivers/pci/probe.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index bccc7a4bdd79..4d98bab2163d 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1040,6 +1040,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
bus->bridge = get_device(&bridge->dev);
device_enable_async_suspend(bus->bridge);
+ device_enable_async_shutdown(bus->bridge);
pci_set_bus_of_node(bus);
pci_set_bus_msi_domain(bus);
if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) &&
@@ -2749,6 +2750,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
pci_reassigndev_resource_alignment(dev);
pci_init_capabilities(dev);
+ device_enable_async_shutdown(&dev->dev);
/*
* Add the device to our list of discovered devices
--
2.53.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 4/5] PCI: Enable async shutdown support
2026-04-07 15:35 [PATCH v13 0/5] shut down devices asynchronously David Jeffery
@ 2026-04-07 15:35 ` David Jeffery
0 siblings, 0 replies; 26+ messages in thread
From: David Jeffery @ 2026-04-07 15:35 UTC (permalink / raw)
To: linux-kernel, driver-core, linux-pci, linux-scsi,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich
Cc: Tarun Sahu, Pasha Tatashin, Michał Cłapiński,
Jordan Richards, Ewan Milne, John Meneghini, Lombardi, Maurizio,
Stuart Hayes, Laurence Oberman, Bart Van Assche, Bjorn Helgaas,
Martin K . Petersen, David Jeffery
Like its async suspend support, allow PCI device shutdown to be performed
asynchronously to reduce shutdown time.
Signed-off-by: David Jeffery <djeffery@redhat.com>
Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Tested-by: Laurence Oberman <loberman@redhat.com>
---
drivers/pci/probe.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index bccc7a4bdd79..4d98bab2163d 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1040,6 +1040,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
bus->bridge = get_device(&bridge->dev);
device_enable_async_suspend(bus->bridge);
+ device_enable_async_shutdown(bus->bridge);
pci_set_bus_of_node(bus);
pci_set_bus_msi_domain(bus);
if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) &&
@@ -2749,6 +2750,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
pci_reassigndev_resource_alignment(dev);
pci_init_capabilities(dev);
+ device_enable_async_shutdown(&dev->dev);
/*
* Add the device to our list of discovered devices
--
2.53.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 4/5] PCI: Enable async shutdown support
2026-04-20 15:26 [PATCH v14 0/5] shut down devices asynchronously David Jeffery
@ 2026-04-20 15:26 ` David Jeffery
0 siblings, 0 replies; 26+ messages in thread
From: David Jeffery @ 2026-04-20 15:26 UTC (permalink / raw)
To: linux-kernel, driver-core, linux-pci, linux-scsi,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich
Cc: Tarun Sahu, Pasha Tatashin, Michał Cłapiński,
Jordan Richards, Ewan Milne, John Meneghini, Lombardi, Maurizio,
Stuart Hayes, Laurence Oberman, Bart Van Assche, Bjorn Helgaas,
Martin K . Petersen, John Garry, David Jeffery
Like its async suspend support, allow PCI device shutdown to be performed
asynchronously to reduce shutdown time.
Signed-off-by: David Jeffery <djeffery@redhat.com>
Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Tested-by: Laurence Oberman <loberman@redhat.com>
---
drivers/pci/probe.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index bccc7a4bdd79..4d98bab2163d 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1040,6 +1040,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
bus->bridge = get_device(&bridge->dev);
device_enable_async_suspend(bus->bridge);
+ device_enable_async_shutdown(bus->bridge);
pci_set_bus_of_node(bus);
pci_set_bus_msi_domain(bus);
if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) &&
@@ -2749,6 +2750,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
pci_reassigndev_resource_alignment(dev);
pci_init_capabilities(dev);
+ device_enable_async_shutdown(&dev->dev);
/*
* Add the device to our list of discovered devices
--
2.53.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 4/5] PCI: Enable async shutdown support
2026-04-29 17:50 [PATCH v15 0/5] shut down devices asynchronously David Jeffery
@ 2026-04-29 17:50 ` David Jeffery
2026-05-06 18:28 ` Bjorn Helgaas
0 siblings, 1 reply; 26+ messages in thread
From: David Jeffery @ 2026-04-29 17:50 UTC (permalink / raw)
To: linux-kernel, driver-core, linux-pci, linux-scsi,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich
Cc: Tarun Sahu, Pasha Tatashin, Michał Cłapiński,
Jordan Richards, Ewan Milne, John Meneghini, Lombardi, Maurizio,
Stuart Hayes, Laurence Oberman, Bart Van Assche, Bjorn Helgaas,
Martin K . Petersen, John Garry, kexec, David Jeffery,
Pasha Tatashin
Like its async suspend support, allow PCI device shutdown to be performed
asynchronously to reduce shutdown time.
Signed-off-by: David Jeffery <djeffery@redhat.com>
Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Tested-by: Laurence Oberman <loberman@redhat.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
---
drivers/pci/probe.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index b63cd0c310bc..86e855090553 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1045,6 +1045,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
bus->bridge = get_device(&bridge->dev);
device_enable_async_suspend(bus->bridge);
+ device_enable_async_shutdown(bus->bridge);
pci_set_bus_of_node(bus);
pci_set_bus_msi_domain(bus);
if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) &&
@@ -2753,6 +2754,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
pci_reassigndev_resource_alignment(dev);
pci_init_capabilities(dev);
+ device_enable_async_shutdown(&dev->dev);
/*
* Add the device to our list of discovered devices
--
2.53.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH 4/5] PCI: Enable async shutdown support
2026-04-29 17:50 ` [PATCH 4/5] PCI: Enable async shutdown support David Jeffery
@ 2026-05-06 18:28 ` Bjorn Helgaas
2026-05-06 21:10 ` David Jeffery
0 siblings, 1 reply; 26+ messages in thread
From: Bjorn Helgaas @ 2026-05-06 18:28 UTC (permalink / raw)
To: David Jeffery
Cc: linux-kernel, driver-core, linux-pci, linux-scsi,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Tarun Sahu, Pasha Tatashin, Michał Cłapiński,
Jordan Richards, Ewan Milne, John Meneghini, Lombardi, Maurizio,
Stuart Hayes, Laurence Oberman, Bart Van Assche,
Martin K . Petersen, John Garry, kexec, Pasha Tatashin
On Wed, Apr 29, 2026 at 01:50:15PM -0400, David Jeffery wrote:
> Like its async suspend support, allow PCI device shutdown to be performed
> asynchronously to reduce shutdown time.
>
> Signed-off-by: David Jeffery <djeffery@redhat.com>
> Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
> Tested-by: Laurence Oberman <loberman@redhat.com>
> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
> Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Reviewed-by: Bjorn Helgaas <bhelgaas@google.com>
I'm concerned about tripping over driver issues, but it's a pretty big
benefit. I think it's worth mentioning the "async_shutdown" module
parameter somewhere in the commit logs and putting an example in
Documentation/admin-guide/kernel-parameters.txt.
Might even consider keeping in -next for a cycle+ and targeting v7.3.
> ---
> drivers/pci/probe.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index b63cd0c310bc..86e855090553 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1045,6 +1045,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
>
> bus->bridge = get_device(&bridge->dev);
> device_enable_async_suspend(bus->bridge);
> + device_enable_async_shutdown(bus->bridge);
> pci_set_bus_of_node(bus);
> pci_set_bus_msi_domain(bus);
> if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) &&
> @@ -2753,6 +2754,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
> pci_reassigndev_resource_alignment(dev);
>
> pci_init_capabilities(dev);
> + device_enable_async_shutdown(&dev->dev);
>
> /*
> * Add the device to our list of discovered devices
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 4/5] PCI: Enable async shutdown support
2026-05-06 18:28 ` Bjorn Helgaas
@ 2026-05-06 21:10 ` David Jeffery
2026-05-06 21:24 ` Bjorn Helgaas
0 siblings, 1 reply; 26+ messages in thread
From: David Jeffery @ 2026-05-06 21:10 UTC (permalink / raw)
To: Bjorn Helgaas, Greg Kroah-Hartman
Cc: linux-kernel, driver-core, linux-pci, linux-scsi,
Rafael J. Wysocki, Danilo Krummrich, Tarun Sahu, Pasha Tatashin,
Michał Cłapiński, Jordan Richards, Ewan Milne,
John Meneghini, Lombardi, Maurizio, Stuart Hayes,
Laurence Oberman, Bart Van Assche, Martin K . Petersen,
John Garry, kexec, Pasha Tatashin
On Wed, May 6, 2026 at 2:28 PM Bjorn Helgaas <helgaas@kernel.org> wrote:
>
> On Wed, Apr 29, 2026 at 01:50:15PM -0400, David Jeffery wrote:
> > Like its async suspend support, allow PCI device shutdown to be performed
> > asynchronously to reduce shutdown time.
> >
> > Signed-off-by: David Jeffery <djeffery@redhat.com>
> > Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
> > Tested-by: Laurence Oberman <loberman@redhat.com>
> > Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
> > Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
>
> Reviewed-by: Bjorn Helgaas <bhelgaas@google.com>
>
> I'm concerned about tripping over driver issues, but it's a pretty big
> benefit. I think it's worth mentioning the "async_shutdown" module
> parameter somewhere in the commit logs and putting an example in
> Documentation/admin-guide/kernel-parameters.txt.
Sure, I can see about adding a document patch to it.
> Might even consider keeping in -next for a cycle+ and targeting v7.3.
I would be happy for it to spend as much time in linux-next as needed
for people to be comfortable with the risk of odd interactions with
all the pci drivers it will indirectly impact.
But I must admit my ignorance with some of the details of linux-next.
Looking at the main code changes, the patchset would seem to want to
go through driver-core to get to linux-next. But as far as indirect
impact, it is the diverse collection of devices and drivers under PCI
which are most affected by the changes. Is there a consensus on how to
steward a patchset like this one into linux-next?
David Jeffery
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 4/5] PCI: Enable async shutdown support
2026-05-06 21:10 ` David Jeffery
@ 2026-05-06 21:24 ` Bjorn Helgaas
0 siblings, 0 replies; 26+ messages in thread
From: Bjorn Helgaas @ 2026-05-06 21:24 UTC (permalink / raw)
To: David Jeffery
Cc: Greg Kroah-Hartman, linux-kernel, driver-core, linux-pci,
linux-scsi, Rafael J. Wysocki, Danilo Krummrich, Tarun Sahu,
Pasha Tatashin, Michał Cłapiński, Jordan Richards,
Ewan Milne, John Meneghini, Lombardi, Maurizio, Stuart Hayes,
Laurence Oberman, Bart Van Assche, Martin K . Petersen,
John Garry, kexec, Pasha Tatashin
On Wed, May 06, 2026 at 05:10:19PM -0400, David Jeffery wrote:
> On Wed, May 6, 2026 at 2:28 PM Bjorn Helgaas <helgaas@kernel.org> wrote:
> > On Wed, Apr 29, 2026 at 01:50:15PM -0400, David Jeffery wrote:
> > > Like its async suspend support, allow PCI device shutdown to be performed
> > > asynchronously to reduce shutdown time.
> > >
> > > Signed-off-by: David Jeffery <djeffery@redhat.com>
> > > Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
> > > Tested-by: Laurence Oberman <loberman@redhat.com>
> > > Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
> > > Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
> >
> > Reviewed-by: Bjorn Helgaas <bhelgaas@google.com>
> >
> > I'm concerned about tripping over driver issues, but it's a pretty big
> > benefit. I think it's worth mentioning the "async_shutdown" module
> > parameter somewhere in the commit logs and putting an example in
> > Documentation/admin-guide/kernel-parameters.txt.
>
> Sure, I can see about adding a document patch to it.
>
> > Might even consider keeping in -next for a cycle+ and targeting v7.3.
>
> I would be happy for it to spend as much time in linux-next as needed
> for people to be comfortable with the risk of odd interactions with
> all the pci drivers it will indirectly impact.
>
> But I must admit my ignorance with some of the details of linux-next.
> Looking at the main code changes, the patchset would seem to want to
> go through driver-core to get to linux-next. But as far as indirect
> impact, it is the diverse collection of devices and drivers under PCI
> which are most affected by the changes. Is there a consensus on how to
> steward a patchset like this one into linux-next?
My guess is it should all go via the driver-core tree, given acks or
reviewed-by from the other subsystems it touches.
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 4/5] PCI: Enable async shutdown support
2026-05-18 19:31 [PATCH v16 0/5] shut down devices asynchronously David Jeffery
@ 2026-05-18 19:32 ` David Jeffery
0 siblings, 0 replies; 26+ messages in thread
From: David Jeffery @ 2026-05-18 19:32 UTC (permalink / raw)
To: linux-kernel, driver-core, linux-pci, linux-scsi,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich
Cc: Tarun Sahu, Pasha Tatashin, Michał Cłapiński,
Jordan Richards, Ewan Milne, John Meneghini, Lombardi, Maurizio,
Stuart Hayes, Laurence Oberman, Bart Van Assche, Bjorn Helgaas,
Martin K . Petersen, John Garry, kexec, David Jeffery,
Pasha Tatashin, Bjorn Helgaas
Like its async suspend support, allow PCI device shutdown to be performed
asynchronously to reduce shutdown time.
Signed-off-by: David Jeffery <djeffery@redhat.com>
Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Tested-by: Laurence Oberman <loberman@redhat.com>
Tested-by: Tarun Sahu <tarunsahu@google.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Reviewed-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/pci/probe.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index b63cd0c310bc..7cf3dabc885e 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1045,6 +1045,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
bus->bridge = get_device(&bridge->dev);
device_enable_async_suspend(bus->bridge);
+ dev_set_async_shutdown(bus->bridge);
pci_set_bus_of_node(bus);
pci_set_bus_msi_domain(bus);
if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) &&
@@ -2753,6 +2754,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
pci_reassigndev_resource_alignment(dev);
pci_init_capabilities(dev);
+ dev_set_async_shutdown(&dev->dev);
/*
* Add the device to our list of discovered devices
--
2.53.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v17 0/5] shut down devices asynchronously
@ 2026-06-16 15:22 David Jeffery
2026-06-16 15:22 ` [PATCH 1/5] driver core: separate function to shutdown one device David Jeffery
` (4 more replies)
0 siblings, 5 replies; 26+ messages in thread
From: David Jeffery @ 2026-06-16 15:22 UTC (permalink / raw)
To: driver-core, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich
Cc: linux-kernel, linux-pci, linux-scsi, Tarun Sahu, Pasha Tatashin,
Michał Cłapiński, Jordan Richards, Ewan Milne,
John Meneghini, Lombardi, Maurizio, Stuart Hayes,
Laurence Oberman, Bart Van Assche, Bjorn Helgaas,
Martin K . Petersen, John Garry, kexec, David Jeffery
These patches are rebased against the driver-core tree's driver-core-next
branch and should also apply against recent linux-next. Changes for v17 are
contained in patches 2 and 3 which are most in need of reviewing.
This patchset allows the kernel to shutdown devices asynchronously and
unrelated async devices to be shut down in parallel to each other.
Only devices which explicitly enable it are shut down asynchronously. The
default is for a device to be shut down from the synchronous shutdown loop.
This can dramatically reduce system shutdown/reboot time on systems that
have multiple devices that take many seconds to shut down (like certain
NVMe drives). On one system tested, the shutdown time went from 11 minutes
without this patch to 55 seconds with the patch. And on another system from
80 seconds to 11.
And thank you to everyone who has spent some of their valuable time
providing reviews, suggestions, criticisms, or tests on the various
iterations of this patchset.
Changes from V16:
Drop spinlock before async subsystem call which uses GFP_KERNEL
Handle that async shutdown can widen races between device shutdown and deletion
* __shutdown_one_device will immediately return if a device is dead
* Set shutdown device completion to complete when marking a device dead to
prevent waiting on a dead device
* Only late-access a parent pointer if device is in a non-dead state to
ensure the pointer is still valid
Changes from V15:
The async_shutdown bit field is converted to a device flags bit
Convert all patches to use the flag bit accessor macros to set or check if
async shutdown should be used
Added documentation on the kernel parameter to control use of async shutdown
Changes from V14:
Remove unneeded use of '!!' with boolean type
Changes from V13:
Remove duplicate flagging of async shutdown on scsi hosts/targets/devices
Changes from V12:
Only acquire a parent reference if acquiring the parent's lock
device_enable_async_shutdown should return void
Minor comment and description cleanups
Changes from V11:
* Swap the order of the first two patches
* Rework conditional parent locking so that lock and unlock no longer use
separate conditional checks
* Remove an used variable
* Comment and description text cleanups
Changes from V10:
Reworked to more closely match the design used for async suspend
* No longer uses async subsystem cookies for synchronization
* Minimized changes to struct device
* Enable async shutdown for pci and scsi devices which support async suspend
Changes from V9:
Address resource and timing issues when spawning a unique async thread
for every device during shutdown:
* Make the asynchronous threads able to shut down multiple devices,
instead of spawning a unique thread for every device.
* Modify core kernel async code with a custom wake function so it
doesn't wake up a thread waiting to synchronize on a cookie until
the cookie has reached the desired value, instead of waking up
every waiting thread to check the cookie every time an async thread
ends.
Changes from V8:
Deal with shutdown hangs resulting when a parent/supplier device is
later in the devices_kset list than its children/consumers:
* Ignore sync_state_only devlinks for shutdown dependencies
* Ignore shutdown_after for devices that don't want async shutdown
* Add a sanity check to revert to sync shutdown for any device that
would otherwise wait for a child/consumer shutdown that hasn't
already been scheduled
Changes from V7:
Do not expose driver async_shutdown_enable in sysfs.
Wrapped a long line.
Changes from V6:
Removed a sysfs attribute that allowed the async device shutdown to be
"on" (with driver opt-out), "safe" (driver opt-in), or "off"... what was
previously "safe" is now the only behavior, so drivers now only need to
have the option to enable or disable async shutdown.
Changes from V5:
Separated into multiple patches to make review easier.
Reworked some code to make it more readable
Made devices wait for consumers to shut down, not just children
(suggested by David Jeffery)
Changes from V4:
Change code to use cookies for synchronization rather than async domains
Allow async shutdown to be disabled via sysfs, and allow driver opt-in or
opt-out of async shutdown (when not disabled), with ability to control
driver opt-in/opt-out via sysfs
Changes from V3:
Bug fix (used "parent" not "dev->parent" in device_shutdown)
Changes from V2:
Removed recursive functions to schedule children to be shutdown before
parents, since existing device_shutdown loop will already do this
Changes from V1:
Rewritten using kernel async code (suggested by Lukas Wunner)
Stuart Hayes (2):
driver core: separate function to shutdown one device
driver core: do not always lock parent in shutdown
David Jeffery (3):
driver core: async device shutdown infrastructure
PCI: Enable async shutdown support
scsi: Enable async shutdown support
.../admin-guide/kernel-parameters.txt | 10 +
drivers/base/base.h | 2 +
drivers/base/core.c | 214 +++++++++++++++---
drivers/pci/probe.c | 2 +
drivers/scsi/hosts.c | 2 +
drivers/scsi/scsi_sysfs.c | 3 +
include/linux/device.h | 2 +
7 files changed, 199 insertions(+), 36 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 1/5] driver core: separate function to shutdown one device
2026-06-16 15:22 [PATCH v17 0/5] shut down devices asynchronously David Jeffery
@ 2026-06-16 15:22 ` David Jeffery
2026-06-16 15:34 ` sashiko-bot
2026-06-16 15:22 ` [PATCH 2/5] driver core: do not always lock parent in shutdown David Jeffery
` (3 subsequent siblings)
4 siblings, 1 reply; 26+ messages in thread
From: David Jeffery @ 2026-06-16 15:22 UTC (permalink / raw)
To: driver-core, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich
Cc: linux-kernel, linux-pci, linux-scsi, Tarun Sahu, Pasha Tatashin,
Michał Cłapiński, Jordan Richards, Ewan Milne,
John Meneghini, Lombardi, Maurizio, Stuart Hayes,
Laurence Oberman, Bart Van Assche, Bjorn Helgaas,
Martin K . Petersen, John Garry, kexec, David Jeffery,
Pasha Tatashin
Make a separate function for the part of device_shutdown() that does the
shutown for a single device. This is in preparation for making device
shutdown asynchronous.
Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Signed-off-by: David Jeffery <djeffery@redhat.com>
Tested-by: Laurence Oberman <loberman@redhat.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
---
drivers/base/core.c | 71 +++++++++++++++++++++++++--------------------
1 file changed, 39 insertions(+), 32 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 4d026682944f..74c693cd19cf 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -4865,12 +4865,48 @@ int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid)
return error;
}
+static void shutdown_one_device(struct device *dev)
+{
+ struct device *parent = dev->parent;
+
+ /* hold lock to avoid race with probe/release */
+ if (parent)
+ device_lock(parent);
+ device_lock(dev);
+
+ /* Don't allow any more runtime suspends */
+ pm_runtime_get_noresume(dev);
+ pm_runtime_barrier(dev);
+
+ if (dev->class && dev->class->shutdown_pre) {
+ if (initcall_debug)
+ dev_info(dev, "shutdown_pre\n");
+ dev->class->shutdown_pre(dev);
+ }
+ if (dev->bus && dev->bus->shutdown) {
+ if (initcall_debug)
+ dev_info(dev, "shutdown\n");
+ dev->bus->shutdown(dev);
+ } else if (dev->driver && dev->driver->shutdown) {
+ if (initcall_debug)
+ dev_info(dev, "shutdown\n");
+ dev->driver->shutdown(dev);
+ }
+
+ device_unlock(dev);
+ if (parent)
+ device_unlock(parent);
+
+ put_device(parent);
+ put_device(dev);
+}
+
/**
* device_shutdown - call ->shutdown() on each device to shutdown.
*/
void device_shutdown(void)
{
- struct device *dev, *parent;
+ struct device *dev;
wait_for_device_probe();
device_block_probing();
@@ -4892,7 +4928,7 @@ void device_shutdown(void)
* prevent it from being freed because parent's
* lock is to be held
*/
- parent = get_device(dev->parent);
+ get_device(dev->parent);
get_device(dev);
/*
* Make sure the device is off the kset list, in the
@@ -4901,36 +4937,7 @@ void device_shutdown(void)
list_del_init(&dev->kobj.entry);
spin_unlock(&devices_kset->list_lock);
- /* hold lock to avoid race with probe/release */
- if (parent)
- device_lock(parent);
- device_lock(dev);
-
- /* Don't allow any more runtime suspends */
- pm_runtime_get_noresume(dev);
- pm_runtime_barrier(dev);
-
- if (dev->class && dev->class->shutdown_pre) {
- if (initcall_debug)
- dev_info(dev, "shutdown_pre\n");
- dev->class->shutdown_pre(dev);
- }
- if (dev->bus && dev->bus->shutdown) {
- if (initcall_debug)
- dev_info(dev, "shutdown\n");
- dev->bus->shutdown(dev);
- } else if (dev->driver && dev->driver->shutdown) {
- if (initcall_debug)
- dev_info(dev, "shutdown\n");
- dev->driver->shutdown(dev);
- }
-
- device_unlock(dev);
- if (parent)
- device_unlock(parent);
-
- put_device(dev);
- put_device(parent);
+ shutdown_one_device(dev);
spin_lock(&devices_kset->list_lock);
}
--
2.54.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 2/5] driver core: do not always lock parent in shutdown
2026-06-16 15:22 [PATCH v17 0/5] shut down devices asynchronously David Jeffery
2026-06-16 15:22 ` [PATCH 1/5] driver core: separate function to shutdown one device David Jeffery
@ 2026-06-16 15:22 ` David Jeffery
2026-06-16 15:38 ` sashiko-bot
2026-06-16 15:22 ` [PATCH 3/5] driver core: async device shutdown infrastructure David Jeffery
` (2 subsequent siblings)
4 siblings, 1 reply; 26+ messages in thread
From: David Jeffery @ 2026-06-16 15:22 UTC (permalink / raw)
To: driver-core, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich
Cc: linux-kernel, linux-pci, linux-scsi, Tarun Sahu, Pasha Tatashin,
Michał Cłapiński, Jordan Richards, Ewan Milne,
John Meneghini, Lombardi, Maurizio, Stuart Hayes,
Laurence Oberman, Bart Van Assche, Bjorn Helgaas,
Martin K . Petersen, John Garry, kexec, David Jeffery
Don't lock a parent device unless it is needed in device_shutdown. This
is in preparation for making device shutdown asynchronous, when it will
be needed to allow children of a common parent to shut down
simultaneously.
And only acquire a reference to the parent device if the parent is to be
locked.
Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Signed-off-by: David Jeffery <djeffery@redhat.com>
Tested-by: Laurence Oberman <loberman@redhat.com>
---
drivers/base/core.c | 42 ++++++++++++++++++++++++++----------------
1 file changed, 26 insertions(+), 16 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 74c693cd19cf..3b3d983b1747 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -4865,14 +4865,10 @@ int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid)
return error;
}
-static void shutdown_one_device(struct device *dev)
+static void __shutdown_one_device(struct device *dev)
{
- struct device *parent = dev->parent;
-
- /* hold lock to avoid race with probe/release */
- if (parent)
- device_lock(parent);
- device_lock(dev);
+ if (dev->p->dead)
+ return;
/* Don't allow any more runtime suspends */
pm_runtime_get_noresume(dev);
@@ -4892,12 +4888,32 @@ static void shutdown_one_device(struct device *dev)
dev_info(dev, "shutdown\n");
dev->driver->shutdown(dev);
}
+}
- device_unlock(dev);
- if (parent)
+static void shutdown_one_device(struct device *dev)
+{
+ struct device *parent;
+
+ device_lock(dev);
+
+ /* use parent lock if needed to avoid race with probe/release */
+ if (dev->bus && dev->bus->need_parent_lock && !dev->p->dead &&
+ (parent = get_device(dev->parent))) {
+ /* the parent lock needs to be acquired first, so re-lock */
+ device_unlock(dev);
+
+ device_lock(parent);
+ device_lock(dev);
+
+ __shutdown_one_device(dev);
+ device_unlock(dev);
device_unlock(parent);
+ put_device(parent);
+ } else {
+ __shutdown_one_device(dev);
+ device_unlock(dev);
+ }
- put_device(parent);
put_device(dev);
}
@@ -4923,12 +4939,6 @@ void device_shutdown(void)
dev = list_entry(devices_kset->list.prev, struct device,
kobj.entry);
- /*
- * hold reference count of device's parent to
- * prevent it from being freed because parent's
- * lock is to be held
- */
- get_device(dev->parent);
get_device(dev);
/*
* Make sure the device is off the kset list, in the
--
2.54.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 3/5] driver core: async device shutdown infrastructure
2026-06-16 15:22 [PATCH v17 0/5] shut down devices asynchronously David Jeffery
2026-06-16 15:22 ` [PATCH 1/5] driver core: separate function to shutdown one device David Jeffery
2026-06-16 15:22 ` [PATCH 2/5] driver core: do not always lock parent in shutdown David Jeffery
@ 2026-06-16 15:22 ` David Jeffery
2026-06-16 15:39 ` sashiko-bot
` (2 more replies)
2026-06-16 15:22 ` [PATCH 4/5] PCI: Enable async shutdown support David Jeffery
2026-06-16 15:22 ` [PATCH 5/5] scsi: " David Jeffery
4 siblings, 3 replies; 26+ messages in thread
From: David Jeffery @ 2026-06-16 15:22 UTC (permalink / raw)
To: driver-core, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich
Cc: linux-kernel, linux-pci, linux-scsi, Tarun Sahu, Pasha Tatashin,
Michał Cłapiński, Jordan Richards, Ewan Milne,
John Meneghini, Lombardi, Maurizio, Stuart Hayes,
Laurence Oberman, Bart Van Assche, Bjorn Helgaas,
Martin K . Petersen, John Garry, kexec, David Jeffery
Patterned after async suspend, allow devices to mark themselves as wanting
to perform async shutdown. Devices using async shutdown wait only for their
dependencies to shutdown before executing their shutdown routine.
Sync shutdown devices are shut down one at a time and will only wait for an
async shutdown device if the async device is a dependency.
Enabled by default, async shutdown can be explicitly enabled or disabled
by using the kernel parameter "core.async_shutdown=<bool>"
Signed-off-by: David Jeffery <djeffery@redhat.com>
Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Tested-by: Laurence Oberman <loberman@redhat.com>
---
.../admin-guide/kernel-parameters.txt | 10 ++
drivers/base/base.h | 2 +
drivers/base/core.c | 127 +++++++++++++++++-
include/linux/device.h | 2 +
4 files changed, 140 insertions(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index b5a51a36a048..dd912f47ace4 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1019,6 +1019,16 @@ Kernel parameters
seconds. A value of 0 disables the blank timer.
Defaults to 0.
+ core.async_shutdown=
+ [KNL]
+ Format: <bool>
+ Enable or disable asynchronous shutdown support. When
+ enabled, on system shutdown unrelated devices flagged
+ as async shutdown compatible may be shut down in
+ parallel and asynchronously. When disabled, device
+ shutdown is performed in a serially and synchronously.
+ Enabled by default.
+
coredump_filter=
[KNL] Change the default value for
/proc/<pid>/coredump_filter.
diff --git a/drivers/base/base.h b/drivers/base/base.h
index a5b7abc10ff0..40dbf588a5d6 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -103,6 +103,7 @@ struct driver_private {
* dev_err_probe() for later retrieval via debugfs
* @device: pointer back to the struct device that this structure is
* associated with.
+ * @complete: completion for device shutdown ordering
* @dead: This device is currently either in the process of or has been
* removed from the system. Any asynchronous events scheduled for this
* device should exit without taking any action.
@@ -119,6 +120,7 @@ struct device_private {
const struct device_driver *async_driver;
char *deferred_probe_reason;
struct device *device;
+ struct completion complete;
u8 dead:1;
};
#define to_device_private_parent(obj) \
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 3b3d983b1747..751fe2e13b3a 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -9,6 +9,7 @@
*/
#include <linux/acpi.h>
+#include <linux/async.h>
#include <linux/blkdev.h>
#include <linux/cleanup.h>
#include <linux/cpufreq.h>
@@ -37,6 +38,10 @@
#include "physical_location.h"
#include "power/power.h"
+static bool async_shutdown = true;
+module_param(async_shutdown, bool, 0644);
+MODULE_PARM_DESC(async_shutdown, "Enable asynchronous device shutdown support");
+
/* Device links support. */
static LIST_HEAD(deferred_sync);
static unsigned int defer_sync_state_count = 1;
@@ -3606,6 +3611,7 @@ static int device_private_init(struct device *dev)
klist_init(&dev->p->klist_children, klist_children_get,
klist_children_put);
INIT_LIST_HEAD(&dev->p->deferred_probe);
+ init_completion(&dev->p->complete);
return 0;
}
@@ -3895,6 +3901,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);
@@ -4865,6 +4872,37 @@ int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid)
return error;
}
+static bool wants_async_shutdown(struct device *dev)
+{
+ return async_shutdown && dev_async_shutdown(dev);
+}
+
+static int wait_for_device_shutdown(struct device *dev, void *data)
+{
+ bool async = *(bool *)data;
+
+ if (async || wants_async_shutdown(dev))
+ wait_for_completion(&dev->p->complete);
+
+ return 0;
+}
+
+static void wait_for_shutdown_dependencies(struct device *dev, bool async)
+{
+ struct device_link *link;
+ int idx;
+
+ device_for_each_child(dev, &async, wait_for_device_shutdown);
+
+ idx = device_links_read_lock();
+
+ dev_for_each_link_to_consumer(link, dev)
+ if (!device_link_flag_is_sync_state_only(link->flags))
+ wait_for_device_shutdown(link->consumer, &async);
+
+ device_links_read_unlock(idx);
+}
+
static void __shutdown_one_device(struct device *dev)
{
if (dev->p->dead)
@@ -4888,6 +4926,8 @@ static void __shutdown_one_device(struct device *dev)
dev_info(dev, "shutdown\n");
dev->driver->shutdown(dev);
}
+
+ complete_all(&dev->p->complete);
}
static void shutdown_one_device(struct device *dev)
@@ -4917,6 +4957,80 @@ static void shutdown_one_device(struct device *dev)
put_device(dev);
}
+static void async_shutdown_handler(void *data, async_cookie_t cookie)
+{
+ struct device *dev = data;
+
+ wait_for_shutdown_dependencies(dev, true);
+ shutdown_one_device(dev);
+}
+
+static bool shutdown_device_async(struct device *dev)
+{
+ if (async_schedule_dev_nocall(async_shutdown_handler, dev))
+ return true;
+
+ dev_clear_async_shutdown(dev);
+ return false;
+}
+
+
+static void start_async_shutdown_devices(void)
+{
+ struct device *dev, *next, *ndev, *needs_put = NULL;
+ bool clear_async = false;
+
+ if (!async_shutdown)
+ return;
+
+ spin_lock(&devices_kset->list_lock);
+restart:
+ list_for_each_entry_safe_reverse(dev, next, &devices_kset->list,
+ kobj.entry) {
+ if (wants_async_shutdown(dev)) {
+ if (clear_async) {
+ dev_clear_async_shutdown(dev);
+ continue;
+ }
+ get_device(dev);
+
+ if (!list_entry_is_head(next, &devices_kset->list,
+ kobj.entry))
+ ndev = get_device(next);
+ else
+ ndev = NULL;
+ spin_unlock(&devices_kset->list_lock);
+
+ if (shutdown_device_async(dev)) {
+ list_del_init(&dev->kobj.entry);
+ } else {
+ /*
+ * async failed, clean up extra reference
+ * and run shutdown from the sync shutdown loop
+ */
+ clear_async = true;
+ put_device(dev);
+ }
+ if (needs_put)
+ put_device(needs_put);
+ needs_put = ndev;
+ spin_lock(&devices_kset->list_lock);
+ /*
+ * If the next device has been marked dead while the
+ * spinlock was released, it may no longer be on the
+ * devices_kset list. Restart the list walk to be safe
+ */
+ if (ndev && ndev->p->dead)
+ goto restart;
+ }
+ }
+
+ spin_unlock(&devices_kset->list_lock);
+
+ if (needs_put)
+ put_device(needs_put);
+}
+
/**
* device_shutdown - call ->shutdown() on each device to shutdown.
*/
@@ -4929,6 +5043,12 @@ void device_shutdown(void)
cpufreq_suspend();
+ /*
+ * Start async device threads where possible to maximize potential
+ * parallelism and minimize false dependency on unrelated sync devices
+ */
+ start_async_shutdown_devices();
+
spin_lock(&devices_kset->list_lock);
/*
* Walk the devices list backward, shutting down each in turn.
@@ -4947,11 +5067,16 @@ void device_shutdown(void)
list_del_init(&dev->kobj.entry);
spin_unlock(&devices_kset->list_lock);
- shutdown_one_device(dev);
+ if (!wants_async_shutdown(dev) || !shutdown_device_async(dev)) {
+ wait_for_shutdown_dependencies(dev, false);
+ shutdown_one_device(dev);
+ }
spin_lock(&devices_kset->list_lock);
}
spin_unlock(&devices_kset->list_lock);
+
+ async_synchronize_full();
}
/*
diff --git a/include/linux/device.h b/include/linux/device.h
index 7b2baffdd2f5..f913d72218f8 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -610,6 +610,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
};
@@ -827,6 +828,7 @@ __create_dev_flag_accessors(dma_coherent, DEV_FLAG_DMA_COHERENT);
__create_dev_flag_accessors(of_node_reused, DEV_FLAG_OF_NODE_REUSED);
__create_dev_flag_accessors(offline_disabled, DEV_FLAG_OFFLINE_DISABLED);
__create_dev_flag_accessors(offline, DEV_FLAG_OFFLINE);
+__create_dev_flag_accessors(async_shutdown, DEV_FLAG_ASYNC_SHUTDOWN);
#undef __create_dev_flag_accessors
--
2.54.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 4/5] PCI: Enable async shutdown support
2026-06-16 15:22 [PATCH v17 0/5] shut down devices asynchronously David Jeffery
` (2 preceding siblings ...)
2026-06-16 15:22 ` [PATCH 3/5] driver core: async device shutdown infrastructure David Jeffery
@ 2026-06-16 15:22 ` David Jeffery
2026-06-16 15:38 ` sashiko-bot
2026-06-16 15:22 ` [PATCH 5/5] scsi: " David Jeffery
4 siblings, 1 reply; 26+ messages in thread
From: David Jeffery @ 2026-06-16 15:22 UTC (permalink / raw)
To: driver-core, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich
Cc: linux-kernel, linux-pci, linux-scsi, Tarun Sahu, Pasha Tatashin,
Michał Cłapiński, Jordan Richards, Ewan Milne,
John Meneghini, Lombardi, Maurizio, Stuart Hayes,
Laurence Oberman, Bart Van Assche, Bjorn Helgaas,
Martin K . Petersen, John Garry, kexec, David Jeffery,
Pasha Tatashin, Bjorn Helgaas
Like its async suspend support, allow PCI device shutdown to be performed
asynchronously to reduce shutdown time.
Signed-off-by: David Jeffery <djeffery@redhat.com>
Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Tested-by: Laurence Oberman <loberman@redhat.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Reviewed-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/pci/probe.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index b63cd0c310bc..7cf3dabc885e 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1045,6 +1045,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
bus->bridge = get_device(&bridge->dev);
device_enable_async_suspend(bus->bridge);
+ dev_set_async_shutdown(bus->bridge);
pci_set_bus_of_node(bus);
pci_set_bus_msi_domain(bus);
if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) &&
@@ -2753,6 +2754,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
pci_reassigndev_resource_alignment(dev);
pci_init_capabilities(dev);
+ dev_set_async_shutdown(&dev->dev);
/*
* Add the device to our list of discovered devices
--
2.54.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 5/5] scsi: Enable async shutdown support
2026-06-16 15:22 [PATCH v17 0/5] shut down devices asynchronously David Jeffery
` (3 preceding siblings ...)
2026-06-16 15:22 ` [PATCH 4/5] PCI: Enable async shutdown support David Jeffery
@ 2026-06-16 15:22 ` David Jeffery
2026-06-16 15:44 ` sashiko-bot
4 siblings, 1 reply; 26+ messages in thread
From: David Jeffery @ 2026-06-16 15:22 UTC (permalink / raw)
To: driver-core, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich
Cc: linux-kernel, linux-pci, linux-scsi, Tarun Sahu, Pasha Tatashin,
Michał Cłapiński, Jordan Richards, Ewan Milne,
John Meneghini, Lombardi, Maurizio, Stuart Hayes,
Laurence Oberman, Bart Van Assche, Bjorn Helgaas,
Martin K . Petersen, John Garry, kexec, David Jeffery,
Pasha Tatashin
Like scsi's async suspend support, allow scsi devices to be shut down
asynchronously to reduce system shutdown time.
Signed-off-by: David Jeffery <djeffery@redhat.com>
Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Tested-by: Laurence Oberman <loberman@redhat.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Reviewed-by: John Garry <john.g.garry@oracle.com>
---
drivers/scsi/hosts.c | 2 ++
drivers/scsi/scsi_sysfs.c | 3 +++
2 files changed, 5 insertions(+)
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index e047747d4ecf..bf691acc7a67 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -273,6 +273,7 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
pm_runtime_set_active(&shost->shost_gendev);
pm_runtime_enable(&shost->shost_gendev);
device_enable_async_suspend(&shost->shost_gendev);
+ dev_set_async_shutdown(&shost->shost_gendev);
error = device_add(&shost->shost_gendev);
if (error)
@@ -282,6 +283,7 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
get_device(shost->shost_gendev.parent);
device_enable_async_suspend(&shost->shost_dev);
+ dev_set_async_shutdown(&shost->shost_dev);
get_device(&shost->shost_gendev);
error = device_add(&shost->shost_dev);
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index dfc3559e7e04..8fd317aef37b 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -1386,6 +1386,7 @@ static int scsi_target_add(struct scsi_target *starget)
pm_runtime_set_active(&starget->dev);
pm_runtime_enable(&starget->dev);
device_enable_async_suspend(&starget->dev);
+ dev_set_async_shutdown(&starget->dev);
return 0;
}
@@ -1412,6 +1413,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
transport_configure_device(&starget->dev);
device_enable_async_suspend(&sdev->sdev_gendev);
+ dev_set_async_shutdown(&sdev->sdev_gendev);
scsi_autopm_get_target(starget);
pm_runtime_set_active(&sdev->sdev_gendev);
if (!sdev->rpm_autosuspend)
@@ -1431,6 +1433,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
}
device_enable_async_suspend(&sdev->sdev_dev);
+ dev_set_async_shutdown(&sdev->sdev_dev);
error = device_add(&sdev->sdev_dev);
if (error) {
sdev_printk(KERN_INFO, sdev,
--
2.54.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH 1/5] driver core: separate function to shutdown one device
2026-06-16 15:22 ` [PATCH 1/5] driver core: separate function to shutdown one device David Jeffery
@ 2026-06-16 15:34 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-06-16 15:34 UTC (permalink / raw)
To: David Jeffery; +Cc: linux-scsi, linux-pci
> Make a separate function for the part of device_shutdown() that does the
> shutown for a single device. This is in preparation for making device
> shutdown asynchronous.
>
> Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
> Signed-off-by: David Jeffery <djeffery@redhat.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260616152219.6268-1-djeffery@redhat.com?part=1
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 2/5] driver core: do not always lock parent in shutdown
2026-06-16 15:22 ` [PATCH 2/5] driver core: do not always lock parent in shutdown David Jeffery
@ 2026-06-16 15:38 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-06-16 15:38 UTC (permalink / raw)
To: David Jeffery; +Cc: linux-scsi, linux-pci
> Don't lock a parent device unless it is needed in device_shutdown. This
> is in preparation for making device shutdown asynchronous, when it will
> be needed to allow children of a common parent to shut down
> simultaneously.
>
> And only acquire a reference to the parent device if the parent is to be
> locked.
>
> Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
> Signed-off-by: David Jeffery <djeffery@redhat.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260616152219.6268-1-djeffery@redhat.com?part=2
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 4/5] PCI: Enable async shutdown support
2026-06-16 15:22 ` [PATCH 4/5] PCI: Enable async shutdown support David Jeffery
@ 2026-06-16 15:38 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-06-16 15:38 UTC (permalink / raw)
To: David Jeffery; +Cc: linux-pci, linux-scsi
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [Critical] Double `put_device()` on `bridge->dev` in the `pci_register_host_bridge()` error path leads to use-after-free.
- [High] Unlocked read-modify-write of C bitfields in `dev_pm_info` via sysfs can clobber PM core states like `in_dpm_list`.
--
commit 5968194913e4b5e2b73a45e8bbc2ab20340b2cfe
Author: David Jeffery <djeffery@redhat.com>
PCI: Enable async shutdown support
This commit allows PCI device shutdown to be performed asynchronously.
It introduces calls to dev_set_async_shutdown() during host bridge
registration and device addition to reduce overall shutdown time.
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index b3cefec25f518..4782b4d5306b6 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1046,6 +1046,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
>
> bus->bridge = get_device(&bridge->dev);
> device_enable_async_suspend(bus->bridge);
[Severity: High]
This is a pre-existing issue, but does writing to the power/async sysfs
file trigger an unlocked read-modify-write that can clobber PM core states?
struct dev_pm_info declares adjacent bitfields async_suspend:1 and
in_dpm_list:1 that share a memory word.
device_pm_add() performs a locked read-modify-write under dpm_list_mtx to set
dev->power.in_dpm_list = true.
Because dpm_sysfs_add(dev) executes before device_pm_add(dev) during
initialization, userspace can immediately trigger a concurrent lockless
read-modify-write by writing to the power/async sysfs file. This calls
async_store() -> device_enable_async_suspend() and sets
dev->power.async_suspend = true without holding any locks.
If this lockless RMW races with device_pm_add(), can it overwrite in_dpm_list
back to false after it was set, breaking PM dependency chains and aborting
device linking?
[Severity: Critical]
This is a pre-existing issue, but does the error path in
pci_register_host_bridge() trigger a double put_device() on bridge->dev?
If device_register(&bus->dev) fails, execution jumps to the unregister label
which explicitly drops the bridge->dev reference:
unregister:
put_device(&bridge->dev);
device_del(&bridge->dev);
free:
...
if (bus_registered)
put_device(&bus->dev);
However, the release function for the bus, release_pcibus_dev(), also
unconditionally drops the bridge reference:
static void release_pcibus_dev(struct device *dev)
{
struct pci_bus *pci_bus = to_pci_bus(dev);
put_device(pci_bus->bridge);
...
}
When the execution falls through to the free label and calls
put_device(&bus->dev), will release_pcibus_dev() drop the bridge->dev
reference a second time, potentially causing a use-after-free when the caller
handles the registration error?
> + dev_set_async_shutdown(bus->bridge);
> pci_set_bus_of_node(bus);
> pci_set_bus_msi_domain(bus);
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260616152219.6268-1-djeffery@redhat.com?part=4
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 3/5] driver core: async device shutdown infrastructure
2026-06-16 15:22 ` [PATCH 3/5] driver core: async device shutdown infrastructure David Jeffery
@ 2026-06-16 15:39 ` sashiko-bot
2026-06-16 16:10 ` David Jeffery
2026-06-16 17:26 ` Randy Dunlap
2 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-06-16 15:39 UTC (permalink / raw)
To: David Jeffery; +Cc: linux-scsi, linux-pci
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Unprotected lockless modification of `devices_kset->list` leading to list corruption.
--
commit 3c22e8d639c6f39d1755272000b5af82fc85ebc8
Author: David Jeffery <djeffery@redhat.com>
driver core: async device shutdown infrastructure
This commit introduces an asynchronous device shutdown infrastructure. Devices
marked for async shutdown can be processed in parallel, waiting only for
their dependencies. This helps minimize false dependencies on unrelated
synchronous devices.
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index 3b3d983b17470..751fe2e13b3aa 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
[ ... ]
> +static void start_async_shutdown_devices(void)
> +{
> + struct device *dev, *next, *ndev, *needs_put = NULL;
> + bool clear_async = false;
> +
> + if (!async_shutdown)
> + return;
> +
> + spin_lock(&devices_kset->list_lock);
> +restart:
> + list_for_each_entry_safe_reverse(dev, next, &devices_kset->list,
> + kobj.entry) {
> + if (wants_async_shutdown(dev)) {
> + if (clear_async) {
> + dev_clear_async_shutdown(dev);
> + continue;
> + }
> + get_device(dev);
> +
> + if (!list_entry_is_head(next, &devices_kset->list,
> + kobj.entry))
> + ndev = get_device(next);
> + else
> + ndev = NULL;
> + spin_unlock(&devices_kset->list_lock);
> +
> + if (shutdown_device_async(dev)) {
> + list_del_init(&dev->kobj.entry);
[Severity: High]
Could this lead to list corruption?
In start_async_shutdown_devices(), the devices_kset->list_lock is released
before calling shutdown_device_async(). If the async schedule succeeds,
list_del_init() is called to remove the device from devices_kset->list
without reacquiring the lock.
Since this is a global doubly-linked list and concurrent device hotplug or
unplug events can still occur during system shutdown, doesn't modifying
this list without the lock risk corrupting the list pointers and causing
memory corruption or a panic?
> + } else {
> + /*
> + * async failed, clean up extra reference
> + * and run shutdown from the sync shutdown loop
> + */
> + clear_async = true;
> + put_device(dev);
> + }
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260616152219.6268-1-djeffery@redhat.com?part=3
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 5/5] scsi: Enable async shutdown support
2026-06-16 15:22 ` [PATCH 5/5] scsi: " David Jeffery
@ 2026-06-16 15:44 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-06-16 15:44 UTC (permalink / raw)
To: David Jeffery; +Cc: linux-scsi, linux-pci
> Like scsi's async suspend support, allow scsi devices to be shut down
> asynchronously to reduce system shutdown time.
>
> Signed-off-by: David Jeffery <djeffery@redhat.com>
> Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260616152219.6268-1-djeffery@redhat.com?part=5
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 3/5] driver core: async device shutdown infrastructure
2026-06-16 15:22 ` [PATCH 3/5] driver core: async device shutdown infrastructure David Jeffery
2026-06-16 15:39 ` sashiko-bot
@ 2026-06-16 16:10 ` David Jeffery
2026-06-16 17:26 ` Randy Dunlap
2 siblings, 0 replies; 26+ messages in thread
From: David Jeffery @ 2026-06-16 16:10 UTC (permalink / raw)
To: driver-core, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich
Cc: linux-kernel, linux-pci, linux-scsi, Tarun Sahu, Pasha Tatashin,
Michał Cłapiński, Jordan Richards, Ewan Milne,
John Meneghini, Lombardi, Maurizio, Stuart Hayes,
Laurence Oberman, Bart Van Assche, Bjorn Helgaas,
Martin K . Petersen, John Garry, kexec
On Tue, Jun 16, 2026 at 11:23 AM David Jeffery <djeffery@redhat.com> wrote:
>
> Patterned after async suspend, allow devices to mark themselves as wanting
> to perform async shutdown. Devices using async shutdown wait only for their
> dependencies to shutdown before executing their shutdown routine.
>
> Sync shutdown devices are shut down one at a time and will only wait for an
> async shutdown device if the async device is a dependency.
>
> Enabled by default, async shutdown can be explicitly enabled or disabled
> by using the kernel parameter "core.async_shutdown=<bool>"
>
> Signed-off-by: David Jeffery <djeffery@redhat.com>
> Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
> Tested-by: Laurence Oberman <loberman@redhat.com>
> ---
> .../admin-guide/kernel-parameters.txt | 10 ++
> drivers/base/base.h | 2 +
> drivers/base/core.c | 127 +++++++++++++++++-
> include/linux/device.h | 2 +
> 4 files changed, 140 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index b5a51a36a048..dd912f47ace4 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -1019,6 +1019,16 @@ Kernel parameters
> seconds. A value of 0 disables the blank timer.
> Defaults to 0.
>
> + core.async_shutdown=
> + [KNL]
> + Format: <bool>
> + Enable or disable asynchronous shutdown support. When
> + enabled, on system shutdown unrelated devices flagged
> + as async shutdown compatible may be shut down in
> + parallel and asynchronously. When disabled, device
> + shutdown is performed in a serially and synchronously.
> + Enabled by default.
> +
> coredump_filter=
> [KNL] Change the default value for
> /proc/<pid>/coredump_filter.
> diff --git a/drivers/base/base.h b/drivers/base/base.h
> index a5b7abc10ff0..40dbf588a5d6 100644
> --- a/drivers/base/base.h
> +++ b/drivers/base/base.h
> @@ -103,6 +103,7 @@ struct driver_private {
> * dev_err_probe() for later retrieval via debugfs
> * @device: pointer back to the struct device that this structure is
> * associated with.
> + * @complete: completion for device shutdown ordering
> * @dead: This device is currently either in the process of or has been
> * removed from the system. Any asynchronous events scheduled for this
> * device should exit without taking any action.
> @@ -119,6 +120,7 @@ struct device_private {
> const struct device_driver *async_driver;
> char *deferred_probe_reason;
> struct device *device;
> + struct completion complete;
> u8 dead:1;
> };
> #define to_device_private_parent(obj) \
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index 3b3d983b1747..751fe2e13b3a 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
> @@ -9,6 +9,7 @@
> */
>
> #include <linux/acpi.h>
> +#include <linux/async.h>
> #include <linux/blkdev.h>
> #include <linux/cleanup.h>
> #include <linux/cpufreq.h>
> @@ -37,6 +38,10 @@
> #include "physical_location.h"
> #include "power/power.h"
>
> +static bool async_shutdown = true;
> +module_param(async_shutdown, bool, 0644);
> +MODULE_PARM_DESC(async_shutdown, "Enable asynchronous device shutdown support");
> +
> /* Device links support. */
> static LIST_HEAD(deferred_sync);
> static unsigned int defer_sync_state_count = 1;
> @@ -3606,6 +3611,7 @@ static int device_private_init(struct device *dev)
> klist_init(&dev->p->klist_children, klist_children_get,
> klist_children_put);
> INIT_LIST_HEAD(&dev->p->deferred_probe);
> + init_completion(&dev->p->complete);
> return 0;
> }
>
> @@ -3895,6 +3901,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);
> @@ -4865,6 +4872,37 @@ int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid)
> return error;
> }
>
> +static bool wants_async_shutdown(struct device *dev)
> +{
> + return async_shutdown && dev_async_shutdown(dev);
> +}
> +
> +static int wait_for_device_shutdown(struct device *dev, void *data)
> +{
> + bool async = *(bool *)data;
> +
> + if (async || wants_async_shutdown(dev))
> + wait_for_completion(&dev->p->complete);
> +
> + return 0;
> +}
> +
> +static void wait_for_shutdown_dependencies(struct device *dev, bool async)
> +{
> + struct device_link *link;
> + int idx;
> +
> + device_for_each_child(dev, &async, wait_for_device_shutdown);
> +
> + idx = device_links_read_lock();
> +
> + dev_for_each_link_to_consumer(link, dev)
> + if (!device_link_flag_is_sync_state_only(link->flags))
> + wait_for_device_shutdown(link->consumer, &async);
> +
> + device_links_read_unlock(idx);
> +}
> +
> static void __shutdown_one_device(struct device *dev)
> {
> if (dev->p->dead)
> @@ -4888,6 +4926,8 @@ static void __shutdown_one_device(struct device *dev)
> dev_info(dev, "shutdown\n");
> dev->driver->shutdown(dev);
> }
> +
> + complete_all(&dev->p->complete);
> }
>
> static void shutdown_one_device(struct device *dev)
> @@ -4917,6 +4957,80 @@ static void shutdown_one_device(struct device *dev)
> put_device(dev);
> }
>
> +static void async_shutdown_handler(void *data, async_cookie_t cookie)
> +{
> + struct device *dev = data;
> +
> + wait_for_shutdown_dependencies(dev, true);
> + shutdown_one_device(dev);
> +}
> +
> +static bool shutdown_device_async(struct device *dev)
> +{
> + if (async_schedule_dev_nocall(async_shutdown_handler, dev))
> + return true;
> +
> + dev_clear_async_shutdown(dev);
> + return false;
> +}
> +
> +
> +static void start_async_shutdown_devices(void)
> +{
> + struct device *dev, *next, *ndev, *needs_put = NULL;
> + bool clear_async = false;
> +
> + if (!async_shutdown)
> + return;
> +
> + spin_lock(&devices_kset->list_lock);
> +restart:
> + list_for_each_entry_safe_reverse(dev, next, &devices_kset->list,
> + kobj.entry) {
> + if (wants_async_shutdown(dev)) {
> + if (clear_async) {
> + dev_clear_async_shutdown(dev);
> + continue;
> + }
> + get_device(dev);
> +
> + if (!list_entry_is_head(next, &devices_kset->list,
> + kobj.entry))
> + ndev = get_device(next);
> + else
> + ndev = NULL;
> + spin_unlock(&devices_kset->list_lock);
> +
> + if (shutdown_device_async(dev)) {
> + list_del_init(&dev->kobj.entry);
Sashiko detected a locking error here. The lock rework made
list_del_init occur while not holding the spinlock, which is a
potential list corruption issue. This will be corrected in the next
iteration.
David Jeffery
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 3/5] driver core: async device shutdown infrastructure
2026-06-16 15:22 ` [PATCH 3/5] driver core: async device shutdown infrastructure David Jeffery
2026-06-16 15:39 ` sashiko-bot
2026-06-16 16:10 ` David Jeffery
@ 2026-06-16 17:26 ` Randy Dunlap
2 siblings, 0 replies; 26+ messages in thread
From: Randy Dunlap @ 2026-06-16 17:26 UTC (permalink / raw)
To: David Jeffery, driver-core, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich
Cc: linux-kernel, linux-pci, linux-scsi, Tarun Sahu, Pasha Tatashin,
Michał Cłapiński, Jordan Richards, Ewan Milne,
John Meneghini, Lombardi, Maurizio, Stuart Hayes,
Laurence Oberman, Bart Van Assche, Bjorn Helgaas,
Martin K . Petersen, John Garry, kexec
On 6/16/26 8:22 AM, David Jeffery wrote:
> + core.async_shutdown=
> + [KNL]
> + Format: <bool>
> + Enable or disable asynchronous shutdown support. When
> + enabled, on system shutdown unrelated devices flagged
> + as async shutdown compatible may be shut down in
> + parallel and asynchronously. When disabled, device
> + shutdown is performed in a serially and synchronously.
performed serially and synchronously.
> + Enabled by default.
--
~Randy
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2026-06-16 17:26 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-16 15:22 [PATCH v17 0/5] shut down devices asynchronously David Jeffery
2026-06-16 15:22 ` [PATCH 1/5] driver core: separate function to shutdown one device David Jeffery
2026-06-16 15:34 ` sashiko-bot
2026-06-16 15:22 ` [PATCH 2/5] driver core: do not always lock parent in shutdown David Jeffery
2026-06-16 15:38 ` sashiko-bot
2026-06-16 15:22 ` [PATCH 3/5] driver core: async device shutdown infrastructure David Jeffery
2026-06-16 15:39 ` sashiko-bot
2026-06-16 16:10 ` David Jeffery
2026-06-16 17:26 ` Randy Dunlap
2026-06-16 15:22 ` [PATCH 4/5] PCI: Enable async shutdown support David Jeffery
2026-06-16 15:38 ` sashiko-bot
2026-06-16 15:22 ` [PATCH 5/5] scsi: " David Jeffery
2026-06-16 15:44 ` sashiko-bot
-- strict thread matches above, loose matches on Subject: below --
2026-05-18 19:31 [PATCH v16 0/5] shut down devices asynchronously David Jeffery
2026-05-18 19:32 ` [PATCH 4/5] PCI: Enable async shutdown support David Jeffery
2026-04-29 17:50 [PATCH v15 0/5] shut down devices asynchronously David Jeffery
2026-04-29 17:50 ` [PATCH 4/5] PCI: Enable async shutdown support David Jeffery
2026-05-06 18:28 ` Bjorn Helgaas
2026-05-06 21:10 ` David Jeffery
2026-05-06 21:24 ` Bjorn Helgaas
2026-04-20 15:26 [PATCH v14 0/5] shut down devices asynchronously David Jeffery
2026-04-20 15:26 ` [PATCH 4/5] PCI: Enable async shutdown support David Jeffery
2026-04-07 15:35 [PATCH v13 0/5] shut down devices asynchronously David Jeffery
2026-04-07 15:35 ` [PATCH 4/5] PCI: Enable async shutdown support David Jeffery
2026-03-19 14:11 [PATCH v12 0/5] shut down devices asynchronously David Jeffery
2026-03-19 14:11 ` [PATCH 4/5] PCI: enable async shutdown support David Jeffery
2026-03-11 17:12 [PATCH 1/5] driver core: do not always lock parent in shutdown David Jeffery
2026-03-11 17:12 ` [PATCH 4/5] pci: enable async shutdown support David Jeffery
2026-03-11 23:08 ` Bjorn Helgaas
2026-03-12 13:46 ` David Jeffery
2026-03-12 5:09 ` Greg Kroah-Hartman
2026-03-12 13:54 ` David Jeffery
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.