From: James Hilliard <james.hilliard1@gmail.com>
To: Viresh Kumar <vireshk@kernel.org>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Vinod Koul <vkoul@kernel.org>, Frank Li <Frank.Li@kernel.org>,
Dan Williams <djbw@kernel.org>
Cc: "Serge Semin" <fancer.lancer@gmail.com>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Jiri Slaby" <jirislaby@kernel.org>,
"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
dmaengine@vger.kernel.org, linux-serial@vger.kernel.org,
linux-kernel@vger.kernel.org, Sashiko <sashiko-bot@kernel.org>,
"Lars-Peter Clausen" <lars@metafoo.de>,
"James Hilliard" <james.hilliard1@gmail.com>,
stable@vger.kernel.org
Subject: [PATCH v4 3/7] dmaengine: dw: complete cookies before releasing the channel lock
Date: Thu, 29 Oct 2026 16:29:37 -0600 [thread overview]
Message-ID: <20261029-submit-dw-dma-synchronize-v1-v4-3-fea447d9f285@gmail.com> (raw)
In-Reply-To: <20261029-submit-dw-dma-synchronize-v1-v4-0-fea447d9f285@gmail.com>
Completion detaches a descriptor from the active list under the channel
lock, but updates its cookie later when freeing it. Termination can take
the lock in between and complete newer descriptors. Completing the older
cookie afterwards moves completed_cookie backwards and makes an already
terminated transfer appear outstanding again.
Complete cookies while detaching descriptors in the completion, error
recovery and termination paths. Keep the active-before-queued ordering
when terminating so completed_cookie advances in submission order.
Descriptor freeing and client notification no longer update cookies.
Fixes: 3bfb1d20b547 ("dmaengine: Driver for the Synopsys DesignWare DMA controller")
Cc: stable@vger.kernel.org
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
drivers/dma/dw/core.c | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
index 51c5460b4670..1f7afcd01565 100644
--- a/drivers/dma/dw/core.c
+++ b/drivers/dma/dw/core.c
@@ -236,18 +236,17 @@ static void dwc_dostart_first_queued(struct dw_dma_chan *dwc)
/*----------------------------------------------------------------------*/
static void
-dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,
- bool callback_required)
+dwc_descriptor_free(struct dw_dma_chan *dwc, struct dw_desc *desc,
+ bool callback_required)
{
struct dma_async_tx_descriptor *txd = &desc->txd;
struct dw_desc *child;
unsigned long flags;
struct dmaengine_desc_callback cb;
- dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie);
+ dev_vdbg(chan2dev(&dwc->chan), "freeing descriptor %p\n", desc);
spin_lock_irqsave(&dwc->lock, flags);
- dma_cookie_complete(txd);
if (callback_required)
dmaengine_desc_get_callback(txd, &cb);
else
@@ -334,12 +333,14 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
/* Detach the completed transfer before starting queued work. */
list_splice_init(&dwc->active_list, &list);
+ list_for_each_entry(desc, &list, desc_node)
+ dma_cookie_complete(&desc->txd);
dwc_dostart_first_queued(dwc);
spin_unlock_irqrestore(&dwc->lock, flags);
list_for_each_entry_safe(desc, _desc, &list, desc_node) {
list_del_init(&desc->desc_node);
- dwc_descriptor_complete(dwc, desc, true);
+ dwc_descriptor_free(dwc, desc, true);
}
return;
}
@@ -441,10 +442,11 @@ static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc)
list_for_each_entry(child, &bad_desc->tx_list, desc_node)
dwc_dump_lli(dwc, child);
+ /* Pretend the descriptor completed successfully */
+ dma_cookie_complete(&bad_desc->txd);
spin_unlock_irqrestore(&dwc->lock, flags);
- /* Pretend the descriptor completed successfully */
- dwc_descriptor_complete(dwc, bad_desc, true);
+ dwc_descriptor_free(dwc, bad_desc, true);
return;
unlock:
@@ -945,12 +947,16 @@ static int dwc_terminate_all(struct dma_chan *chan)
/* active_list entries will end up before queued entries */
list_splice_init(&dwc->queue, &list);
list_splice_init(&dwc->active_list, &list);
+ list_for_each_entry(desc, &list, desc_node)
+ dma_cookie_complete(&desc->txd);
spin_unlock_irqrestore(&dwc->lock, flags);
/* Flush all pending and queued descriptors */
- list_for_each_entry_safe(desc, _desc, &list, desc_node)
- dwc_descriptor_complete(dwc, desc, false);
+ list_for_each_entry_safe(desc, _desc, &list, desc_node) {
+ list_del_init(&desc->desc_node);
+ dwc_descriptor_free(dwc, desc, false);
+ }
return 0;
}
--
2.53.0
next prev parent reply other threads:[~2026-10-29 22:29 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-29 22:29 [PATCH v4 0/7] dmaengine: dw: serialize completion and termination James Hilliard
2026-10-29 22:29 ` [PATCH v4 1/7] dmaengine: dw: Fix XFER bit set, but channel not idle error James Hilliard
2026-10-29 22:29 ` [PATCH v4 2/7] dmaengine: dw: serialize error recovery with channel termination James Hilliard
2026-10-29 22:29 ` James Hilliard [this message]
2026-10-29 22:29 ` [PATCH v4 4/7] dmaengine: dw: calculate residue separately from completion James Hilliard
2026-10-29 22:29 ` [PATCH v4 5/7] dmaengine: dw: drain the tasklet before releasing channel resources James Hilliard
2026-10-29 22:29 ` [PATCH v4 6/7] dmaengine: dw: synchronize completion callbacks James Hilliard
2026-10-29 22:29 ` [PATCH v4 7/7] dmaengine: dw: Prevent tx-status calling DMA-desc callback James Hilliard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261029-submit-dw-dma-synchronize-v1-v4-3-fea447d9f285@gmail.com \
--to=james.hilliard1@gmail.com \
--cc=Frank.Li@kernel.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=djbw@kernel.org \
--cc=dmaengine@vger.kernel.org \
--cc=fancer.lancer@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=jirislaby@kernel.org \
--cc=lars@metafoo.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=sashiko-bot@kernel.org \
--cc=stable@vger.kernel.org \
--cc=vireshk@kernel.org \
--cc=vkoul@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®