DMA Engine development
 help / color / mirror / Atom feed
* [PATCH] dmaengine: switchtec-dma: preserve results for out-of-order completions
@ 2026-07-18 14:32 Hao-Qun Huang
  2026-07-18 14:48 ` sashiko-bot
  0 siblings, 1 reply; 2+ messages in thread
From: Hao-Qun Huang @ 2026-07-18 14:32 UTC (permalink / raw)
  To: Kelvin Cao, Logan Gunthorpe
  Cc: Vinod Koul, Frank Li, George Ge, dmaengine, linux-kernel

Switchtec completion entries can arrive out of submission order, and the
driver handles that by marking the descriptor complete and deferring its
callback until the ring tail catches up.  The problem is that the
per-transfer result (status and residue) is only kept in a stack variable
while the completion entry is being read.  Once the tail gap closes,
cleanup retires the descriptor at the tail along with any already
completed descriptors behind it, and hands the same stack result to every
one of them.

So a transfer that failed out of order can be reported as successful (or
the other way round) depending on which completion happened to close the
gap, and the residue can end up coming from the wrong transfer too.

Keep the result in each descriptor instead of on the stack, and pass the
descriptor's own saved result when it is retired.  Cookie ordering, the
CID-to-descriptor mapping and the completion locking are unchanged; only
the result handed to each callback is corrected.

Fixes: 30eba9df76ad ("dmaengine: switchtec-dma: Implement hardware initialization and cleanup")
Assisted-by: Claude:claude-fable-5
Signed-off-by: Hao-Qun Huang <alvinhuang0603@gmail.com>
---
 drivers/dma/switchtec_dma.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/dma/switchtec_dma.c b/drivers/dma/switchtec_dma.c
index 3ef928640615..681540836e73 100644
--- a/drivers/dma/switchtec_dma.c
+++ b/drivers/dma/switchtec_dma.c
@@ -246,6 +246,7 @@ struct switchtec_dma_hw_ce {
 struct switchtec_dma_desc {
 	struct dma_async_tx_descriptor txd;
 	struct switchtec_dma_hw_se_desc *hw;
+	struct dmaengine_result result;
 	u32 orig_size;
 	bool completed;
 };
@@ -409,7 +410,6 @@ switchtec_dma_cleanup_completed(struct switchtec_dma_chan *swdma_chan)
 	struct device *chan_dev = &swdma_chan->dma_chan.dev->device;
 	struct switchtec_dma_desc *desc;
 	struct switchtec_dma_hw_ce *ce;
-	struct dmaengine_result res;
 	int tail, cid, se_idx, i;
 	__le16 phase_tag;
 	u32 sts_code;
@@ -439,17 +439,17 @@ switchtec_dma_cleanup_completed(struct switchtec_dma_chan *swdma_chan)
 
 		tail = swdma_chan->tail;
 
-		res.residue = desc->orig_size - le32_to_cpu(ce->cpl_byte_cnt);
+		desc->result.residue = desc->orig_size - le32_to_cpu(ce->cpl_byte_cnt);
 
 		sts_code = le32_to_cpu(ce->sts_code);
 
 		if (!(sts_code & SWITCHTEC_CE_SC_MASK)) {
-			res.result = DMA_TRANS_NOERROR;
+			desc->result.result = DMA_TRANS_NOERROR;
 		} else {
 			if (sts_code & SWITCHTEC_CE_SC_D_RD_CTO)
-				res.result = DMA_TRANS_READ_FAILED;
+				desc->result.result = DMA_TRANS_READ_FAILED;
 			else
-				res.result = DMA_TRANS_WRITE_FAILED;
+				desc->result.result = DMA_TRANS_WRITE_FAILED;
 
 			dev_err(chan_dev, "CID 0x%04x failed, SC 0x%08x\n", cid,
 				(u32)(sts_code & SWITCHTEC_CE_SC_MASK));
@@ -488,7 +488,7 @@ switchtec_dma_cleanup_completed(struct switchtec_dma_chan *swdma_chan)
 		do {
 			dma_cookie_complete(&desc->txd);
 			dma_descriptor_unmap(&desc->txd);
-			dmaengine_desc_get_callback_invoke(&desc->txd, &res);
+			dmaengine_desc_get_callback_invoke(&desc->txd, &desc->result);
 			desc->txd.callback = NULL;
 			desc->txd.callback_result = NULL;
 			desc->completed = false;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-07-18 14:48 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-18 14:32 [PATCH] dmaengine: switchtec-dma: preserve results for out-of-order completions Hao-Qun Huang
2026-07-18 14:48 ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox