mirror of
https://github.com/armbian/build.git
synced 2025-08-18 21:11:02 +02:00
71 lines
2.1 KiB
Diff
71 lines
2.1 KiB
Diff
From 4acf270a6310f5e2dbadac1d5f21d8e7477fade6 Mon Sep 17 00:00:00 2001
|
|
From: Paolo Sabatino <paolo.sabatino@gmail.com>
|
|
Date: Sun, 16 Feb 2025 11:15:55 +0100
|
|
Subject: [PATCH] pl330: fix buffer underrun with cyclic dma
|
|
|
|
userspace applications (notably, pulseaudio) were
|
|
suffering frequent buffer underruns when cyclic DMA
|
|
was handled by controller itself. This patch fixes
|
|
the buffer underruns avoiding to juggle with the
|
|
descriptor state, keeping it in BUSY state as long
|
|
as it is actual transfer is progressing.
|
|
---
|
|
drivers/dma/pl330.c | 24 ++++++++++++------------
|
|
1 file changed, 12 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
|
|
index 208e2a089a4d..6dac00995765 100644
|
|
--- a/drivers/dma/pl330.c
|
|
+++ b/drivers/dma/pl330.c
|
|
@@ -1737,11 +1737,11 @@ static void dma_pl330_rqcb(struct dma_pl330_desc *desc, enum pl330_op_err err)
|
|
if (!pch)
|
|
return;
|
|
|
|
- spin_lock_irqsave(&pch->lock, flags);
|
|
-
|
|
- desc->status = DONE;
|
|
-
|
|
- spin_unlock_irqrestore(&pch->lock, flags);
|
|
+ if (!desc->cyclic) {
|
|
+ spin_lock_irqsave(&pch->lock, flags);
|
|
+ desc->status = DONE;
|
|
+ spin_unlock_irqrestore(&pch->lock, flags);
|
|
+ }
|
|
|
|
tasklet_schedule(&pch->task);
|
|
}
|
|
@@ -2256,23 +2256,23 @@ static void pl330_tasklet(struct tasklet_struct *t)
|
|
|
|
/* Pick up ripe tomatoes */
|
|
list_for_each_entry_safe(desc, _dt, &pch->work_list, node) {
|
|
- if (desc->status == DONE) {
|
|
- if (!desc->cyclic) {
|
|
- dma_cookie_complete(&desc->txd);
|
|
- list_move_tail(&desc->node, &pch->completed_list);
|
|
- } else {
|
|
- struct dmaengine_desc_callback cb;
|
|
|
|
+ if (desc->cyclic) {
|
|
+ if (desc->status == BUSY || desc->status == DONE) {
|
|
+ struct dmaengine_desc_callback cb;
|
|
desc->status = BUSY;
|
|
dmaengine_desc_get_callback(&desc->txd, &cb);
|
|
-
|
|
if (dmaengine_desc_callback_valid(&cb)) {
|
|
spin_unlock_irqrestore(&pch->lock, flags);
|
|
dmaengine_desc_callback_invoke(&cb, NULL);
|
|
spin_lock_irqsave(&pch->lock, flags);
|
|
}
|
|
}
|
|
+ } else if (desc->status == DONE) {
|
|
+ dma_cookie_complete(&desc->txd);
|
|
+ list_move_tail(&desc->node, &pch->completed_list);
|
|
}
|
|
+
|
|
}
|
|
|
|
/* Try to submit a req imm. next to the last completed cookie */
|
|
--
|
|
2.43.0
|
|
|