Skip to content

Conversation

@pelwell
Copy link
Contributor

@pelwell pelwell commented Mar 15, 2024

dw_axi_dma_interrupt disables interrupts for the duration of the channel handling. It does so by clearing a bit in the DMA_CFG register - an action that involves a read-modify-write. That in itself would be safe because there will be no further interrupts, hence no reentrancy, were it the only bit of code accessing that register.

The only neighbour of INT_EN is DMAC_EN - the main enable for the block. That's not the sort of thing you would expect to be modified during the normal course of operation, but bizarrely it is set at the start of the transfer of every block, in axi_chan_block_xfer_star, by a call to axi_dma_enable. This can lead to INT_EN being accidentally cleared, which causes all DMA transfers to time out.

One might think that the enabling was being delayed until the first transfer, but the probe function calls axi_dma_resume which in turn calls axi_dma_enable, so that isn't the case.

Fix the atomicity problem by removing the spurious call to axi_dma_enable.

See: #6020, #5858, #5865

dw_axi_dma_interrupt disables interrupts for the duration of the channel
handling. It does so by clearing a bit in the DMA_CFG register - an
action that involves a read-modify-write. That in itself would be safe
because there will be no further interrupts, hence no reentrancy, were
it the only bit of code accessing that register.

The only neighbour of INT_EN is DMAC_EN - the main enable for the block.
That's not the sort of thing you would expect to be modified during the
normal course of operation, but bizarrely it is set at the start of the
transfer of every block, in axi_chan_block_xfer_star, by a call to
axi_dma_enable. This can lead to INT_EN being accidentally cleared,
which causes all DMA transfers to time out.

One might think that the enabling was being delayed until the first
transfer, but the probe function calls axi_dma_resume which in turn
calls axi_dma_enable, so that isn't the case.

Fix the atomicity problem by removing the spurious call to
axi_dma_enable.

Signed-off-by: Phil Elwell <[email protected]>
@pelwell pelwell merged commit b35cdbc into raspberrypi:rpi-6.6.y Mar 15, 2024
popcornmix added a commit to raspberrypi/firmware that referenced this pull request Mar 19, 2024
See: raspberrypi/linux#6054

kernel: overlays: i2c-rtc: pcf8563 supports wakeup-source
See: raspberrypi/linux#6052

kernel: ARM: dts: bcm2712: Move /soc/sound to bcm2712-rpi
See: raspberrypi/linux#6051

kernel: I2C: Improve reliability at higher bus speeds
See: raspberrypi/linux#6050

kernel: dmaengine: dw-axi-dmac: Fix a non-atomic update
See: raspberrypi/linux#6044

kernel: dtoverlays: Add a disconnect_on_idle override to i2c-mux
See: raspberrypi/linux#6040

kernel: Add support for generic i2c-mux base-nr property
See: raspberrypi/linux#6038

kernel: dtoverlays: Fixup pendown gpio polarity for ads7846 users
See: raspberrypi/linux#6029
popcornmix added a commit to raspberrypi/rpi-firmware that referenced this pull request Mar 19, 2024
See: raspberrypi/linux#6054

kernel: overlays: i2c-rtc: pcf8563 supports wakeup-source
See: raspberrypi/linux#6052

kernel: ARM: dts: bcm2712: Move /soc/sound to bcm2712-rpi
See: raspberrypi/linux#6051

kernel: I2C: Improve reliability at higher bus speeds
See: raspberrypi/linux#6050

kernel: dmaengine: dw-axi-dmac: Fix a non-atomic update
See: raspberrypi/linux#6044

kernel: dtoverlays: Add a disconnect_on_idle override to i2c-mux
See: raspberrypi/linux#6040

kernel: Add support for generic i2c-mux base-nr property
See: raspberrypi/linux#6038

kernel: dtoverlays: Fixup pendown gpio polarity for ads7846 users
See: raspberrypi/linux#6029
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants