[PATCH 2/5] PCI: Support two-pass shutdown
Bjorn Helgaas
helgaas at kernel.org
Thu Jan 4 10:55:24 PST 2024
On Wed, Jan 03, 2024 at 01:04:02PM -0800, Jeremy Allison wrote:
> From: Tanjore Suresh <tansuresh at google.com>
>
> Enhances the base PCI driver to add support for two-pass
> shutdown. Adds shutdown_wait() method.
>
> Assume a device takes n secs to shutdown. If a machine has been
> populated with M such devices, the total time spent in shutting down
> all the devices will be M * n secs if the shutdown is done
> synchronously. For example, if NVMe PCI Controllers take 5 secs
> to shutdown and if there are 16 such NVMe controllers in a system,
> system will spend a total of 80 secs to shutdown all
> NVMe devices in that system.
>
> In order to speed up the shutdown time, a two-pass interface to
> shutdown has been implemented. The caller calls the shutdown method
> for each device in turn to allow a shutdown request to be sent,
> then the caller walks the list of devices and calls shutdown_wait()
> to synchronously wait for the shutdown to complete.
>
> In the NVMe case above, all 16 devices will process the shutdown
> in parallel taking the total time to shutdown down to the time
> for one NVMe PCI Controller to shut down.
>
> This will significantly reduce the machine reboot time.
>
> Signed-off-by: Tanjore Suresh <tansuresh at google.com>
> Signed-off-by: Jeremy Allison <jallison at ciq.com>
Rewrap commit log to fill 75 columns. Use present tense imperative,
e.g., "Enhance ..." and "Add ..."
Acked-by: Bjorn Helgaas <bhelgaas at google.com>
> ---
> drivers/pci/pci-driver.c | 9 +++++++++
> include/linux/pci.h | 2 ++
> 2 files changed, 11 insertions(+)
>
> diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
> index 51ec9e7e784f..257bbb04c806 100644
> --- a/drivers/pci/pci-driver.c
> +++ b/drivers/pci/pci-driver.c
> @@ -547,6 +547,14 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev)
> }
> #endif /* CONFIG_PM_SLEEP */
>
> +static void pci_device_shutdown_wait(struct device *dev)
> +{
> + struct pci_dev *pci_dev = to_pci_dev(dev);
> + struct pci_driver *drv = pci_dev->driver;
> +
> + if (drv && drv->shutdown_wait)
> + drv->shutdown_wait(pci_dev);
> +}
> #ifdef CONFIG_PM
>
> /* Auxiliary functions used for system resume and run-time resume */
> @@ -1682,6 +1690,7 @@ struct bus_type pci_bus_type = {
> .probe = pci_device_probe,
> .remove = pci_device_remove,
> .shutdown = pci_device_shutdown,
> + .shutdown_wait = pci_device_shutdown_wait,
> .dev_groups = pci_dev_groups,
> .bus_groups = pci_bus_groups,
> .drv_groups = pci_drv_groups,
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 60ca768bc867..e3ba7043c7de 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -917,6 +917,7 @@ struct module;
> * Useful for enabling wake-on-lan (NIC) or changing
> * the power state of a device before reboot.
> * e.g. drivers/net/e100.c.
> + * @shutdown_wait: Optional driver callback to allow two-pass shutdown.
> * @sriov_configure: Optional driver callback to allow configuration of
> * number of VFs to enable via sysfs "sriov_numvfs" file.
> * @sriov_set_msix_vec_count: PF Driver callback to change number of MSI-X
> @@ -948,6 +949,7 @@ struct pci_driver {
> int (*suspend)(struct pci_dev *dev, pm_message_t state); /* Device suspended */
> int (*resume)(struct pci_dev *dev); /* Device woken up */
> void (*shutdown)(struct pci_dev *dev);
> + void (*shutdown_wait)(struct pci_dev *dev);
> int (*sriov_configure)(struct pci_dev *dev, int num_vfs); /* On PF */
> int (*sriov_set_msix_vec_count)(struct pci_dev *vf, int msix_vec_count); /* On PF */
> u32 (*sriov_get_vf_total_msix)(struct pci_dev *pf);
> --
> 2.39.3
>
>
More information about the Linux-nvme
mailing list