From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
To: Stuart Hayes <stuart.w.hayes@gmail.com>,
linux-kernel@vger.kernel.org,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
"Rafael J . Wysocki" <rafael@kernel.org>,
Martin Belanger <Martin.Belanger@dell.com>,
Oliver O'Halloran <oohall@gmail.com>,
Daniel Wagner <dwagner@suse.de>, Keith Busch <kbusch@kernel.org>,
Lukas Wunner <lukas@wunner.de>,
David Jeffery <djeffery@redhat.com>,
Jeremy Allison <jallison@ciq.com>, Jens Axboe <axboe@fb.com>,
Christoph Hellwig <hch@lst.de>, Sagi Grimberg <sagi@grimberg.me>,
linux-nvme@lists.infradead.org
Subject: Re: [PATCH v8 3/4] driver core: shut down devices asynchronously
Date: Sun, 8 Sep 2024 16:44:31 +0200 [thread overview]
Message-ID: <8debbb55-449d-4f8d-a6dd-3ba15836aacf@wanadoo.fr> (raw)
In-Reply-To: <20240822202805.6379-4-stuart.w.hayes@gmail.com>
Le 22/08/2024 à 22:28, Stuart Hayes a écrit :
> Add code to allow asynchronous shutdown of devices, ensuring that each
> device is shut down before its parents & suppliers.
>
> Only devices with drivers that have async_shutdown_enable enabled will be
> shut down asynchronously.
>
> 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.
>
> Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
> Signed-off-by: David Jeffery <djeffery@redhat.com>
> ---
...
> +/**
> + * shutdown_one_device_async
> + * @data: the pointer to the struct device to be shutdown
> + * @cookie: not used
> + *
> + * Shuts down one device, after waiting for shutdown_after to complete.
> + * shutdown_after should be set to the cookie of the last child or consumer
> + * of this device to be shutdown (if any), or to the cookie of the previous
> + * device to be shut down for devices that don't enable asynchronous shutdown.
> + */
> +static void shutdown_one_device_async(void *data, async_cookie_t cookie)
> +{
> + struct device *dev = data;
> +
> + async_synchronize_cookie_domain(dev->p->shutdown_after + 1, &sd_domain);
> +
> + shutdown_one_device(dev);
> +}
> +
> /**
> * device_shutdown - call ->shutdown() on each device to shutdown.
> */
> void device_shutdown(void)
> {
> struct device *dev, *parent;
> + async_cookie_t cookie = 0;
> + struct device_link *link;
> + int idx;
>
> wait_for_device_probe();
> device_block_probing();
> @@ -4852,11 +4878,37 @@ void device_shutdown(void)
> list_del_init(&dev->kobj.entry);
> spin_unlock(&devices_kset->list_lock);
>
> - shutdown_one_device(dev);
> +
> + /*
> + * Set cookie for devices that will be shut down synchronously
> + */
> + if (!dev->driver || !dev->driver->async_shutdown_enable)
> + dev->p->shutdown_after = cookie;
> +
> + get_device(dev);
> + get_device(parent);
> +
> + cookie = async_schedule_domain(shutdown_one_device_async,
> + dev, &sd_domain);
> + /*
> + * Ensure parent & suppliers wait for this device to shut down
> + */
> + if (parent) {
> + parent->p->shutdown_after = cookie;
> + put_device(parent);
Would it make sense to have this put_device() out of the if block?
IIUC, the behavior would be exactly the same, but it is more intuitive
to have a put_device(parent) called for each get_device(parent) call.
Another way to keep symmetry is to have:
if (parent)
get_device(parent);
above.
> + }
> +
> + idx = device_links_read_lock();
> + list_for_each_entry_rcu(link, &dev->links.suppliers, c_node,
> + device_links_read_lock_held())
> + link->supplier->p->shutdown_after = cookie;
> + device_links_read_unlock(idx);
> + put_device(dev);
>
> spin_lock(&devices_kset->list_lock);
> }
> spin_unlock(&devices_kset->list_lock);
> + async_synchronize_full_domain(&sd_domain);
> }
>
> /*
> diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h
> index 1fc8b68786de..2b6127faaa25 100644
> --- a/include/linux/device/driver.h
> +++ b/include/linux/device/driver.h
> @@ -56,6 +56,7 @@ enum probe_type {
> * @mod_name: Used for built-in modules.
> * @suppress_bind_attrs: Disables bind/unbind via sysfs.
> * @probe_type: Type of the probe (synchronous or asynchronous) to use.
> + * @async_shutdown_enable: Enables devices to be shutdown asynchronously.
> * @of_match_table: The open firmware table.
> * @acpi_match_table: The ACPI match table.
> * @probe: Called to query the existence of a specific device,
> @@ -102,6 +103,7 @@ struct device_driver {
>
> bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
> enum probe_type probe_type;
> + bool async_shutdown_enable;
Maybe keep these 2 bools together to potentially avoid hole?
Just my 2c.
CJ
>
> const struct of_device_id *of_match_table;
> const struct acpi_device_id *acpi_match_table;
next prev parent reply other threads:[~2024-09-08 14:44 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-22 20:28 [PATCH v8 0/4] shut down devices asynchronously Stuart Hayes
2024-08-22 20:28 ` [PATCH v8 1/4] driver core: don't always lock parent in shutdown Stuart Hayes
2024-08-23 6:26 ` Christoph Hellwig
2024-08-25 7:56 ` Sagi Grimberg
2024-08-22 20:28 ` [PATCH v8 2/4] driver core: separate function to shutdown one device Stuart Hayes
2024-08-23 6:26 ` Christoph Hellwig
2024-08-25 7:56 ` Sagi Grimberg
2024-08-22 20:28 ` [PATCH v8 3/4] driver core: shut down devices asynchronously Stuart Hayes
2024-08-23 6:26 ` Christoph Hellwig
2024-08-24 10:29 ` Lukas Wunner
2024-08-25 7:58 ` Sagi Grimberg
2024-09-05 22:13 ` Nathan Chancellor
2024-09-06 14:44 ` stuart hayes
2024-09-08 13:36 ` Jan Kiszka
2024-09-11 0:14 ` stuart hayes
2024-09-11 5:51 ` Jan Kiszka
2024-09-11 22:06 ` stuart hayes
2024-09-12 14:30 ` David Jeffery
2024-09-12 16:20 ` stuart hayes
2024-09-08 14:44 ` Christophe JAILLET [this message]
2024-09-23 20:50 ` Andrey Skvortsov
2024-09-24 9:23 ` Greg Kroah-Hartman
2024-09-24 20:44 ` Andrey Skvortsov
2024-09-25 8:55 ` Greg Kroah-Hartman
2024-08-22 20:28 ` [PATCH v8 4/4] nvme-pci: Make driver prefer asynchronous shutdown Stuart Hayes
2024-08-23 6:27 ` Christoph Hellwig
2024-08-25 7:57 ` Sagi Grimberg
2024-08-23 16:54 ` [PATCH v8 0/4] shut down devices asynchronously Keith Busch
2024-09-03 11:10 ` Greg Kroah-Hartman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8debbb55-449d-4f8d-a6dd-3ba15836aacf@wanadoo.fr \
--to=christophe.jaillet@wanadoo.fr \
--cc=Martin.Belanger@dell.com \
--cc=axboe@fb.com \
--cc=djeffery@redhat.com \
--cc=dwagner@suse.de \
--cc=gregkh@linuxfoundation.org \
--cc=hch@lst.de \
--cc=jallison@ciq.com \
--cc=kbusch@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=lukas@wunner.de \
--cc=oohall@gmail.com \
--cc=rafael@kernel.org \
--cc=sagi@grimberg.me \
--cc=stuart.w.hayes@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.