Re: [PATCH 03/17] dmaengine: idxd: refuse a memcpy longer than the WQ max transfer size
From: Frank Li
Date: Mon Oct 19 2026 - 17:26:17 EST
On Mon, Oct 19, 2026 at 08:06:16AM -0700, Daniel Byrne wrote:
> [You don't often get email from daniel1.byrne@xxxxxxxxx. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> idxd_dma_submit_memcpy() checks the length only against the device
> limit from GENCAP. Since commit d7aad5550eca ("dmaengine: idxd: add
> support for configurable max wq xfer size"), WQCFG is programmed with
> the work queue's own max_transfer_size instead, and that is the limit
> the hardware enforces. Since commit 92452a72ebdf ("dmaengine: idxd: set
> defaults for wq configs"), that limit defaults to 2 MiB.
>
> A copy longer than the work queue's limit is therefore accepted at prep
> time and then fails in hardware with DSA_COMP_XFER_ERANGE. A client that
> sets only tx->callback cannot see that error, so the copy looks
> complete. Also check the work queue's limit, so that prep returns NULL
> and the caller can fall back.
>
> On a Granite Rapids DSA with the default 2 MiB work queue limit and a
> device limit of 2 GiB, dmatest with norandom=1 and test_buf_size=4194304
> reports a data error for every copy on v7.2: the destination is never
> written, yet each copy completes. With this change the same test fails
> at prep, and copies of 1 MiB and 2 MiB pass as before.
>
> Fixes: d7aad5550eca ("dmaengine: idxd: add support for configurable max wq xfer size")
> Cc: stable@xxxxxxxxxxxxxxx # 5.10+
> Assisted-by: Claude:claude-opus-5-5
> Signed-off-by: Daniel Byrne <daniel1.byrne@xxxxxxxxx>
> ---
Reviewed-by: Frank Li <Frank.Li@xxxxxxx>
> drivers/dma/idxd/dma.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma/idxd/dma.c b/drivers/dma/idxd/dma.c
> index 9937b671f637..c116416e10e5 100644
> --- a/drivers/dma/idxd/dma.c
> +++ b/drivers/dma/idxd/dma.c
> @@ -115,7 +115,8 @@ idxd_dma_submit_memcpy(struct dma_chan *c, dma_addr_t dma_dest,
> if (wq->state != IDXD_WQ_ENABLED)
> return NULL;
>
> - if (len > idxd->max_xfer_bytes)
> + /* The work queue's configured limit is what the hardware enforces. */
> + if (len > idxd->max_xfer_bytes || len > wq->max_xfer_bytes)
> return NULL;
>
> op_flag_setup(flags, &desc_flags);
> --
> 2.43.0
>