linux-mips
[Top] [All Lists]

Re: RFH: What are the semantics of writeb() and friends?

To: "Maciej W. Rozycki" <macro@linux-mips.org>
Subject: Re: RFH: What are the semantics of writeb() and friends?
From: Alan Cox <alan@lxorguk.ukuu.org.uk>
Date: Fri, 01 Jul 2005 12:46:28 +0100
Cc: David Daney <ddaney@avtrex.com>, linux-mips@linux-mips.org
In-reply-to: <Pine.LNX.4.61L.0507011002520.30138@blysk.ds.pg.gda.pl>
Original-recipient: rfc822;linux-mips@linux-mips.org
References: <01049E563C8ECC43AD6B53A5AF419B38098BD2@avtrex-server2.hq2.avtrex.com> <Pine.LNX.4.61L.0507011002520.30138@blysk.ds.pg.gda.pl>
Sender: linux-mips-bounce@linux-mips.org
On Gwe, 2005-07-01 at 10:33, Maciej W. Rozycki wrote:
> > al.?  I would assume that the effects of these must be in the same order 
> > that they were issued, and that any hardware write back queue cannot 
> > combine or merge them in any way.  Is that correct?
> 
>  No it's not.  You need to insert appropriate barriers, one of: wmb(), 
> mb() or rmb().  In rare cases you may need to use iob(), which is 
> currently non-portable (which reminds me I should really push it 
> upstream).

Its even more complicated than that 8)

writeb/writel may be merged in some cases (but not re-ordered) for I/O
devices but a simple mb() will only synchronize them as viewed from
cpu/memory interface. There are two other synchronization points. From
the bridge with the I/O device (typically the PCI root bridge) which is
not enforced automatically across processors on some large numa boxes
but is not usually a problem and on the PCI bus itself.

PCI permits posting (delaying writes) and some forms of merging (but not
re-ordering). Thus if you need an I/O to hit a device on the PCI bus and
know it arrived you must follow it by a read from the same device. So
for example if you want to shut down a DMA transfer and free the buffer
for a PCI device you
need to do

                writel(TURN_DMA_OFF, dev->control);
                readl(dev->something);
                /* Only now is the free safe */

Alan


<Prev in Thread] Current Thread [Next in Thread>