[PATCH v4 13/13] mmc: tmio: add barriers to IO operations
Guennadi Liakhovetski
g.liakhovetski at gmx.de
Wed Feb 20 08:59:50 EST 2013
On Mon, 18 Feb 2013, Arnd Bergmann wrote:
> On Monday 18 February 2013, Guennadi Liakhovetski wrote:
> > On Mon, 18 Feb 2013, Arnd Bergmann wrote:
> >
> > Sorry, I'm not sure how best to describe it, and I don't have sufficient
> > information myself. In any case on a block-diagram of sh73a0 SDHI devices
> > aren't directly connected to a common super-highway bus, instead they are
> > on a bus-splitter. One more thing I forgot to mention - this error has
> > been observed on SMP.
>
> Ah, I guess that explains it. If you have one CPU filling the buffer
> and another CPU reading it, you need an smp_wmb/wmp_rmb pair.
>
> That case can easily happen with tmio interrupt handler in PIO
> mode.
Ok, I also managed to reproduce it on UP, and it definitely is related to
MMC_CAP_POWER_OFF_CARD, but I'll have to do some more work on it. I asked
Chris to hold back on this patch for now.
Thanks
Guennadi
> > I checked clock code under drivers/sh/clk, I don't see any relevant
> > __raw_* operations there. One I do see, however, GIC code does use
> > *_relaxed() accessors, but under raw spinlocks... Do those provide
> > sufficient barriers?
>
> A spinlock by definition contains an SMP barrier, which seems to be
> what is missing here. I don't know if that is enough here, because
> the spinlock only needs barriers to protect against other users
> behind the same spinlock.
>
> In architecture independent code, any smp_wmb() on the writer side
> must be paired with an smp_rmb on the reader. You probably have the
> sufficient barriers on the side that initiates the I/O because
> that uses a dmb() in the MMIO instructions, but that is only
> by accident and not portable.
>
> Also, in the uniprocessor case, you have more barriers than you
> need, which limits the performance. The best solution for
> both performance and readability would be to use readw_relaxed()
> and writew_relaxed() and manually add the barriers you actually
> need, i.e. two smp_rmb()/smp_wmb() in the PIO case, and a
> wmb() before you start a real DMA to the device and an rmb()
> after a DMA from the device is complete.
>
> Arnd
>
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
More information about the devicetree-discuss
mailing list