[PATCH 1/6] gpiolib: wait for pending label frees before cleaning up desc_srcu
From: Adrian Ambrozewicz
Date: Mon Oct 12 2026 - 10:02:21 EST
desc_set_label() frees the old label with call_srcu() on gdev->desc_srcu.
gpiodev_release() calls synchronize_srcu() and then cleanup_srcu_struct()
on it, meaning to run the pending frees first, but synchronize_srcu()
only waits for a grace period, not for callbacks queued before it to be
invoked. Once the srcu_struct uses per-CPU callback lists, a label freed
on one CPU, for instance by gpiochip_free_hogs() at the start of
gpiochip_remove(), can still be waiting for its invocation timer there
when synchronize_srcu() returns on another, and cleanup_srcu_struct()
warns:
WARNING: kernel/rcu/srcutree.c:706 at cleanup_srcu_struct+0x239/0x330, CPU#0: init/1
Call Trace:
<TASK>
gpiodev_release+0x20/0x60
device_release+0x3e/0x90
kobject_put+0x67/0xf0
release_nodes+0x3a/0x60
devres_release_all+0x8a/0xf0
device_unbind_cleanup+0x21/0xa0
device_release_driver_internal+0x1c6/0x210
bus_remove_device+0xea/0x180
device_del+0x152/0x460
platform_device_del+0x20/0x80
platform_device_unregister+0xd/0x30
gpio_sim_device_deactivate+0x26/0x80
gpio_sim_device_config_live_store+0x254/0x3e0
configfs_write_iter+0xc2/0x130
vfs_write+0x252/0x530
ksys_write+0x6c/0xe0
do_syscall_64+0x109/0x5d0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
cleanup_srcu_struct() then flushes the callbacks itself, so the label is
still freed, but the warning is what the comment above that check says
srcu_barrier() is for. Use it.
A gpio-sim chip with one hogged line, set live and back in a loop, warns
within 4 to 60 cycles in three runs on a 4-CPU guest booted with
srcutree.convert_to_big=1; with this change, three runs of 1000 cycles
pass. With the default srcutree parameters the srcu_struct only goes
per-CPU under contention and the loop did not hit it in 3000 cycles; the
warning was first seen that way, once, on a KCSAN arm64 guest unbinding
a USB-attached GPIO controller whose firmware node hogs a line, and
since then on real hardware with v7.3-rc5 arm64 KCSAN kernels, when
unbinding a USB GPIO expander whose driver is not yet upstream, built
both as an out-of-tree module and into the kernel.
Fixes: a86d27693066 ("gpiolib: fix the speed of descriptor label setting with SRCU")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Adrian Ambrozewicz <aambrozewicz@xxxxxxxxxx>
---
drivers/gpio/gpiolib.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 772c6f04f489..1984f3416437 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -895,7 +895,7 @@ static void gpiodev_release(struct device *dev)
struct gpio_device *gdev = to_gpio_device(dev);
/* Call pending kfree()s for descriptor labels. */
- synchronize_srcu(&gdev->desc_srcu);
+ srcu_barrier(&gdev->desc_srcu);
cleanup_srcu_struct(&gdev->desc_srcu);
ida_free(&gpio_ida, gdev->id);
--
2.43.0