Commit 1e8b5d85 authored by Michael S. Tsirkin's avatar Michael S. Tsirkin
Browse files

docs: dma-api: document __dma_from_device_group_begin()/end()



Document the __dma_from_device_group_begin()/end() annotations.

Message-ID: <01ea88055ded4d70cac70ba557680fd5fa7d9ff5.1767601130.git.mst@redhat.com>
Acked-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: default avatarPetr Tesarik <ptesarik@suse.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent ca085faa
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -146,6 +146,58 @@ What about block I/O and networking buffers? The block I/O and
networking subsystems make sure that the buffers they use are valid
for you to DMA from/to.

__dma_from_device_group_begin/end annotations
=============================================

As explained previously, when a structure contains a DMA_FROM_DEVICE /
DMA_BIDIRECTIONAL buffer (device writes to memory) alongside fields that the
CPU writes to, cache line sharing between the DMA buffer and CPU-written fields
can cause data corruption on CPUs with DMA-incoherent caches.

The ``__dma_from_device_group_begin(GROUP)/__dma_from_device_group_end(GROUP)``
macros ensure proper alignment to prevent this::

	struct my_device {
		spinlock_t lock1;
		__dma_from_device_group_begin();
		char dma_buffer1[16];
		char dma_buffer2[16];
		__dma_from_device_group_end();
		spinlock_t lock2;
	};

To isolate a DMA buffer from adjacent fields, use
``__dma_from_device_group_begin(GROUP)`` before the first DMA buffer
field and ``__dma_from_device_group_end(GROUP)`` after the last DMA
buffer field (with the same GROUP name). This protects both the head
and tail of the buffer from cache line sharing.

The GROUP parameter is an optional identifier that names the DMA buffer group
(in case you have several in the same structure)::

	struct my_device {
		spinlock_t lock1;
		__dma_from_device_group_begin(buffer1);
		char dma_buffer1[16];
		__dma_from_device_group_end(buffer1);
		spinlock_t lock2;
		__dma_from_device_group_begin(buffer2);
		char dma_buffer2[16];
		__dma_from_device_group_end(buffer2);
	};

On cache-coherent platforms these macros expand to zero-length array markers.
On non-coherent platforms, they also ensure the minimal DMA alignment, which
can be as large as 128 bytes.

.. note::

        It is allowed (though somewhat fragile) to include extra fields, not
        intended for DMA from the device, within the group (in order to pack the
        structure tightly) - but only as long as the CPU does not write these
        fields while any fields in the group are mapped for DMA_FROM_DEVICE or
        DMA_BIDIRECTIONAL.

DMA addressing capabilities
===========================