[PATCH v6 01/15] ARM: mxs: Add core definitions
Russell King - ARM Linux
linux at arm.linux.org.uk
Wed Dec 15 12:27:54 EST 2010
On Wed, Dec 15, 2010 at 06:17:33PM +0100, Arnd Bergmann wrote:
> The problem is that __raw_* is defined as a pointer reference on
> all architectures, nothing more. Depending on the architecture and
> compiler, sometimes even on the I/O subsystem, it may or may not
> do any of the following:
>
> * work on mapped PCI addresses
> * work on mapped non-PCI addresses
> * work on addresses returned from ioport_map
> * be synchronized with spinlocks
Err. Even readl/writel are not synchronized with spinlocks. See
Documentation/memory-barriers.txt:
| Under certain circumstances (especially involving NUMA), I/O accesses within
| two spinlocked sections on two different CPUs may be seen as interleaved by the
| PCI bridge, because the PCI bridge does not necessarily participate in the
| cache-coherence protocol, and is therefore incapable of issuing the required
| read memory barriers.
|
| For example:
|
| CPU 1 CPU 2
| =============================== ===============================
| spin_lock(Q)
| writel(0, ADDR)
| writel(1, DATA);
| spin_unlock(Q);
| spin_lock(Q);
| writel(4, ADDR);
| writel(5, DATA);
| spin_unlock(Q);
|
| may be seen by the PCI bridge as follows:
|
| STORE *ADDR = 0, STORE *ADDR = 4, STORE *DATA = 1, STORE *DATA = 5
|
| which would probably cause the hardware to malfunction.
More information about the linux-arm-kernel
mailing list