[PATCH RFC 2/2 stable-6.1] dmaengine: at_hdmac: complete chain after next message is started

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Thomas Pfaff <tpfaff@xxxxxxx>

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@xxxxxxx>
---
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






[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux PCI]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux