All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "David Jeffery" <djeffery@redhat.com>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	"Danilo Krummrich" <dakr@kernel.org>
Cc: linux-pci@vger.kernel.org, linux-scsi@vger.kernel.org,
	"Tarun Sahu" <tarunsahu@google.com>,
	"Stuart Hayes" <stuart.w.hayes@gmail.com>,
	"Laurence Oberman" <loberman@redhat.com>,
	"Bjorn Helgaas" <helgaas@kernel.org>,
	kexec@lists.infradead.org, "Ewan Milne" <emilne@redhat.com>,
	"John Meneghini" <jmeneghi@redhat.com>,
	"Lombardi, Maurizio" <mlombard@redhat.com>,
	"Bart Van Assche" <bvanassche@acm.org>,
	"John Garry" <john.g.garry@oracle.com>,
	"Jeremy Allison" <jallison@ciq.com>,
	"Martin K . Petersen" <martin.petersen@oracle.com>,
	"Pasha Tatashin" <tatashin@google.com>
Subject: Re: [PATCH 2/9] driver core: prevent device_add() during system shutdown
Date: Tue, 20 Oct 2026 17:03:52 +0000	[thread overview]
Message-ID: <sashiko-outbox-179396@kernel.org> (raw)
In-Reply-To: <20261020164435.80499-3-djeffery@redhat.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] driver core: device_shutdown() calls synchronize_srcu() after blocking probes
- [High] driver core: device_add() blocks nested device_link_add() during shutdown
--

commit fff836fc21ae90945fdc03da97b97959ca2c2584
Author: Tarun Sahu <tarunsahu@google.com>

driver core: prevent device_add() during system shutdown

This commit prevents new devices from being registered during system
shutdown by checking system_is_shutting_down() in device_add() and
synchronizing in-flight device_add() calls in device_shutdown() using SRCU.

> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index 83263e3fa5d44..bce555dd74f69 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c

[ ... ]

> @@ -3647,13 +3666,20 @@ int device_add(struct device *dev)
>  	struct device *parent;
>  	struct kobject *kobj;
>  	struct class_interface *class_intf;
> -	int error = -EINVAL;
> +	int idx, error = -EINVAL;
>  	struct kobject *glue_dir = NULL;
>  
> +	idx = srcu_read_lock(&device_add_srcu);
> +
>  	dev = get_device(dev);
>  	if (!dev)
>  		goto done;
>  
> +	if (unlikely(system_is_shutting_down())) {
> +		error = -ESHUTDOWN;
> +		goto done;
> +	}

[Severity: High]
Can this check in device_add() break nested device_link_add() calls for an
in-flight supplier registration when system_state transitions to a shutdown
state?

Suppose a consumer device is already registered in devices_kset->list, and
its supplier device is being registered in thread A:

Thread A:
device_add(sup_dev)
  srcu_read_lock(&device_add_srcu)
  system_is_shutting_down() -> false
  kobject_add(&sup_dev->kobj, ...)
    -> appends sup_dev to the tail of devices_kset->list (after con_dev)

If thread B now initiates shutdown, sets system_state to SYSTEM_RESTART,
SYSTEM_HALT, or SYSTEM_POWER_OFF, and waits in device_shutdown() at
synchronize_srcu(&device_add_srcu), thread A continues in device_add():

  if (dev->fwnode && !dev->fwnode->dev) {
          dev->fwnode->dev = dev;
          fw_devlink_link_device(dev);
  }

fw_devlink_link_device() walks the fwnode links and calls
device_link_add(), which registers the link device via device_register():

drivers/base/core.c:device_link_add() {
    ...
	if (device_register(&link->link_dev)) {
		put_device(&link->link_dev);
		link = NULL;
		goto out;
	}
    ...
reorder:
	device_reorder_to_tail(consumer, NULL);
    ...
}

Because system_is_shutting_down() is now true, the nested
device_register(&link->link_dev) -> device_add(&link->link_dev) fails with
-ESHUTDOWN.

As a result, device_link_add() returns NULL without creating the device
link and without calling device_reorder_to_tail(consumer, NULL) to move the
consumer after the supplier in devices_kset->list (and
__fw_devlink_link_to_consumers() / __fw_devlink_link_to_suppliers() drop
the fwnode_link when fw_devlink_create_devlink() returns -EINVAL).

When synchronize_srcu(&device_add_srcu) completes and device_shutdown()
walks devices_kset->list backward from tail to head, wouldn't the supplier
sup_dev be shut down before its consumer con_dev?

> +
>  	if (!dev->p) {
>  		error = device_private_init(dev);
>  		if (error)
> @@ -3803,6 +3829,7 @@ int device_add(struct device *dev)
>  	}
>  done:
>  	put_device(dev);
> +	srcu_read_unlock(&device_add_srcu, idx);
>  	return error;
>   SysEntryError:
>  	if (MAJOR(dev->devt))
> @@ -4877,6 +4904,7 @@ void device_shutdown(void)
>  
>  	wait_for_device_probe();
>  	device_block_probing();
> +	synchronize_srcu(&device_add_srcu);

[Severity: High]
Should synchronize_srcu(&device_add_srcu) be called before
wait_for_device_probe() and device_block_probing() instead of after them?

If thread A is inside device_add(dev) and has already passed
system_is_shutting_down() before system_state is updated, but has not yet
reached bus_probe_device(dev), thread B can run wait_for_device_probe() and
device_block_probing() to completion and then block in
synchronize_srcu(&device_add_srcu).

While thread B is waiting in synchronize_srcu(&device_add_srcu), thread A
reaches:

device_add(dev)
  bus_probe_device(dev)
    device_initial_probe(dev)
      __device_attach(dev, true)

In drivers/base/dd.c:__device_attach(), if dev matches an asynchronous
driver on the bus, __device_attach_driver() sets data.have_async = true and
returns 0 before reaching driver_probe_device() / really_probe() (where
defer_all_probes is checked), and __device_attach() then schedules async
probing without checking defer_all_probes:

drivers/base/dd.c:__device_attach() {
    ...
		ret = bus_for_each_drv(dev->bus, NULL, &data,
					__device_attach_driver);
		if (!ret && allow_async && data.have_async) {
			dev_dbg(dev, "scheduling asynchronous probe\n");
			get_device(dev);
			async = true;
		} else {
			pm_request_idle(dev);
		}

		if (dev->parent)
			pm_runtime_put(dev->parent);
	}
out_unlock:
	device_unlock(dev);
	if (async)
		async_schedule_dev(__device_attach_async_helper, dev);
    ...
}

Similarly, if dev->driver was already set prior to device_add(dev),
__device_attach() calls device_bind_driver(dev) -> driver_bound(dev) ->
driver_deferred_probe_trigger(), queuing deferred_probe_work on
system_dfl_wq.

Once thread A calls srcu_read_unlock(&device_add_srcu, idx),
synchronize_srcu(&device_add_srcu) in device_shutdown() returns without
waiting for probes again. Can this allow __device_attach_async_helper()
(which performs runtime PM calls on dev and dev->parent) or
deferred_probe_work_func() (which reorders devices_kset->list via
device_pm_move_to_tail()) to run concurrently with device_shutdown()?

>  
>  	cpufreq_suspend();
>

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261020164435.80499-1-djeffery@redhat.com?part=2

  reply	other threads:[~2026-10-20 17:04 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-20 16:44 [PATCH RESEND v22 0/9] shut down devices asynchronously David Jeffery
2026-10-20 16:44 ` [PATCH 1/9] driver core: rely on put_device to free dev->p David Jeffery
2026-10-20 16:56   ` sashiko-bot
2026-10-20 16:44 ` [PATCH 2/9] driver core: prevent device_add() during system shutdown David Jeffery
2026-10-20 17:03   ` sashiko-bot [this message]
2026-10-20 16:44 ` [PATCH 3/9] driver core: warn should device_move try to move a need_parent_lock device David Jeffery
2026-10-20 16:48   ` sashiko-bot
2026-10-20 16:44 ` [PATCH 4/9] driver core: separate function to shutdown one device David Jeffery
2026-10-20 16:47   ` sashiko-bot
2026-10-20 16:44 ` [PATCH 5/9] driver core: do not always lock parent in shutdown David Jeffery
2026-10-20 17:02   ` sashiko-bot
2026-10-20 16:44 ` [PATCH 6/9] driver core: async device shutdown infrastructure David Jeffery
2026-10-20 17:19   ` sashiko-bot
2026-10-20 16:44 ` [PATCH 7/9] PCI: Link a virtual function to its physical function David Jeffery
2026-10-20 16:52   ` sashiko-bot
2026-10-20 16:44 ` [PATCH 8/9] PCI: Enable async shutdown support David Jeffery
2026-10-20 16:54   ` sashiko-bot
2026-10-20 16:44 ` [PATCH 9/9] scsi: " David Jeffery
2026-10-20 17:01   ` sashiko-bot
  -- strict thread matches above, loose matches on Subject: below --
2026-09-17 16:37 [PATCH v22 0/9] shut down devices asynchronously David Jeffery
2026-09-17 16:37 ` [PATCH 2/9] driver core: prevent device_add() during system shutdown David Jeffery
2026-09-17 16:46   ` sashiko-bot
2026-09-02 17:07 [PATCH v21 0/9] shut down devices asynchronously David Jeffery
2026-09-02 17:07 ` [PATCH 2/9] driver core: prevent device_add() during system shutdown David Jeffery
2026-09-02 17:15   ` sashiko-bot
2026-08-21 14:24 [PATCH v20 0/9] shut down devices asynchronously David Jeffery
2026-08-21 14:24 ` [PATCH 2/9] driver core: prevent device_add() during system shutdown David Jeffery
2026-08-21 14:43   ` sashiko-bot
2026-08-28 16:01     ` tarunsahu

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=sashiko-outbox-179396@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bvanassche@acm.org \
    --cc=dakr@kernel.org \
    --cc=djeffery@redhat.com \
    --cc=emilne@redhat.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=helgaas@kernel.org \
    --cc=jallison@ciq.com \
    --cc=jmeneghi@redhat.com \
    --cc=john.g.garry@oracle.com \
    --cc=kexec@lists.infradead.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=loberman@redhat.com \
    --cc=martin.petersen@oracle.com \
    --cc=mlombard@redhat.com \
    --cc=rafael@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=stuart.w.hayes@gmail.com \
    --cc=tarunsahu@google.com \
    --cc=tatashin@google.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.