Skip to content

Commit 95e5fda

Browse files
epilmorevinodkoul
authored andcommitted
ptdma: pt_core_execute_cmd() should use spinlock
The interrupt handler (pt_core_irq_handler()) of the ptdma driver can be called from interrupt context. The code flow in this function can lead down to pt_core_execute_cmd() which will attempt to grab a mutex, which is not appropriate in interrupt context and ultimately leads to a kernel panic. The fix here changes this mutex to a spinlock, which has been verified to resolve the issue. Fixes: fa5d823 ("dmaengine: ptdma: Initial driver for the AMD PTDMA") Signed-off-by: Eric Pilmore <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent a7a7ee6 commit 95e5fda

File tree

2 files changed

+5
-4
lines changed

2 files changed

+5
-4
lines changed

drivers/dma/ptdma/ptdma-dev.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,13 @@ static int pt_core_execute_cmd(struct ptdma_desc *desc, struct pt_cmd_queue *cmd
7171
bool soc = FIELD_GET(DWORD0_SOC, desc->dw0);
7272
u8 *q_desc = (u8 *)&cmd_q->qbase[cmd_q->qidx];
7373
u32 tail;
74+
unsigned long flags;
7475

7576
if (soc) {
7677
desc->dw0 |= FIELD_PREP(DWORD0_IOC, desc->dw0);
7778
desc->dw0 &= ~DWORD0_SOC;
7879
}
79-
mutex_lock(&cmd_q->q_mutex);
80+
spin_lock_irqsave(&cmd_q->q_lock, flags);
8081

8182
/* Copy 32-byte command descriptor to hw queue. */
8283
memcpy(q_desc, desc, 32);
@@ -91,7 +92,7 @@ static int pt_core_execute_cmd(struct ptdma_desc *desc, struct pt_cmd_queue *cmd
9192

9293
/* Turn the queue back on using our cached control register */
9394
pt_start_queue(cmd_q);
94-
mutex_unlock(&cmd_q->q_mutex);
95+
spin_unlock_irqrestore(&cmd_q->q_lock, flags);
9596

9697
return 0;
9798
}
@@ -199,7 +200,7 @@ int pt_core_init(struct pt_device *pt)
199200

200201
cmd_q->pt = pt;
201202
cmd_q->dma_pool = dma_pool;
202-
mutex_init(&cmd_q->q_mutex);
203+
spin_lock_init(&cmd_q->q_lock);
203204

204205
/* Page alignment satisfies our needs for N <= 128 */
205206
cmd_q->qsize = Q_SIZE(Q_DESC_SIZE);

drivers/dma/ptdma/ptdma.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ struct pt_cmd_queue {
196196
struct ptdma_desc *qbase;
197197

198198
/* Aligned queue start address (per requirement) */
199-
struct mutex q_mutex ____cacheline_aligned;
199+
spinlock_t q_lock ____cacheline_aligned;
200200
unsigned int qidx;
201201

202202
unsigned int qsize;

0 commit comments

Comments
 (0)