[PATCH] USB: ehci: use packed, aligned(4) instead of removing the packed attribute
From: nico@fluxnic.net (Nicolas Pitre)
Date: 2011-06-25 01:25:43
On Tue, 21 Jun 2011, Arnd Bergmann wrote:
On Tuesday 21 June 2011, Nicolas Pitre wrote:quoted
On Mon, 20 Jun 2011, Arnd Bergmann wrote:quoted
This example is flawed. The DMA API documentation already forbids DMA to the stack because of cache line sharing issues. If you declare your buffer outside of the function body, the compiler can't optimize away the buffer store anymore, and this example works as expected without any memory clobber.Ok, another example, even simpler: int f(int *dma_buf, volatile int *mmio_reg) { (void) *mmio_reg; /* wait for DMA to complete */ return *dma_buf; } gcc-4.4, 4.5 and 4.6 all turn this into: ldr r0, [r0, #0] ldr r3, [r1, #0] bx lr which means that the dma_buf variable is dereferenced before the volatile mmio_reg variable, which opens up a race: An interrupt may have signalled us that a DMA is in progress, so we read a MMIO register from the device (this is guaranteed to flush the DMA on PCI and similar buses). If we read the dma_buf before we read the mmio register, the data we get back may be stale. Adding a barrier() between the two turns the assembly into the expected ldr r3, [r1, #0] ldr r0, [r0, #0] bx lr
But isn't the usual dma_unmap_*() API call providing that barrier already? Nicolas