tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
bus_dma without bouncing
NIC drivers allocate rx buffers for the device to read network data
into through DMA. In some devices the device's DMA has constraints,
specified through the DMA tag and/or bus_dmamap_create parameters, and
enforced in bus_dmamap_load by bouncing.
To avoid bouncing, or to satisfy alignment requirements imposed by the
device[1], drivers will often allocate rx buffers themselves with
bus_dmamem_alloc/map.
But, given constraints, bus_dmamap_create will _also_ allocate bounce
buffers with bus_dmamem_alloc/map -- even if the driver will never
bounce because it already allocated rx buffers satisfying the
constraint. This wastes physical pages and kva that will never be
used -- except if there's a driver bug causing every rx buffer to be
bounced unintentionally, which quietly gives bad performance!
Should we have a way to avoid this?
Here are a couple options that come to mind (with 30sec of thought put
into each name, and alternate bike shed paint suggestions welcome):
1. An option BUS_DMA_BOUNCELESS to bus_dmamap_create that causes
bus_dmamap_load to fail instead of bouncing if constraints are not
met.
=> This simple API change generally obviates the need to allocate
bounce buffers in the scenario above. However, some
architectural constraints such as confidential computing
architecture (AMD SEV, Intel TDX) may still require bouncing for
other reasons (must selectively expose page unencrypted to the
hypervisor).
2. (a) An option BUS_DMA_ALLOCBUF to bus_dmamap_create that _forces_
it to allocate a bounce buffer with bus_dmamem_alloc/map
meeting the constraints.
(b) Another operation, such as bus_dmamap_bufmem, to get at the
bounce buffer so a driver can work directly with it instead of
calling bus_dmamem_alloc/map itself.
=> This would allow us to avoid the duplicate bounce buffer in the
confidential computing case. But it's a more complicated change
to the API, and some bus_dma implementations -- such as sparc
and sparc64 -- appear not to bounce at all, ever, so they would
have to be adapted to add logic for allocating bounce bufers.
[1] It seems there is no MI way with bus_dma tags or bus_dmamap_create
to make bus_dmamap_load enforce alignment by bouncing into an
aligned bounce buffer if the given address is misaligned. But
there are plenty of devices that require aligned addresses for
DMA, such as Intel wireless cards which require 8- or 12-bit
alignment. Am I missing something? Is there just no way to
express this constraint in bus_dmamap_create so that
bus_dmamap_load will _either_ fail noisily or bounce on misaligned
inputs?
Home |
Main Index |
Thread Index |
Old Index