Skip to content

rp1-pio: BUG: scheduling while atomic — DMA channel release/request under spinlock in SM_CONFIG_XFER (6.12.61, CM5) #7512

Description

@owendaw

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions