mirror of
https://github.com/armbian/build
synced 2025-09-24 19:47:06 +07:00
rockchip/64: fix again periodic dma and audio stuttering
This commit is contained in:
@@ -38,9 +38,9 @@
|
||||
patches.armbian/general-linux-export-mm-trace-rss-stats.patch
|
||||
patches.armbian/general-pl330-01-fix-periodic-transfers.patch
|
||||
patches.armbian/general-pl330-02-add-support-for-interleaved-transfers.patch
|
||||
patches.armbian/general-pl330-03-fix-data-race-on-tx-transfers.patch
|
||||
patches.armbian/general-pl330-04-bigger-mcode-buffer.patch
|
||||
patches.armbian/general-pl330-05-fix-unbalanced-power-down.patch
|
||||
patches.armbian/general-pl330-06-fix-buffer-underruns.patch
|
||||
patches.armbian/general-rk322x-gpio-ir-driver.patch
|
||||
patches.armbian/general-rockchip-various-fixes.patch
|
||||
patches.armbian/ir-keymap-rk322x-box.patch
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
From 5654890f22bc9f08ac2afd051c935ba8f8bc7e33 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Sabatino <paolo.sabatino@gmail.com>
|
||||
Date: Thu, 23 Jan 2025 20:26:49 +0100
|
||||
Subject: [PATCH 2/2] rockchip/64: pl330: Fix data race on TX transferred bytes
|
||||
reporting
|
||||
|
||||
original source: https://patchwork.kernel.org/project/linux-rockchip/patch/20170302125710.14483-1-romain.perier@collabora.com/
|
||||
---
|
||||
drivers/dma/pl330.c | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
|
||||
index b49a3a6c4686..62003b67c231 100644
|
||||
--- a/drivers/dma/pl330.c
|
||||
+++ b/drivers/dma/pl330.c
|
||||
@@ -1872,6 +1872,7 @@ static int pl330_update(struct pl330_dmac *pl330)
|
||||
|
||||
/* Detach the req */
|
||||
descdone = thrd->req[active].desc;
|
||||
+ descdone->status = DONE;
|
||||
if (descdone) {
|
||||
if (!descdone->cyclic) {
|
||||
thrd->req[active].desc = NULL;
|
||||
@@ -1887,12 +1888,19 @@ static int pl330_update(struct pl330_dmac *pl330)
|
||||
}
|
||||
|
||||
/* Now that we are in no hurry, do the callbacks */
|
||||
+ struct dma_pl330_chan *pch;
|
||||
while (!list_empty(&pl330->req_done)) {
|
||||
descdone = list_first_entry(&pl330->req_done,
|
||||
struct dma_pl330_desc, rqd);
|
||||
list_del(&descdone->rqd);
|
||||
spin_unlock_irqrestore(&pl330->lock, flags);
|
||||
- dma_pl330_rqcb(descdone, PL330_ERR_NONE);
|
||||
+ pch = descdone->pchan;
|
||||
+ /* If desc aborted */
|
||||
+ if (!pch) {
|
||||
+ spin_lock_irqsave(&pl330->lock, flags);
|
||||
+ continue;
|
||||
+ }
|
||||
+ tasklet_schedule(&pch->task);
|
||||
spin_lock_irqsave(&pl330->lock, flags);
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
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
|
||||
|
||||
@@ -46,9 +46,9 @@
|
||||
patches.armbian/general-linux-export-mm-trace-rss-stats.patch
|
||||
patches.armbian/general-pl330-01-fix-periodic-transfers.patch
|
||||
patches.armbian/general-pl330-02-add-support-for-interleaved-transfers.patch
|
||||
patches.armbian/general-pl330-03-fix-data-race-on-tx-transfers.patch
|
||||
patches.armbian/general-pl330-04-bigger-mcode-buffer.patch
|
||||
patches.armbian/general-pl330-05-fix-unbalanced-power-down.patch
|
||||
patches.armbian/general-pl330-06-fix-buffer-underruns.patch
|
||||
patches.armbian/general-rk322x-gpio-ir-driver.patch
|
||||
patches.armbian/general-rockchip-various-fixes.patch
|
||||
patches.armbian/ir-keymap-rk322x-box.patch
|
||||
|
||||
@@ -38,9 +38,9 @@
|
||||
patches.armbian/general-linux-export-mm-trace-rss-stats.patch
|
||||
patches.armbian/general-pl330-01-fix-periodic-transfers.patch
|
||||
patches.armbian/general-pl330-02-add-support-for-interleaved-transfers.patch
|
||||
patches.armbian/general-pl330-03-fix-data-race-on-tx-transfers.patch
|
||||
patches.armbian/general-pl330-04-bigger-mcode-buffer.patch
|
||||
patches.armbian/general-pl330-05-fix-unbalanced-power-down.patch
|
||||
patches.armbian/general-pl330-06-fix-buffer-underruns.patch
|
||||
patches.armbian/general-rk322x-gpio-ir-driver.patch
|
||||
patches.armbian/general-rockchip-various-fixes.patch
|
||||
patches.armbian/ir-keymap-rk322x-box.patch
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
From 5654890f22bc9f08ac2afd051c935ba8f8bc7e33 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Sabatino <paolo.sabatino@gmail.com>
|
||||
Date: Thu, 23 Jan 2025 20:26:49 +0100
|
||||
Subject: [PATCH 2/2] rockchip/64: pl330: Fix data race on TX transferred bytes
|
||||
reporting
|
||||
|
||||
original source: https://patchwork.kernel.org/project/linux-rockchip/patch/20170302125710.14483-1-romain.perier@collabora.com/
|
||||
---
|
||||
drivers/dma/pl330.c | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
|
||||
index b49a3a6c4686..62003b67c231 100644
|
||||
--- a/drivers/dma/pl330.c
|
||||
+++ b/drivers/dma/pl330.c
|
||||
@@ -1872,6 +1872,7 @@ static int pl330_update(struct pl330_dmac *pl330)
|
||||
|
||||
/* Detach the req */
|
||||
descdone = thrd->req[active].desc;
|
||||
+ descdone->status = DONE;
|
||||
if (descdone) {
|
||||
if (!descdone->cyclic) {
|
||||
thrd->req[active].desc = NULL;
|
||||
@@ -1887,12 +1888,19 @@ static int pl330_update(struct pl330_dmac *pl330)
|
||||
}
|
||||
|
||||
/* Now that we are in no hurry, do the callbacks */
|
||||
+ struct dma_pl330_chan *pch;
|
||||
while (!list_empty(&pl330->req_done)) {
|
||||
descdone = list_first_entry(&pl330->req_done,
|
||||
struct dma_pl330_desc, rqd);
|
||||
list_del(&descdone->rqd);
|
||||
spin_unlock_irqrestore(&pl330->lock, flags);
|
||||
- dma_pl330_rqcb(descdone, PL330_ERR_NONE);
|
||||
+ pch = descdone->pchan;
|
||||
+ /* If desc aborted */
|
||||
+ if (!pch) {
|
||||
+ spin_lock_irqsave(&pl330->lock, flags);
|
||||
+ continue;
|
||||
+ }
|
||||
+ tasklet_schedule(&pch->task);
|
||||
spin_lock_irqsave(&pl330->lock, flags);
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
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
|
||||
|
||||
@@ -46,9 +46,9 @@
|
||||
patches.armbian/general-linux-export-mm-trace-rss-stats.patch
|
||||
patches.armbian/general-pl330-01-fix-periodic-transfers.patch
|
||||
patches.armbian/general-pl330-02-add-support-for-interleaved-transfers.patch
|
||||
patches.armbian/general-pl330-03-fix-data-race-on-tx-transfers.patch
|
||||
patches.armbian/general-pl330-04-bigger-mcode-buffer.patch
|
||||
patches.armbian/general-pl330-05-fix-unbalanced-power-down.patch
|
||||
patches.armbian/general-pl330-06-fix-buffer-underruns.patch
|
||||
patches.armbian/general-rk322x-gpio-ir-driver.patch
|
||||
patches.armbian/general-rockchip-various-fixes.patch
|
||||
patches.armbian/ir-keymap-rk322x-box.patch
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
From 5654890f22bc9f08ac2afd051c935ba8f8bc7e33 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Sabatino <paolo.sabatino@gmail.com>
|
||||
Date: Thu, 23 Jan 2025 20:26:49 +0100
|
||||
Subject: [PATCH 2/2] rockchip/64: pl330: Fix data race on TX transferred bytes
|
||||
reporting
|
||||
|
||||
original source: https://patchwork.kernel.org/project/linux-rockchip/patch/20170302125710.14483-1-romain.perier@collabora.com/
|
||||
---
|
||||
drivers/dma/pl330.c | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
|
||||
index b49a3a6c4686..62003b67c231 100644
|
||||
--- a/drivers/dma/pl330.c
|
||||
+++ b/drivers/dma/pl330.c
|
||||
@@ -1872,6 +1872,7 @@ static int pl330_update(struct pl330_dmac *pl330)
|
||||
|
||||
/* Detach the req */
|
||||
descdone = thrd->req[active].desc;
|
||||
+ descdone->status = DONE;
|
||||
if (descdone) {
|
||||
if (!descdone->cyclic) {
|
||||
thrd->req[active].desc = NULL;
|
||||
@@ -1887,12 +1888,19 @@ static int pl330_update(struct pl330_dmac *pl330)
|
||||
}
|
||||
|
||||
/* Now that we are in no hurry, do the callbacks */
|
||||
+ struct dma_pl330_chan *pch;
|
||||
while (!list_empty(&pl330->req_done)) {
|
||||
descdone = list_first_entry(&pl330->req_done,
|
||||
struct dma_pl330_desc, rqd);
|
||||
list_del(&descdone->rqd);
|
||||
spin_unlock_irqrestore(&pl330->lock, flags);
|
||||
- dma_pl330_rqcb(descdone, PL330_ERR_NONE);
|
||||
+ pch = descdone->pchan;
|
||||
+ /* If desc aborted */
|
||||
+ if (!pch) {
|
||||
+ spin_lock_irqsave(&pl330->lock, flags);
|
||||
+ continue;
|
||||
+ }
|
||||
+ tasklet_schedule(&pch->task);
|
||||
spin_lock_irqsave(&pl330->lock, flags);
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
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
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
From 5654890f22bc9f08ac2afd051c935ba8f8bc7e33 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Sabatino <paolo.sabatino@gmail.com>
|
||||
Date: Thu, 23 Jan 2025 20:26:49 +0100
|
||||
Subject: [PATCH 2/2] rockchip/64: pl330: Fix data race on TX transferred bytes
|
||||
reporting
|
||||
|
||||
original source: https://patchwork.kernel.org/project/linux-rockchip/patch/20170302125710.14483-1-romain.perier@collabora.com/
|
||||
---
|
||||
drivers/dma/pl330.c | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
|
||||
index b49a3a6c4686..62003b67c231 100644
|
||||
--- a/drivers/dma/pl330.c
|
||||
+++ b/drivers/dma/pl330.c
|
||||
@@ -1872,6 +1872,7 @@ static int pl330_update(struct pl330_dmac *pl330)
|
||||
|
||||
/* Detach the req */
|
||||
descdone = thrd->req[active].desc;
|
||||
+ descdone->status = DONE;
|
||||
if (descdone) {
|
||||
if (!descdone->cyclic) {
|
||||
thrd->req[active].desc = NULL;
|
||||
@@ -1887,12 +1888,19 @@ static int pl330_update(struct pl330_dmac *pl330)
|
||||
}
|
||||
|
||||
/* Now that we are in no hurry, do the callbacks */
|
||||
+ struct dma_pl330_chan *pch;
|
||||
while (!list_empty(&pl330->req_done)) {
|
||||
descdone = list_first_entry(&pl330->req_done,
|
||||
struct dma_pl330_desc, rqd);
|
||||
list_del(&descdone->rqd);
|
||||
spin_unlock_irqrestore(&pl330->lock, flags);
|
||||
- dma_pl330_rqcb(descdone, PL330_ERR_NONE);
|
||||
+ pch = descdone->pchan;
|
||||
+ /* If desc aborted */
|
||||
+ if (!pch) {
|
||||
+ spin_lock_irqsave(&pl330->lock, flags);
|
||||
+ continue;
|
||||
+ }
|
||||
+ tasklet_schedule(&pch->task);
|
||||
spin_lock_irqsave(&pl330->lock, flags);
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user