freenode
Kernel & Low-Level

Kernel fix stops tasks hanging forever on muxed I/O regions

A 16-year-old lost-wakeup race left processes unkillable after brief SMBus and similar contention, reachable from ordinary sensor reads.

A long-standing race in the Linux kernel’s shared I/O region handling can leave a waiting task asleep forever in an uninterruptible state, even after the region it needs has already been freed. Dai Renjie reported and fixed the bug on the kernel mailing list.

When one side waits for a muxed region and another releases it, a wakeup can land in a one-instruction window before the waiter has published that it is sleeping. The wakeup is then discarded. Callers hold these regions only for short transactions, so nothing wakes the task again. The result is an unkillable process whose caller never returns.

The failure became practical to hit after Linux 6.11. The spd5118 driver exposes DDR5 sensors on many AMD boards over SMBus, taking a muxed region for each transaction. Roughly a third of in-tree muxed-region users are hwmon drivers, so reading a world-readable sysfs attribute is enough for an unprivileged user to create contention. In the observed case the stuck task still held the I2C adapter lock, and dozens of others piled up behind it.

The fix publishes the sleeping state before dropping the resource lock, matching the usual prepare-to-wait pattern, so a release cannot wake the queue before the waiter is ready. The bug dates to the original shared I/O region support about sixteen years ago; the patch is marked for stable backports. Bradley Morgan reviewed it, and Andrew Morton asked maintainers to consider a proper MAINTAINERS entry for the code.