docs: dma-api: replace consistent with coherent
For consistency, always use the term "coherent" when talking about memory that is not subject to CPU caching effects. The term "consistent" is a relic of a long-removed PCI DMA API (pci_alloc_consistent() and pci_free_consistent() functions). Signed-off-by: Petr Tesarik <ptesarik@suse.com> Tested-by: Randy Dunlap <rdunlap@infradead.org> Acked-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Jonathan Corbet <corbet@lwn.net> Link: https://lore.kernel.org/r/20250627101015.1600042-3-ptesarik@suse.compull/1310/head
parent
7362b6ba17
commit
4d3c6bc11b
|
|
@ -155,7 +155,7 @@ a device with limitations, it needs to be decreased.
|
||||||
|
|
||||||
Special note about PCI: PCI-X specification requires PCI-X devices to support
|
Special note about PCI: PCI-X specification requires PCI-X devices to support
|
||||||
64-bit addressing (DAC) for all transactions. And at least one platform (SGI
|
64-bit addressing (DAC) for all transactions. And at least one platform (SGI
|
||||||
SN2) requires 64-bit consistent allocations to operate correctly when the IO
|
SN2) requires 64-bit coherent allocations to operate correctly when the IO
|
||||||
bus is in PCI-X mode.
|
bus is in PCI-X mode.
|
||||||
|
|
||||||
For correct operation, you must set the DMA mask to inform the kernel about
|
For correct operation, you must set the DMA mask to inform the kernel about
|
||||||
|
|
@ -174,7 +174,7 @@ used instead:
|
||||||
|
|
||||||
int dma_set_mask(struct device *dev, u64 mask);
|
int dma_set_mask(struct device *dev, u64 mask);
|
||||||
|
|
||||||
The setup for consistent allocations is performed via a call
|
The setup for coherent allocations is performed via a call
|
||||||
to dma_set_coherent_mask()::
|
to dma_set_coherent_mask()::
|
||||||
|
|
||||||
int dma_set_coherent_mask(struct device *dev, u64 mask);
|
int dma_set_coherent_mask(struct device *dev, u64 mask);
|
||||||
|
|
@ -241,7 +241,7 @@ it would look like this::
|
||||||
|
|
||||||
The coherent mask will always be able to set the same or a smaller mask as
|
The coherent mask will always be able to set the same or a smaller mask as
|
||||||
the streaming mask. However for the rare case that a device driver only
|
the streaming mask. However for the rare case that a device driver only
|
||||||
uses consistent allocations, one would have to check the return value from
|
uses coherent allocations, one would have to check the return value from
|
||||||
dma_set_coherent_mask().
|
dma_set_coherent_mask().
|
||||||
|
|
||||||
Finally, if your device can only drive the low 24-bits of
|
Finally, if your device can only drive the low 24-bits of
|
||||||
|
|
@ -298,20 +298,20 @@ Types of DMA mappings
|
||||||
|
|
||||||
There are two types of DMA mappings:
|
There are two types of DMA mappings:
|
||||||
|
|
||||||
- Consistent DMA mappings which are usually mapped at driver
|
- Coherent DMA mappings which are usually mapped at driver
|
||||||
initialization, unmapped at the end and for which the hardware should
|
initialization, unmapped at the end and for which the hardware should
|
||||||
guarantee that the device and the CPU can access the data
|
guarantee that the device and the CPU can access the data
|
||||||
in parallel and will see updates made by each other without any
|
in parallel and will see updates made by each other without any
|
||||||
explicit software flushing.
|
explicit software flushing.
|
||||||
|
|
||||||
Think of "consistent" as "synchronous" or "coherent".
|
Think of "coherent" as "synchronous".
|
||||||
|
|
||||||
The current default is to return consistent memory in the low 32
|
The current default is to return coherent memory in the low 32
|
||||||
bits of the DMA space. However, for future compatibility you should
|
bits of the DMA space. However, for future compatibility you should
|
||||||
set the consistent mask even if this default is fine for your
|
set the coherent mask even if this default is fine for your
|
||||||
driver.
|
driver.
|
||||||
|
|
||||||
Good examples of what to use consistent mappings for are:
|
Good examples of what to use coherent mappings for are:
|
||||||
|
|
||||||
- Network card DMA ring descriptors.
|
- Network card DMA ring descriptors.
|
||||||
- SCSI adapter mailbox command data structures.
|
- SCSI adapter mailbox command data structures.
|
||||||
|
|
@ -320,13 +320,13 @@ There are two types of DMA mappings:
|
||||||
|
|
||||||
The invariant these examples all require is that any CPU store
|
The invariant these examples all require is that any CPU store
|
||||||
to memory is immediately visible to the device, and vice
|
to memory is immediately visible to the device, and vice
|
||||||
versa. Consistent mappings guarantee this.
|
versa. Coherent mappings guarantee this.
|
||||||
|
|
||||||
.. important::
|
.. important::
|
||||||
|
|
||||||
Consistent DMA memory does not preclude the usage of
|
Coherent DMA memory does not preclude the usage of
|
||||||
proper memory barriers. The CPU may reorder stores to
|
proper memory barriers. The CPU may reorder stores to
|
||||||
consistent memory just as it may normal memory. Example:
|
coherent memory just as it may normal memory. Example:
|
||||||
if it is important for the device to see the first word
|
if it is important for the device to see the first word
|
||||||
of a descriptor updated before the second, you must do
|
of a descriptor updated before the second, you must do
|
||||||
something like::
|
something like::
|
||||||
|
|
@ -365,10 +365,10 @@ Also, systems with caches that aren't DMA-coherent will work better
|
||||||
when the underlying buffers don't share cache lines with other data.
|
when the underlying buffers don't share cache lines with other data.
|
||||||
|
|
||||||
|
|
||||||
Using Consistent DMA mappings
|
Using Coherent DMA mappings
|
||||||
=============================
|
===========================
|
||||||
|
|
||||||
To allocate and map large (PAGE_SIZE or so) consistent DMA regions,
|
To allocate and map large (PAGE_SIZE or so) coherent DMA regions,
|
||||||
you should do::
|
you should do::
|
||||||
|
|
||||||
dma_addr_t dma_handle;
|
dma_addr_t dma_handle;
|
||||||
|
|
@ -385,10 +385,10 @@ __get_free_pages() (but takes size instead of a page order). If your
|
||||||
driver needs regions sized smaller than a page, you may prefer using
|
driver needs regions sized smaller than a page, you may prefer using
|
||||||
the dma_pool interface, described below.
|
the dma_pool interface, described below.
|
||||||
|
|
||||||
The consistent DMA mapping interfaces, will by default return a DMA address
|
The coherent DMA mapping interfaces, will by default return a DMA address
|
||||||
which is 32-bit addressable. Even if the device indicates (via the DMA mask)
|
which is 32-bit addressable. Even if the device indicates (via the DMA mask)
|
||||||
that it may address the upper 32-bits, consistent allocation will only
|
that it may address the upper 32-bits, coherent allocation will only
|
||||||
return > 32-bit addresses for DMA if the consistent DMA mask has been
|
return > 32-bit addresses for DMA if the coherent DMA mask has been
|
||||||
explicitly changed via dma_set_coherent_mask(). This is true of the
|
explicitly changed via dma_set_coherent_mask(). This is true of the
|
||||||
dma_pool interface as well.
|
dma_pool interface as well.
|
||||||
|
|
||||||
|
|
@ -497,7 +497,7 @@ program address space. Such platforms can and do report errors in the
|
||||||
kernel logs when the DMA controller hardware detects violation of the
|
kernel logs when the DMA controller hardware detects violation of the
|
||||||
permission setting.
|
permission setting.
|
||||||
|
|
||||||
Only streaming mappings specify a direction, consistent mappings
|
Only streaming mappings specify a direction, coherent mappings
|
||||||
implicitly have a direction attribute setting of
|
implicitly have a direction attribute setting of
|
||||||
DMA_BIDIRECTIONAL.
|
DMA_BIDIRECTIONAL.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ This document describes the DMA API. For a more gentle introduction
|
||||||
of the API (and actual examples), see Documentation/core-api/dma-api-howto.rst.
|
of the API (and actual examples), see Documentation/core-api/dma-api-howto.rst.
|
||||||
|
|
||||||
This API is split into two pieces. Part I describes the basic API.
|
This API is split into two pieces. Part I describes the basic API.
|
||||||
Part II describes extensions for supporting non-consistent memory
|
Part II describes extensions for supporting non-coherent memory
|
||||||
machines. Unless you know that your driver absolutely has to support
|
machines. Unless you know that your driver absolutely has to support
|
||||||
non-consistent platforms (this is usually only legacy platforms) you
|
non-coherent platforms (this is usually only legacy platforms) you
|
||||||
should only use the API described in part I.
|
should only use the API described in part I.
|
||||||
|
|
||||||
Part I - DMA API
|
Part I - DMA API
|
||||||
|
|
@ -33,13 +33,13 @@ Part Ia - Using large DMA-coherent buffers
|
||||||
dma_alloc_coherent(struct device *dev, size_t size,
|
dma_alloc_coherent(struct device *dev, size_t size,
|
||||||
dma_addr_t *dma_handle, gfp_t flag)
|
dma_addr_t *dma_handle, gfp_t flag)
|
||||||
|
|
||||||
Consistent memory is memory for which a write by either the device or
|
Coherent memory is memory for which a write by either the device or
|
||||||
the processor can immediately be read by the processor or device
|
the processor can immediately be read by the processor or device
|
||||||
without having to worry about caching effects. (You may however need
|
without having to worry about caching effects. (You may however need
|
||||||
to make sure to flush the processor's write buffers before telling
|
to make sure to flush the processor's write buffers before telling
|
||||||
devices to read that memory.)
|
devices to read that memory.)
|
||||||
|
|
||||||
This routine allocates a region of <size> bytes of consistent memory.
|
This routine allocates a region of <size> bytes of coherent memory.
|
||||||
|
|
||||||
It returns a pointer to the allocated region (in the processor's virtual
|
It returns a pointer to the allocated region (in the processor's virtual
|
||||||
address space) or NULL if the allocation failed.
|
address space) or NULL if the allocation failed.
|
||||||
|
|
@ -48,9 +48,9 @@ It also returns a <dma_handle> which may be cast to an unsigned integer the
|
||||||
same width as the bus and given to the device as the DMA address base of
|
same width as the bus and given to the device as the DMA address base of
|
||||||
the region.
|
the region.
|
||||||
|
|
||||||
Note: consistent memory can be expensive on some platforms, and the
|
Note: coherent memory can be expensive on some platforms, and the
|
||||||
minimum allocation length may be as big as a page, so you should
|
minimum allocation length may be as big as a page, so you should
|
||||||
consolidate your requests for consistent memory as much as possible.
|
consolidate your requests for coherent memory as much as possible.
|
||||||
The simplest way to do that is to use the dma_pool calls (see below).
|
The simplest way to do that is to use the dma_pool calls (see below).
|
||||||
|
|
||||||
The flag parameter (dma_alloc_coherent() only) allows the caller to
|
The flag parameter (dma_alloc_coherent() only) allows the caller to
|
||||||
|
|
@ -64,7 +64,7 @@ the returned memory, like GFP_DMA).
|
||||||
dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
|
dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
|
||||||
dma_addr_t dma_handle)
|
dma_addr_t dma_handle)
|
||||||
|
|
||||||
Free a region of consistent memory you previously allocated. dev,
|
Free a region of coherent memory you previously allocated. dev,
|
||||||
size and dma_handle must all be the same as those passed into
|
size and dma_handle must all be the same as those passed into
|
||||||
dma_alloc_coherent(). cpu_addr must be the virtual address returned by
|
dma_alloc_coherent(). cpu_addr must be the virtual address returned by
|
||||||
the dma_alloc_coherent().
|
the dma_alloc_coherent().
|
||||||
|
|
|
||||||
|
|
@ -200,7 +200,7 @@ static void pool_block_push(struct dma_pool *pool, struct dma_block *block,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dma_pool_create_node - Creates a pool of consistent memory blocks, for dma.
|
* dma_pool_create_node - Creates a pool of coherent DMA memory blocks.
|
||||||
* @name: name of pool, for diagnostics
|
* @name: name of pool, for diagnostics
|
||||||
* @dev: device that will be doing the DMA
|
* @dev: device that will be doing the DMA
|
||||||
* @size: size of the blocks in this pool.
|
* @size: size of the blocks in this pool.
|
||||||
|
|
@ -210,7 +210,7 @@ static void pool_block_push(struct dma_pool *pool, struct dma_block *block,
|
||||||
* Context: not in_interrupt()
|
* Context: not in_interrupt()
|
||||||
*
|
*
|
||||||
* Given one of these pools, dma_pool_alloc()
|
* Given one of these pools, dma_pool_alloc()
|
||||||
* may be used to allocate memory. Such memory will all have "consistent"
|
* may be used to allocate memory. Such memory will all have coherent
|
||||||
* DMA mappings, accessible by the device and its driver without using
|
* DMA mappings, accessible by the device and its driver without using
|
||||||
* cache flushing primitives. The actual size of blocks allocated may be
|
* cache flushing primitives. The actual size of blocks allocated may be
|
||||||
* larger than requested because of alignment.
|
* larger than requested because of alignment.
|
||||||
|
|
@ -395,7 +395,7 @@ void dma_pool_destroy(struct dma_pool *pool)
|
||||||
EXPORT_SYMBOL(dma_pool_destroy);
|
EXPORT_SYMBOL(dma_pool_destroy);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dma_pool_alloc - get a block of consistent memory
|
* dma_pool_alloc - get a block of coherent memory
|
||||||
* @pool: dma pool that will produce the block
|
* @pool: dma pool that will produce the block
|
||||||
* @mem_flags: GFP_* bitmask
|
* @mem_flags: GFP_* bitmask
|
||||||
* @handle: pointer to dma address of block
|
* @handle: pointer to dma address of block
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue