-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Title: DMA buffer ring handling broken: head_idx
not incremented in rp1_pio_sm_xfer_data()
Description:
There is a critical issue in the rp1_pio_sm_xfer_data()
function related to DMA buffer management.
Currently, the function allocates and uses a buffer from the internal DMA ring via:
dbi = &dma->bufs[dma->head_idx % dma->buf_count];
However, after submitting the DMA transfer, the head_idx
is never incremented. As a result:
- Every transfer reuses the same buffer (typically
bufs[0]
). - Only the first transfer works correctly.
- Subsequent DMA transfers appear to fail silently (or overwrite data in-flight).
- The
buf_sem
semaphore eventually blocks further transfers, since the ring never advances.
This breaks multi-buffer DMA handling and causes subtle data loss and transfer hangs.
Suggested Fix:
Increment head_idx
after a successful DMA submission:
ret = dmaengine_submit(desc);
if (ret < 0) {
dev_err(dev, "dmaengine_submit failed (%d)\n", ret);
return ret;
}
dma_async_issue_pending(dma->chan);
/* Add this line to advance the ring */
dma->head_idx++;
return 0;
The corresponding tail_idx++
already occurs in the DMA completion callback, so this fix restores proper ring behavior.
Impact:
This bug causes:
- DMA transfers after the first one to fail silently.
- Potential data corruption due to buffer reuse.
- System hangs if the ring fills and buffers never recycle.
Steps to reproduce the behaviour
just analyze the code ; the callback is doing the tail_idx++ but for the head no increase is done.
i tried to use my driver wich includes the rp1-pio driver with a ping pong buffer scenario and reading data from the second buffer results in 0 reads.
Device (s)
Raspberry Pi 5
System
latest
Logs
no logs
Additional context
No response