Skip to contentSkip to conversation

dmaengine: sirf: fix kernel panic under one race condition

PATCH New Barry Song 2 participants 3 messages Jul 14, 2015 – Jul 20, 2015 dmaengine

lore
Share & tools
lore

Barry Song

author
#0 lore raw

PATCH 1/1 dmaengine: sirf: fix kernel panic under one race condition

From: Yanchang Li <[email protected]>

If DMA interrupt comes and is latched by IRQ controller during the execution of dma_terminate_all(), dma_irq routine will be executed after dma terminated, and it will cause kernel panic.
We clear DMA interrupts in dma_terminate_all() to avoid this useless interrupt.

---
 drivers/dma/sirf-dma.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/dma/sirf-dma.c +3 -0
index 8c5186c..7d5598d 100644
@@ -455,6 +455,7 @@ static int sirfsoc_dma_terminate_all(struct dma_chan *chan)
 	switch (sdma->type) {
 	case SIRFSOC_DMA_VER_A7V1:
 		writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_INT_EN_CLR);
+		writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_CH_INT);
 		writel_relaxed((1 << cid) | 1 << (cid + 16),
 			       sdma->base +
 			       SIRFSOC_DMA_CH_LOOP_CTRL_CLR_ATLAS7);
@@ -462,6 +463,8 @@ static int sirfsoc_dma_terminate_all(struct dma_chan *chan)
 		break;
 	case SIRFSOC_DMA_VER_A7V2:
 		writel_relaxed(0, sdma->base + SIRFSOC_DMA_INT_EN_ATLAS7);
+		writel_relaxed(SIRFSOC_DMA_INT_ALL_ATLAS7,
+			       sdma->base + SIRFSOC_DMA_INT_ATLAS7);
 		writel_relaxed(0, sdma->base + SIRFSOC_DMA_LOOP_CTRL_ATLAS7);
 		writel_relaxed(0, sdma->base + SIRFSOC_DMA_VALID_ATLAS7);
 		break;
Signature · 1 line
2.3.5
#1 lore raw

PATCH 1/1 dmaengine: sirf: fix kernel panic under one race condition

Quoted 1 line · Barry Song

From: Yanchang Li <[email protected]>

patch title should alos say what is changed. "panic under one race" is not an apt description for this

Can you fix that up, otherwise it looks okay

Signature · 1 line
~Vinod
Quoted 37 lines

If DMA interrupt comes and is latched by IRQ controller during the execution of dma_terminate_all(), dma_irq routine will be executed after dma terminated, and it will cause kernel panic.
We clear DMA interrupts in dma_terminate_all() to avoid this useless interrupt.

---
 drivers/dma/sirf-dma.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/dma/sirf-dma.c +3 -0
index 8c5186c..7d5598d 100644
@@ -455,6 +455,7 @@ static int sirfsoc_dma_terminate_all(struct dma_chan *chan)
 	switch (sdma->type) {
 	case SIRFSOC_DMA_VER_A7V1:
 		writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_INT_EN_CLR);
+		writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_CH_INT);
 		writel_relaxed((1 << cid) | 1 << (cid + 16),
 			       sdma->base +
 			       SIRFSOC_DMA_CH_LOOP_CTRL_CLR_ATLAS7);
@@ -462,6 +463,8 @@ static int sirfsoc_dma_terminate_all(struct dma_chan *chan)
 		break;
 	case SIRFSOC_DMA_VER_A7V2:
 		writel_relaxed(0, sdma->base + SIRFSOC_DMA_INT_EN_ATLAS7);
+		writel_relaxed(SIRFSOC_DMA_INT_ALL_ATLAS7,
+			       sdma->base + SIRFSOC_DMA_INT_ATLAS7);
 		writel_relaxed(0, sdma->base + SIRFSOC_DMA_LOOP_CTRL_ATLAS7);
 		writel_relaxed(0, sdma->base + SIRFSOC_DMA_VALID_ATLAS7);
 		break;
Signature · 1 line
2.3.5
author
#2 lore raw

PATCH 1/1 dmaengine: sirf: fix kernel panic under one race condition

2015-07-16 21:17 GMT+08:00 Vinod Koul <[email protected]>:

Quoted 8 lines · Barry Song
Quoted 1 line

From: Yanchang Li <[email protected]>

patch title should alos say what is changed. "panic under one race" is not an apt description for this

Can you fix that up, otherwise it looks okay

yes. it seems it can be

dmaengine: sirf: clear any pending DMA interrupt when DMA terminates

Quoted 32 lines

--
~Vinod

Quoted 29 lines

If DMA interrupt comes and is latched by IRQ controller during the execution of dma_terminate_all(), dma_irq routine will be executed after dma terminated, and it will cause kernel panic.
We clear DMA interrupts in dma_terminate_all() to avoid this useless interrupt.

---
 drivers/dma/sirf-dma.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/dma/sirf-dma.c +1 -0
index 8c5186c..7d5598d 100644
@@ -455,6 +455,7 @@ static int sirfsoc_dma_terminate_all(struct dma_chan *chan)
      switch (sdma->type) {
      case SIRFSOC_DMA_VER_A7V1:
              writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_INT_EN_CLR);
+             writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_CH_INT);
              writel_relaxed((1 << cid) | 1 << (cid + 16),
                             sdma->base +
                             SIRFSOC_DMA_CH_LOOP_CTRL_CLR_ATLAS7);
@@ -462,6 +463,8 @@ static int sirfsoc_dma_terminate_all(struct dma_chan *chan)
              break;
      case SIRFSOC_DMA_VER_A7V2:
              writel_relaxed(0, sdma->base + SIRFSOC_DMA_INT_EN_ATLAS7);
Quoted 9 lines
Quoted 8 lines
drivers/dma/sirf-dma.c +2 -1
+             writel_relaxed(SIRFSOC_DMA_INT_ALL_ATLAS7,
+                            sdma->base + SIRFSOC_DMA_INT_ATLAS7);
              writel_relaxed(0, sdma->base + SIRFSOC_DMA_LOOP_CTRL_ATLAS7);
              writel_relaxed(0, sdma->base + SIRFSOC_DMA_VALID_ATLAS7);
              break;
--

2.3.5

-barry