docs/memory-barriers.txt: Fix style, spacing and grammar in I/O section
Commit4614bbdee3
("docs/memory-barriers.txt: Rewrite "KERNEL I/O BARRIER EFFECTS" section") rewrote the I/O ordering section of memory-barriers.txt. Subsequently, Ingo noticed a number of issues with the style, spacing and grammar of the rewritten section. Fix them based on his suggestions. Link: https://lkml.kernel.org/r/20190410105833.GA116161@gmail.com Fixes:4614bbdee3
("docs/memory-barriers.txt: Rewrite "KERNEL I/O BARRIER EFFECTS" section") Reported-by: Ingo Molnar <mingo@kernel.org> Acked-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Will Deacon <will.deacon@arm.com>
This commit is contained in:
parent
01e3b958ef
commit
0cde62a46e
@ -2517,80 +2517,88 @@ guarantees:
|
|||||||
|
|
||||||
(*) readX(), writeX():
|
(*) readX(), writeX():
|
||||||
|
|
||||||
The readX() and writeX() MMIO accessors take a pointer to the peripheral
|
The readX() and writeX() MMIO accessors take a pointer to the
|
||||||
being accessed as an __iomem * parameter. For pointers mapped with the
|
peripheral being accessed as an __iomem * parameter. For pointers
|
||||||
default I/O attributes (e.g. those returned by ioremap()), then the
|
mapped with the default I/O attributes (e.g. those returned by
|
||||||
ordering guarantees are as follows:
|
ioremap()), the ordering guarantees are as follows:
|
||||||
|
|
||||||
1. All readX() and writeX() accesses to the same peripheral are ordered
|
1. All readX() and writeX() accesses to the same peripheral are ordered
|
||||||
with respect to each other. For example, this ensures that MMIO register
|
with respect to each other. This ensures that MMIO register writes by
|
||||||
writes by the CPU to a particular device will arrive in program order.
|
the CPU to a particular device will arrive in program order.
|
||||||
|
|
||||||
2. A writeX() by the CPU to the peripheral will first wait for the
|
2. A writeX() by the CPU to the peripheral will first wait for the
|
||||||
completion of all prior CPU writes to memory. For example, this ensures
|
completion of all prior CPU writes to memory. This ensures that
|
||||||
that writes by the CPU to an outbound DMA buffer allocated by
|
writes by the CPU to an outbound DMA buffer allocated by
|
||||||
dma_alloc_coherent() will be visible to a DMA engine when the CPU writes
|
dma_alloc_coherent() will be visible to a DMA engine when the CPU
|
||||||
to its MMIO control register to trigger the transfer.
|
writes to its MMIO control register to trigger the transfer.
|
||||||
|
|
||||||
3. A readX() by the CPU from the peripheral will complete before any
|
3. A readX() by the CPU from the peripheral will complete before any
|
||||||
subsequent CPU reads from memory can begin. For example, this ensures
|
subsequent CPU reads from memory can begin. This ensures that reads
|
||||||
that reads by the CPU from an incoming DMA buffer allocated by
|
by the CPU from an incoming DMA buffer allocated by
|
||||||
dma_alloc_coherent() will not see stale data after reading from the DMA
|
dma_alloc_coherent() will not see stale data after reading from the
|
||||||
engine's MMIO status register to establish that the DMA transfer has
|
DMA engine's MMIO status register to establish that the DMA transfer
|
||||||
completed.
|
has completed.
|
||||||
|
|
||||||
4. A readX() by the CPU from the peripheral will complete before any
|
4. A readX() by the CPU from the peripheral will complete before any
|
||||||
subsequent delay() loop can begin execution. For example, this ensures
|
subsequent delay() loop can begin execution. This ensures that two
|
||||||
that two MMIO register writes by the CPU to a peripheral will arrive at
|
MMIO register writes by the CPU to a peripheral will arrive at least
|
||||||
least 1us apart if the first write is immediately read back with readX()
|
1us apart if the first write is immediately read back with readX()
|
||||||
and udelay(1) is called prior to the second writeX().
|
and udelay(1) is called prior to the second writeX():
|
||||||
|
|
||||||
__iomem pointers obtained with non-default attributes (e.g. those returned
|
writel(42, DEVICE_REGISTER_0); // Arrives at the device...
|
||||||
by ioremap_wc()) are unlikely to provide many of these guarantees.
|
readl(DEVICE_REGISTER_0);
|
||||||
|
udelay(1);
|
||||||
|
writel(42, DEVICE_REGISTER_1); // ...at least 1us before this.
|
||||||
|
|
||||||
|
The ordering properties of __iomem pointers obtained with non-default
|
||||||
|
attributes (e.g. those returned by ioremap_wc()) are specific to the
|
||||||
|
underlying architecture and therefore the guarantees listed above cannot
|
||||||
|
generally be relied upon for accesses to these types of mappings.
|
||||||
|
|
||||||
(*) readX_relaxed(), writeX_relaxed():
|
(*) readX_relaxed(), writeX_relaxed():
|
||||||
|
|
||||||
These are similar to readX() and writeX(), but provide weaker memory
|
These are similar to readX() and writeX(), but provide weaker memory
|
||||||
ordering guarantees. Specifically, they do not guarantee ordering with
|
ordering guarantees. Specifically, they do not guarantee ordering with
|
||||||
respect to normal memory accesses or delay() loops (i.e bullets 2-4 above)
|
respect to normal memory accesses or delay() loops (i.e. bullets 2-4
|
||||||
but they are still guaranteed to be ordered with respect to other accesses
|
above) but they are still guaranteed to be ordered with respect to other
|
||||||
to the same peripheral when operating on __iomem pointers mapped with the
|
accesses to the same peripheral when operating on __iomem pointers
|
||||||
default I/O attributes.
|
mapped with the default I/O attributes.
|
||||||
|
|
||||||
(*) readsX(), writesX():
|
(*) readsX(), writesX():
|
||||||
|
|
||||||
The readsX() and writesX() MMIO accessors are designed for accessing
|
The readsX() and writesX() MMIO accessors are designed for accessing
|
||||||
register-based, memory-mapped FIFOs residing on peripherals that are not
|
register-based, memory-mapped FIFOs residing on peripherals that are not
|
||||||
capable of performing DMA. Consequently, they provide only the ordering
|
capable of performing DMA. Consequently, they provide only the ordering
|
||||||
guarantees of readX_relaxed() and writeX_relaxed(), as documented above.
|
guarantees of readX_relaxed() and writeX_relaxed(), as documented above.
|
||||||
|
|
||||||
(*) inX(), outX():
|
(*) inX(), outX():
|
||||||
|
|
||||||
The inX() and outX() accessors are intended to access legacy port-mapped
|
The inX() and outX() accessors are intended to access legacy port-mapped
|
||||||
I/O peripherals, which may require special instructions on some
|
I/O peripherals, which may require special instructions on some
|
||||||
architectures (notably x86). The port number of the peripheral being
|
architectures (notably x86). The port number of the peripheral being
|
||||||
accessed is passed as an argument.
|
accessed is passed as an argument.
|
||||||
|
|
||||||
Since many CPU architectures ultimately access these peripherals via an
|
Since many CPU architectures ultimately access these peripherals via an
|
||||||
internal virtual memory mapping, the portable ordering guarantees provided
|
internal virtual memory mapping, the portable ordering guarantees
|
||||||
by inX() and outX() are the same as those provided by readX() and writeX()
|
provided by inX() and outX() are the same as those provided by readX()
|
||||||
respectively when accessing a mapping with the default I/O attributes.
|
and writeX() respectively when accessing a mapping with the default I/O
|
||||||
|
attributes.
|
||||||
|
|
||||||
Device drivers may expect outX() to emit a non-posted write transaction
|
Device drivers may expect outX() to emit a non-posted write transaction
|
||||||
that waits for a completion response from the I/O peripheral before
|
that waits for a completion response from the I/O peripheral before
|
||||||
returning. This is not guaranteed by all architectures and is therefore
|
returning. This is not guaranteed by all architectures and is therefore
|
||||||
not part of the portable ordering semantics.
|
not part of the portable ordering semantics.
|
||||||
|
|
||||||
(*) insX(), outsX():
|
(*) insX(), outsX():
|
||||||
|
|
||||||
As above, the insX() and outsX() accessors provide the same ordering
|
As above, the insX() and outsX() accessors provide the same ordering
|
||||||
guarantees as readsX() and writesX() respectively when accessing a mapping
|
guarantees as readsX() and writesX() respectively when accessing a
|
||||||
with the default I/O attributes.
|
mapping with the default I/O attributes.
|
||||||
|
|
||||||
(*) ioreadX(), iowriteX()
|
(*) ioreadX(), iowriteX():
|
||||||
|
|
||||||
These will perform appropriately for the type of access they're actually
|
These will perform appropriately for the type of access they're actually
|
||||||
doing, be it inX()/outX() or readX()/writeX().
|
doing, be it inX()/outX() or readX()/writeX().
|
||||||
|
|
||||||
All of these accessors assume that the underlying peripheral is little-endian,
|
All of these accessors assume that the underlying peripheral is little-endian,
|
||||||
and will therefore perform byte-swapping operations on big-endian architectures.
|
and will therefore perform byte-swapping operations on big-endian architectures.
|
||||||
|
Loading…
Reference in New Issue
Block a user