[<prev] [next>] [day] [month] [year] [list]
Message-ID: <4412b25a-d4e1-f455-f7bd-82262e691a2b@pcs.com>
Date: Tue, 14 Nov 2023 13:23:03 +0100
From: Thomas Pfaff <tpfaff@....com>
To: <ludovic.desroches@...rochip.com>, <tudor.ambarus@...rochip.com>
CC: <nicolas.ferre@...rochip.com>, <vkoul@...nel.org>,
<linux-arm-kernel@...ts.infradead.org>,
<dmaengine@...r.kernel.org>, <linux-kernel@...r.kernel.org>
Subject: [PATCH RFC 2/2 stable-6.1] dmaengine: at_hdmac: complete chain after
next message is started
From: Thomas Pfaff <tpfaff@....com>
calling atc_chain_complete with unlocked spinlock in the middle of
atc_advance_work might cause a race condition regarding the next dma
transfer.
If the dma_callback is handled by a task with higher priority and
starts a new dma transfer it might call atc_issue_pending before the
spinlock is locked again.
In this case, the active list contains already a new entry that is started,
and atc_advance_work tries to start it again, which will fail because the
channel is already enabled.
Signed-off-by: Thomas Pfaff <tpfaff@....com>
---
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 68c1bfbefc5c..9b2a1cf23763 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -529,15 +529,12 @@ static void atc_advance_work(struct at_dma_chan *atchan)
desc = atc_first_active(atchan);
/* Remove the transfer node from the active list. */
list_del_init(&desc->desc_node);
- spin_unlock_irqrestore(&atchan->lock, flags);
- atc_chain_complete(atchan, desc);
-
/* advance work */
- spin_lock_irqsave(&atchan->lock, flags);
atc_start_next(atchan);
spin_unlock_irqrestore(&atchan->lock, flags);
-}
+ atc_chain_complete(atchan, desc);
+}
/**
* atc_handle_error - handle errors reported by DMA controller
Powered by blists - more mailing lists