Describe the bug
drivers/misc/rp1-pio.c performs the DMA channel free + re-request sequence for
PIO_IOC_SM_CONFIG_XFER while holding a spinlock (atomic context). Both
dma_release_channel() and dma_request_chan() take the kernfs rwsem via
sysfs_remove_link()/sysfs_create_link(), which may sleep. When the rwsem is
contended (e.g. concurrent sysfs activity from container runtimes / udev), the
scheduler fires BUG: scheduling while atomic, and we observe subsequent full
system hangs/spontaneous reboots on a production device (with kernel.panic=1,
a panic reboots silently ~seconds later; MTBF 2–11 min under our workload). Kernel is the downstream rpi tree as packaged by balenaOS 7.4.0 for CM5.
To reproduce
Alternate WS2812 output between two GPIOs/buffer sizes on one PIO SM via piolib
(pattern used by adafruit-blinka-raspberry-pi5-neopixel, which keeps one global
SM and calls pio_sm_config_xfer() whenever the transfer size changes). Driving
two LED chains (1152 B and 92 B buffers) alternately at ~30 Hz each yields
~60 SM_CONFIG_XFER ioctls/sec; the BUG fires intermittently when sysfs is busy
(container churn), and the machine eventually hard-hangs/reboots.
System
Logs
[ 103.180175] BUG: scheduling while atomic: hardware/4094/0x00000002
[ 103.180255] CPU: 2 UID: 0 PID: 4094 Comm: hardware Not tainted 6.12.61-v8-16k #1
[ 103.180259] Hardware name: Raspberry Pi Compute Module 5 Rev 1.0 (DT)
[ 103.180262] Call trace:
[ 103.180264] dump_backtrace+0x9c/0x100
[ 103.180276] show_stack+0x20/0x38
[ 103.180278] dump_stack_lvl+0x78/0x90
[ 103.180289] dump_stack+0x18/0x28
[ 103.180291] __schedule_bug+0x58/0x78
[ 103.180295] __schedule+0x924/0xb70
[ 103.180300] schedule+0x3c/0x148
[ 103.180302] schedule_preempt_disabled+0x2c/0x50
[ 103.180304] rwsem_down_write_slowpath+0x24c/0x6c8
[ 103.180308] down_write+0xa0/0xb0
[ 103.180310] kernfs_remove_by_name_ns+0x48/0xe8
[ 103.180315] sysfs_remove_link+0x34/0x48
[ 103.180318] dma_release_channel+0x7c/0x120
[ 103.180322] rp1_pio_sm_dma_free+0x84/0xa0 [rp1_pio]
[ 103.180339] rp1_pio_sm_config_xfer_internal+0x41c/0x478 [rp1_pio]
[ 103.180342] rp1_pio_sm_config_xfer_user+0x28/0x40 [rp1_pio]
[ 103.180346] rp1_pio_ioctl+0x19c/0x250 [rp1_pio]
[ 103.180350] __arm64_sys_ioctl+0xb0/0x100
...
[ 103.180420] BUG: scheduling while atomic: hardware/4094/0x00000000
[ 103.180455] CPU: 2 UID: 0 PID: 4094 Comm: hardware Tainted: G W 6.12.61-v8-16k #1
[ 103.180461] Call trace:
...
[ 103.180482] rwsem_down_write_slowpath+0x24c/0x6c8
[ 103.180484] down_write+0xa0/0xb0
[ 103.180486] kernfs_add_one+0x44/0x160
[ 103.180488] kernfs_create_link+0x6c/0xf8
[ 103.180490] sysfs_do_create_link_sd+0x74/0x108
[ 103.180493] sysfs_create_link+0x38/0x58
[ 103.180495] dma_request_chan+0xc0/0x2f0
[ 103.180497] rp1_pio_sm_config_xfer_internal+0x1a4/0x478 [rp1_pio]
[ 103.180503] rp1_pio_sm_config_xfer_user+0x28/0x40 [rp1_pio]
[ 103.180506] rp1_pio_ioctl+0x19c/0x250 [rp1_pio]
Note the two reports are the two halves of a single reconfiguration
(free old channel, request new one) inside one SM_CONFIG_XFER ioctl — the
spinlock appears to be held across the whole sequence.
Additional context
Same bug class as the pwm-pio atomic-context fix (#7439 / the 6.18
"scheduling while atomic" in pwm_pio_rp1_apply), but this instance is in the
rp1-pio chardev DMA reconfig path and reproduces on 6.12.x. Workaround we use:
avoid repeated SM_CONFIG_XFER (keep buffer size and pin constant per process).
Related but distinct: #6918 discusses config/transfer synchronization in the same ioctl path but not the atomic-context sleep reported here.
Describe the bug
drivers/misc/rp1-pio.cperforms the DMA channel free + re-request sequence forPIO_IOC_SM_CONFIG_XFERwhile holding a spinlock (atomic context). Bothdma_release_channel()anddma_request_chan()take the kernfs rwsem viasysfs_remove_link()/sysfs_create_link(), which may sleep. When the rwsem iscontended (e.g. concurrent sysfs activity from container runtimes / udev), the
scheduler fires
BUG: scheduling while atomic, and we observe subsequent fullsystem hangs/spontaneous reboots on a production device (with
kernel.panic=1,a panic reboots silently ~seconds later; MTBF 2–11 min under our workload). Kernel is the downstream rpi tree as packaged by balenaOS 7.4.0 for CM5.
To reproduce
Alternate WS2812 output between two GPIOs/buffer sizes on one PIO SM via piolib
(pattern used by adafruit-blinka-raspberry-pi5-neopixel, which keeps one global
SM and calls
pio_sm_config_xfer()whenever the transfer size changes). Drivingtwo LED chains (1152 B and 92 B buffers) alternately at ~30 Hz each yields
~60
SM_CONFIG_XFERioctls/sec; the BUG fires intermittently when sysfs is busy(container churn), and the machine eventually hard-hangs/reboots.
System
Logs
Note the two reports are the two halves of a single reconfiguration
(free old channel, request new one) inside one
SM_CONFIG_XFERioctl — thespinlock appears to be held across the whole sequence.
Additional context
Same bug class as the pwm-pio atomic-context fix (#7439 / the 6.18
"scheduling while atomic" in
pwm_pio_rp1_apply), but this instance is in therp1-pio chardev DMA reconfig path and reproduces on 6.12.x. Workaround we use:
avoid repeated
SM_CONFIG_XFER(keep buffer size and pin constant per process).Related but distinct: #6918 discusses config/transfer synchronization in the same ioctl path but not the atomic-context sleep reported here.