linux/Documentation/io_ordering.txt
<<
>>
Prefs
   1On some platforms, so-called memory-mapped I/O is weakly ordered.  On such
   2platforms, driver writers are responsible for ensuring that I/O writes to
   3memory-mapped addresses on their device arrive in the order intended.  This is
   4typically done by reading a 'safe' device or bridge register, causing the I/O
   5chipset to flush pending writes to the device before any reads are posted.  A
   6driver would usually use this technique immediately prior to the exit of a
   7critical section of code protected by spinlocks.  This would ensure that
   8subsequent writes to I/O space arrived only after all prior writes (much like a
   9memory barrier op, mb(), only with respect to I/O).
  10
  11A more concrete example from a hypothetical device driver:
  12
  13        ...
  14CPU A:  spin_lock_irqsave(&dev_lock, flags)
  15CPU A:  val = readl(my_status);
  16CPU A:  ...
  17CPU A:  writel(newval, ring_ptr);
  18CPU A:  spin_unlock_irqrestore(&dev_lock, flags)
  19        ...
  20CPU B:  spin_lock_irqsave(&dev_lock, flags)
  21CPU B:  val = readl(my_status);
  22CPU B:  ...
  23CPU B:  writel(newval2, ring_ptr);
  24CPU B:  spin_unlock_irqrestore(&dev_lock, flags)
  25        ...
  26
  27In the case above, the device may receive newval2 before it receives newval,
  28which could cause problems.  Fixing it is easy enough though:
  29
  30        ...
  31CPU A:  spin_lock_irqsave(&dev_lock, flags)
  32CPU A:  val = readl(my_status);
  33CPU A:  ...
  34CPU A:  writel(newval, ring_ptr);
  35CPU A:  (void)readl(safe_register); /* maybe a config register? */
  36CPU A:  spin_unlock_irqrestore(&dev_lock, flags)
  37        ...
  38CPU B:  spin_lock_irqsave(&dev_lock, flags)
  39CPU B:  val = readl(my_status);
  40CPU B:  ...
  41CPU B:  writel(newval2, ring_ptr);
  42CPU B:  (void)readl(safe_register); /* maybe a config register? */
  43CPU B:  spin_unlock_irqrestore(&dev_lock, flags)
  44
  45Here, the reads from safe_register will cause the I/O chipset to flush any
  46pending writes before actually posting the read to the chipset, preventing
  47possible data corruption.
  48
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.