[PATCH] USB: ehci: use packed, aligned(4) instead of removing the packed attribute

Nicolas Pitre nico at fluxnic.net
Fri Jun 24 21:25:43 EDT 2011


On Tue, 21 Jun 2011, Arnd Bergmann wrote:

> On Tuesday 21 June 2011, Nicolas Pitre wrote:
> > On Mon, 20 Jun 2011, Arnd Bergmann wrote:
> 
> > 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



More information about the linux-arm-kernel mailing list