From: Jesse Barnes <jbarnes@engr.sgi.com>
To: Matthew Wilcox <willy@debian.org>
Cc: Grant Grundler <grundler@parisc-linux.org>,
Andrew Vasquez <andrew.vasquez@qlogic.com>,
pj@sgi.com, linux-scsi@vger.kernel.org, mdr@cthulhu.engr.sgi.com,
jeremy@cthulhu.engr.sgi.com, djh@cthulhu.engr.sgi.com,
Andrew Morton <akpm@osdl.org>,
linux-kernel@vger.kernel.org
Subject: Re: Documentation/io_ordering.txt is wrong
Date: Mon, 20 Sep 2004 17:38:16 -0700 [thread overview]
Message-ID: <200409201738.16746.jbarnes@engr.sgi.com> (raw)
In-Reply-To: <20040918175714.GD642@parcelfarce.linux.theplanet.co.uk>
[-- Attachment #1: Type: text/plain, Size: 968 bytes --]
On Saturday, September 18, 2004 10:57 am, Matthew Wilcox wrote:
> On Sat, Sep 18, 2004 at 12:10:01AM -0600, Grant Grundler wrote:
> > Jesse Barnes wrote:
> > ...
> >
> > > Btw Andrew (Vasquez), there's a small doc I put together that should
> > > describe when you have to worry about PCI posting. It's in the tree:
> > > Documentation/io_ordering.txt. If it's incomplete or confusing, just
> > > let me know and I'll update it.
> >
> > Jesse,
> > Both. incomplete and confusing.
> > "concrete example of a hypothetical driver" wasn't my first warning
> > this document needed work. :^)
>
> Not just incomplete and confusing, but actively wrong. spin_lock/
> spin_unlock should imply ordering of readb(). What you're describing
> there is __readb(). See Documentation/DocBook/deviceiobook.tmpl. Also,
> rmb() should ensure ordering of io reads; there should be no need to
> touch the device.
Is this any better? I just sent it off to Grant too.
Thanks,
Jesse
[-- Attachment #2: io_ordering.txt --]
[-- Type: text/plain, Size: 2098 bytes --]
Dealing with posted writes
--------------------------
On some platforms platforms, driver writers are responsible for
ensuring that I/O writes to memory-mapped addresses on their device
arrive in the order intended. This is typically done by reading a
'safe' device or bridge register, causing the I/O chipset to flush
pending writes to the device before any reads are posted. A driver
would usually use this technique immediately prior to the exit of a
critical section of code protected by spinlocks. This would ensure
that subsequent writes to I/O space arrived only after all prior
writes (much like a memory barrier op, mb(), only with respect to
I/O).
Some pseudocode to illustrate the problem:
...
CPU A: spin_lock_irqsave(&dev_lock, flags)
CPU A: ...
CPU A: writel(newval, ring_ptr);
CPU A: spin_unlock_irqrestore(&dev_lock, flags)
...
CPU B: spin_lock_irqsave(&dev_lock, flags)
CPU B: ...
CPU B: writel(newval2, ring_ptr);
CPU B: spin_unlock_irqrestore(&dev_lock, flags)
...
In the case above, the device may receive newval2 before it receives newval,
which could cause problems. Fixing it is easy enough though:
...
CPU A: spin_lock_irqsave(&dev_lock, flags)
CPU A: ...
CPU A: writel(newval, ring_ptr);
CPU A: (void)readl(safe_register); /* maybe a config register? */
CPU A: spin_unlock_irqrestore(&dev_lock, flags)
...
CPU B: spin_lock_irqsave(&dev_lock, flags)
CPU B: ...
CPU B: writel(newval2, ring_ptr);
CPU B: (void)readl(safe_register); /* or read_relaxed() */
CPU B: spin_unlock_irqrestore(&dev_lock, flags)
Here, the reads from safe_register will cause the I/O chipset to flush any
pending writes before actually posting the read to the chipset, preventing
possible data corruption.
This sort of synchronization is only necessary for read/write calls,
not in/out calls, since they're by definition strongly ordered.
We should probably add a writeflush call or something to deal with the
above in an easier to read way. Some platforms could even implement
such a routine more efficiently than a regular read.
prev parent reply other threads:[~2004-09-21 0:38 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20040917183029.GW642@parcelfarce.linux.theplanet.co.uk>
[not found] ` <20040918061001.GC21456@colo.lackof.org>
2004-09-18 17:57 ` Matthew Wilcox
2004-09-20 23:39 ` Jesse Barnes
2004-09-21 0:38 ` Jesse Barnes [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200409201738.16746.jbarnes@engr.sgi.com \
--to=jbarnes@engr.sgi.com \
--cc=akpm@osdl.org \
--cc=andrew.vasquez@qlogic.com \
--cc=djh@cthulhu.engr.sgi.com \
--cc=grundler@parisc-linux.org \
--cc=jeremy@cthulhu.engr.sgi.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=mdr@cthulhu.engr.sgi.com \
--cc=pj@sgi.com \
--cc=willy@debian.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome