Re: [PATCH 1/3] dmaengine: Add multi-buffer support in single DMA transfer
Robin Murphy <[email protected]> Fri, 13 Mar 2026 15:16:50 +0000
| Newsgroups | dev.linux.lists.mhi,dev.linux.lists.iommu,org.kernel.vger.dmaengine,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci |
|---|---|
| Message-ID | <[email protected]> |
On 2026-03-13 6:49 am, Sumit Kumar wrote:
> Add dmaengine_prep_batch_sg API for batching multiple independent buffers
> in a single DMA transaction. Each scatter-gather entry specifies both
> source and destination addresses. This allows multiple non-contiguous
> memory regions to be transferred in a single DMA transaction instead of
> separate operations, significantly reducing submission overhead and
> interrupt overhead.
>
> Extends struct scatterlist with optional dma_dst_address field
> and implements support in dw-edma driver.
[...]
> diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
> index 29f6ceb98d74b118d08b6a3d4eb7f62dcde0495d..20b65ffcd5e2a65ec5026a29344caf6baa09700b 100644
> --- a/include/linux/scatterlist.h
> +++ b/include/linux/scatterlist.h
> @@ -19,6 +19,9 @@ struct scatterlist {
> #ifdef CONFIG_NEED_SG_DMA_FLAGS
> unsigned int dma_flags;
> #endif
> +#ifdef CONFIG_NEED_SG_DMA_DST_ADDR
> + dma_addr_t dma_dst_address;
> +#endif
Eww, no, what does this even mean? Is the regular dma_addr somehow
implicitly a "source" now? How could the single piece of memory
represented by page_link/offset/length have two different DMA addresses?
How are both the DMA mapping code and users supposed to know which one
is relevant in any particular situation?
If you want to bring back DMA_MEMCPY_SG yet again, and you have an
actual user this time, then do that (although by now it most likely
wants to be a dma_vec version). Don't do whatever this is...
If you want to batch multiple
dmaengine_slave_config()/dma_prep_slave_single() operations into some
many-to-many variant of dmaengine_prep_peripheral_dma_vec(), then surely
that requires actual batching of the config part as well - e.g. passing
an explicit vector of distinct dma_slave_configs corresponding to each
individual dma_vec - in order to be able to work correctly in general?
Thanks,
Robin.
> };
>
> /*
> @@ -36,6 +39,10 @@ struct scatterlist {
> #define sg_dma_len(sg) ((sg)->length)
> #endif
>
> +#ifdef CONFIG_NEED_SG_DMA_DST_ADDR
> +#define sg_dma_dst_address(sg) ((sg)->dma_dst_address)
> +#endif
> +
> struct sg_table {
> struct scatterlist *sgl; /* the list */
> unsigned int nents; /* number of mapped entries */
> diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig
> index 31cfdb6b4bc3e33c239111955d97b3ec160baafa..3539b5b1efe27be7ccbfebb358dbb9cad2868f11 100644
> --- a/kernel/dma/Kconfig
> +++ b/kernel/dma/Kconfig
> @@ -32,6 +32,9 @@ config NEED_SG_DMA_LENGTH
> config NEED_DMA_MAP_STATE
> bool
>
> +config NEED_SG_DMA_DST_ADDR
> + bool
> +
> config ARCH_DMA_ADDR_T_64BIT
> def_bool 64BIT || PHYS_ADDR_T_64BIT
>
>