summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDAI RENJIE <drj19981414013@gmail.com>2026-08-21 14:08:17 +0000
committerAndrew Morton <akpm@linux-foundation.org>2026-08-27 22:50:04 -0700
commitbd5659f71cd8cb79c9b250861344692e003b8d4e (patch)
tree1b1f428e2218880cafa7522eacdcdc9a54d54715 /include
parentae67b0e940a60797cb6c0d05f8d206a2bfac4ef6 (diff)
downloadlinux-next-bd5659f71cd8cb79c9b250861344692e003b8d4e.tar.gz
linux-next-bd5659f71cd8cb79c9b250861344692e003b8d4e.zip
resource: fix lost wakeup when waiting for a muxed region
A task waiting for a muxed region can sleep forever in TASK_UNINTERRUPTIBLE even though the region it waits for is already free. __request_region_locked() queues itself on muxed_resource_wait and drops resource_lock before setting TASK_UNINTERRUPTIBLE, while __release_region() wakes the queue after dropping the same lock. A wakeup landing in between finds TASK_RUNNING, does not match TASK_NORMAL and is discarded; callers hold a muxed region only across a bounded transaction, so no further release is coming. The task is unkillable and its caller never returns. The window is one store wide, but an interrupt is enough to hold the waiter in it, and the machine this was seen on runs PREEMPT_DYNAMIC in its voluntary default. Since v6.11 spd5118 exports the DDR5 sensors of AMD boards through i2c-piix4, which takes a muxed region per SMBus transaction; a third of the in-tree users of request_muxed_region() are hwmon drivers, so reading a world-readable attribute is all an unprivileged user needs to drive the contention. The blocked task sleeps holding the i2c adapter bus lock, and 27 more piled up behind it. Reproduced by building a kernel with the two orderings selectable at runtime and a 2ms delay inside the window. Switching only that knob, a two-thread barriered reproducer loses the wakeup 200 times out of 200 before the fix and 0 out of 200 after it; without the delay it goes 20000 times through the wait path and loses none. Fix it by setting the task state before dropping resource_lock, as prepare_to_wait() does: the releasing side needs resource_lock to unlink the resource, so it cannot reach the wakeup before the state is published. Link: https://lore.kernel.org/20260821-b4-resource-muxed-lost-wakeup-v1-1-37eb6473a76c@gmail.com Fixes: 8b6d043b7ee2 ("resource: shared I/O region support") Signed-off-by: DAI RENJIE <drj19981414013@gmail.com> Reviewed-by: Bradley Morgan <brads@mainlining.org> Assisted-by: Claude:claude-opus-5 Reviewed-by: Andrew Morton <akpm@linux-foundation.org> Cc: Mark Brown <broonie@kernel.org> Cc: Kees Cook <kees@kernel.org> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'include')
0 files changed, 0 insertions, 0 deletions