* [PATCH v1] driver core: Don't take the device lock in waiting_for_supplier_show()
@ 2026-10-18 0:18 Nickolai Zeldovich
2026-10-18 6:51 ` Greg Kroah-Hartman
0 siblings, 1 reply; 2+ messages in thread
From: Nickolai Zeldovich @ 2026-10-18 0:18 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J . Wysocki, Danilo Krummrich
Cc: Saravana Kannan, driver-core, linux-kernel, Nickolai Zeldovich
Reading a device's waiting_for_supplier attribute while the device is
being probed hangs both the reader and the probing task for good, in
uninterruptible sleep, if the probe succeeds. The file is world
readable and fw_devlink, enabled by default, creates it for every
device with a firmware node until the device is bound, so any user
reading sysfs during a probe (udev, a tool walking /sys, a plain cat)
can wedge it. The probing task keeps holding the device lock, so the
module load or deferred probe work that ran the probe, and everything
that takes that device's lock later, hangs as well. Kernels since v5.9
are affected.
waiting_for_supplier_show() blocks in device_lock() while the read
holds an active reference on the sysfs file. On successful probe,
driver_bound() calls device_links_driver_bound() with the device lock
held, which removes the file, and kernfs waits for that active
reference to be dropped: the reader waits for the prober and the
prober for the reader. Lockdep does not report it because dev->mutex
is not validated.
The device lock is not needed here. The value is computed by
fwnode_links_check_suppliers() under fwnode_link_lock, which every
writer of the fwnode supplier list holds, and the active reference keeps
the device from being deleted while the callback runs. Drop the device
lock.
Reproduced on x86_64 under QEMU with an lsi53c895a SCSI controller and
sym53c8xx built as a module: its probe resets the SCSI bus and the
synchronous scan then waits for the settle delay (3 seconds by default),
and a read of the PCI device's waiting_for_supplier file 1 second into
the module load hangs. Before the change the hung task detector reports
insmod in kernfs_drain() under device_links_driver_bound() and cat in
waiting_for_supplier_show(), neither ever returns, and a power-off
afterwards hangs in device_shutdown() on the same lock; after the
change the read returns 0 and the module load completes.
Fixes: da6d647598a6 ("driver core: Add waiting_for_supplier sysfs file for devices")
Assisted-by: LLM
Signed-off-by: Nickolai Zeldovich <nickolai@csail.mit.edu>
---
Notes:
Every writer of the fwnode supplier list (fwnode_link_add(), the purge
helpers, __fwnode_links_move_consumers() via
fw_devlink_pickup_dangling_consumers(), and the cycle/link code under
fw_devlink_link_device()) holds fwnode_link_lock, so the walk in
fwnode_links_check_suppliers() needs nothing more.
Reproducer (x86_64 defconfig + CONFIG_SCSI_SYM53C8XX_2=m + CONFIG_DETECT_HUNG_TASK,
QEMU with -device lsi53c895a,id=scsi0 -device scsi-hd,drive=d0,bus=scsi0.0; the
PCI device has an ACPI companion, so it owns a waiting_for_supplier file until a
driver binds; sym2_probe() resets the SCSI bus and the synchronous scan waits for
the settle delay, so the probe takes "settle" seconds). Busybox /init, with
sym53c8xx.ko in the initramfs:
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev
for d in /sys/bus/pci/devices/*; do
read v < $d/vendor; read i < $d/device
[ "$v $i" = "0x1000 0x0012" ] && dev=${d##*/}
done
(insmod /sym53c8xx.ko settle=8 && echo "init: module load done") &
sleep 1
(echo "init: read returned $(cat /sys/bus/pci/devices/$dev/waiting_for_supplier), attribute access done") &
sleep 30
echo "init: after 30 s:"
ps | grep -E 'insmod|cat /sys'
echo w > /proc/sysrq-trigger
qemu-system-x86_64 -cpu max -smp 2 -m 512M -nographic -no-reboot -kernel bzImage \
-initrd initramfs.cpio -drive file=disk.img,if=none,id=d0,format=raw \
-device lsi53c895a,id=scsi0 -device scsi-hd,drive=d0,bus=scsi0.0 \
-append "console=ttyS0 panic=-1 rdinit=/init loglevel=7"
Before:
INFO: task insmod:72 blocked for more than 10 seconds.
kernfs_drain+0xf6/0x170
__kernfs_remove+0x188/0x250
kernfs_remove_by_name_ns+0x78/0xd0
device_links_driver_bound+0xd4/0x350
driver_bound+0x46/0x180
really_probe+0x1b1/0x360
__driver_attach+0xfc/0x1d0
bus_add_driver+0x15c/0x270
init_module+0xc9/0xff0 [sym53c8xx]
INFO: task cat:79 blocked for more than 10 seconds.
__mutex_lock+0x395/0xa00
waiting_for_supplier_show+0x1f/0xa0
dev_attr_show+0x17/0x60
INFO: task cat:79 is blocked on a mutex likely owned by task insmod:72.
init: after 30 s:
72 0 {insmod} /bin/sh /init
79 0 cat /sys/bus/pci/devices/0000:00:04.0/waiting_for_supplier
(a power-off afterwards hangs too: device_shutdown() takes the same lock)
After:
init: read returned 0, attribute access done
sd 2:0:0:0: [sda] Attached SCSI disk
init: module load done
drivers/base/core.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 4c0c373998a1..a3a28d83d339 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1317,10 +1317,8 @@ static ssize_t waiting_for_supplier_show(struct device *dev,
{
bool val;
- device_lock(dev);
scoped_guard(mutex, &fwnode_link_lock)
val = !!fwnode_links_check_suppliers(dev->fwnode);
- device_unlock(dev);
return sysfs_emit(buf, "%u\n", val);
}
static const DEVICE_ATTR_RO(waiting_for_supplier);
base-commit: 70dd4ee72eb2d5793c62e71c14e3aba78e5a4e56
--
2.53.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v1] driver core: Don't take the device lock in waiting_for_supplier_show()
2026-10-18 0:18 [PATCH v1] driver core: Don't take the device lock in waiting_for_supplier_show() Nickolai Zeldovich
@ 2026-10-18 6:51 ` Greg Kroah-Hartman
0 siblings, 0 replies; 2+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-18 6:51 UTC (permalink / raw)
To: Nickolai Zeldovich
Cc: Rafael J . Wysocki, Danilo Krummrich, Saravana Kannan,
driver-core, linux-kernel
On Sat, Oct 17, 2026 at 08:18:37PM -0400, Nickolai Zeldovich wrote:
> Reading a device's waiting_for_supplier attribute while the device is
> being probed hangs both the reader and the probing task for good, in
> uninterruptible sleep, if the probe succeeds. The file is world
> readable and fw_devlink, enabled by default, creates it for every
> device with a firmware node until the device is bound, so any user
> reading sysfs during a probe (udev, a tool walking /sys, a plain cat)
> can wedge it. The probing task keeps holding the device lock, so the
> module load or deferred probe work that ran the probe, and everything
> that takes that device's lock later, hangs as well. Kernels since v5.9
> are affected.
>
> waiting_for_supplier_show() blocks in device_lock() while the read
> holds an active reference on the sysfs file. On successful probe,
> driver_bound() calls device_links_driver_bound() with the device lock
> held, which removes the file, and kernfs waits for that active
> reference to be dropped: the reader waits for the prober and the
> prober for the reader. Lockdep does not report it because dev->mutex
> is not validated.
>
> The device lock is not needed here. The value is computed by
> fwnode_links_check_suppliers() under fwnode_link_lock, which every
> writer of the fwnode supplier list holds, and the active reference keeps
> the device from being deleted while the callback runs. Drop the device
> lock.
>
> Reproduced on x86_64 under QEMU with an lsi53c895a SCSI controller and
> sym53c8xx built as a module: its probe resets the SCSI bus and the
> synchronous scan then waits for the settle delay (3 seconds by default),
> and a read of the PCI device's waiting_for_supplier file 1 second into
> the module load hangs. Before the change the hung task detector reports
> insmod in kernfs_drain() under device_links_driver_bound() and cat in
> waiting_for_supplier_show(), neither ever returns, and a power-off
> afterwards hangs in device_shutdown() on the same lock; after the
> change the read returns 0 and the module load completes.
>
> Fixes: da6d647598a6 ("driver core: Add waiting_for_supplier sysfs file for devices")
> Assisted-by: LLM
> Signed-off-by: Nickolai Zeldovich <nickolai@csail.mit.edu>
> ---
>
Hi,
This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him
a patch that has triggered this response. He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created. Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.
You are receiving this message because of the following common error(s)
as indicated below:
- You have marked a patch with a "Fixes:" tag for a commit that is in an
older released kernel, yet you do not have a cc: stable line in the
signed-off-by area at all, which means that the patch will not be
applied to any older kernel releases. To properly fix this, please
follow the documented rules in the
Documentation/process/stable-kernel-rules.rst file for how to resolve
this.
If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.
thanks,
greg k-h's patch email bot
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-18 6:51 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-18 0:18 [PATCH v1] driver core: Don't take the device lock in waiting_for_supplier_show() Nickolai Zeldovich
2026-10-18 6:51 ` Greg Kroah-Hartman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox