dma: k3dma: Fix non-cyclic mode
PATCH 1/1 dma: k3dma: Fix non-cyclic mode
From: Antonio Borneo <[email protected]>
Commit 36387a2b1f62b5c087c5fe6f0f7b23b94f722ad7 ("k3dma: Fix memory handling in preparation for cyclic mode") broke the logic around ds_run/ds_done in case of non-cyclic DMA.
This went unnoticed as the only user of k3dma was the i2s audio driver, but with a patch set to enable dma on SPI, the issue cropped up.
This patch resolves the issue by reverting part of the problematic commit.
This patch has been tested to ensure both audio playback and SPI works fine using DMA and that no memory leak is present.
--- drivers/dma/k3dma.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
drivers/dma/k3dma.c +4 -8
@@ -223,7 +223,6 @@ static irqreturn_t k3_dma_int_handler(int irq, void *dev_id)if (c && (tc1 &BIT (i))) {spin_lock_irqsave (&c->vc.lock, flags);vchan_cookie_complete (&p->ds_run->vd); -WARN_ON_ONCE (p->ds_done); p->ds_done = p->ds_run; p->ds_run =NULL ;spin_unlock_irqrestore (&c->vc.lock, flags);
@@ -274,13 +273,14 @@ static int k3_dma_start_txd(struct k3_dma_chan *c)*/ list_del (&ds->vd.node); -WARN_ON_ONCE (c->phy->ds_run); -WARN_ON_ONCE (c->phy->ds_done); c->phy->ds_run = ds; + c->phy->ds_done =NULL ;/* start dma */ k3_dma_set_desc (c->phy, &ds->desc_hw[0 ]);return 0 ; } + c->phy->ds_run =NULL ; + c->phy->ds_done =NULL ;return -EAGAIN ; }
@@ -722,11 +722,7 @@ static int k3_dma_terminate_all(struct dma_chan *chan)k3_dma_free_desc (&p->ds_run->vd); p->ds_run =NULL ; } -if (p->ds_done) { -k3_dma_free_desc (&p->ds_done->vd); - p->ds_done =NULL ; - } - + p->ds_done =NULL ; }spin_unlock_irqrestore (&c->vc.lock, flags);vchan_dma_desc_free_list (&c->vc, &head);
Signature · 1 line
2.7.4
Quoted 16 lines · John Stultz
From: Antonio Borneo <[email protected]>
Commit
36387a2b1f62b5c087c5fe6f0f7b23b94f722ad7("k3dma: Fix memory handling in preparation for cyclic mode") broke the logic around ds_run/ds_done in case of non-cyclic DMA.This went unnoticed as the only user of k3dma was the i2s audio driver, but with a patch set to enable dma on SPI, the issue cropped up.
This patch resolves the issue by reverting part of the problematic commit.
This patch has been tested to ensure both audio playback and SPI works fine using DMA and that no memory leak is present.
Quoted 7 lines
Cc Vinod Koul <[email protected]>Cc Dan Williams <[email protected]>Cc Zhangfei Gao <[email protected]>Signed-off-by Antonio Borneo <[email protected]>[jstultz: Expanded commit message a bit]Signed-off-by John Stultz <[email protected]>
Thanks
Quoted 6 lines · John Stultz
From: Antonio Borneo <[email protected]>
Commit
36387a2b1f62b5c087c5fe6f0f7b23b94f722ad7("k3dma: Fix memory handling in preparation for cyclic mode") broke the logic around ds_run/ds_done in case of non-cyclic DMA.
Quoted 6 lines
This went unnoticed as the only user of k3dma was the i2s audio driver, but with a patch set to enable dma on SPI, the issue cropped up.
This patch resolves the issue by reverting part of the problematic commit.
Can you explain the fix here, how reverting helps around with that? Right now am not able to comprehend the fix on this..
Quoted 27 lines
This patch has been tested to ensure both audio playback and SPI works fine using DMA and that no memory leak is present.
Cc Vinod Koul <[email protected]>Cc Dan Williams <[email protected]>Cc Zhangfei Gao <[email protected]>Signed-off-by Antonio Borneo <[email protected]>[jstultz: Expanded commit message a bit]Signed-off-by John Stultz <[email protected]>--- drivers/dma/k3dma.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)drivers/dma/k3dma.c +0
-1@@ -223,7 +223,6 @@ static irqreturn_t k3_dma_int_handler(int irq, void *dev_id)if (c && (tc1 &BIT (i))) {spin_lock_irqsave (&c->vc.lock, flags);vchan_cookie_complete (&p->ds_run->vd); -WARN_ON_ONCE (p->ds_done); p->ds_done = p->ds_run; p->ds_run =NULL ;spin_unlock_irqrestore (&c->vc.lock, flags);
drivers/dma/k3dma.c static int k3_dma_start_txd(struct k3_dma_chan *c) · line 278
Quoted 5 lines
drivers/dma/k3dma.c +0
-2@@ -274,13 +273,14 @@ static int k3_dma_start_txd(struct k3_dma_chan *c)*/ list_del (&ds->vd.node); -WARN_ON_ONCE (c->phy->ds_run); -WARN_ON_ONCE (c->phy->ds_done);
Not sure why WARN_ON should be removed?
Quoted 27 lines
drivers/dma/k3dma.c +4
-5c->phy->ds_run = ds; + c->phy->ds_done =NULL ;/* start dma */ k3_dma_set_desc (c->phy, &ds->desc_hw[0 ]);return 0 ; } + c->phy->ds_run =NULL ; + c->phy->ds_done =NULL ;return -EAGAIN ; }@@ -722,11 +722,7 @@ static int k3_dma_terminate_all(struct dma_chan *chan)k3_dma_free_desc (&p->ds_run->vd); p->ds_run =NULL ; } -if (p->ds_done) { -k3_dma_free_desc (&p->ds_done->vd); - p->ds_done =NULL ; - } - + p->ds_done =NULL ; }spin_unlock_irqrestore (&c->vc.lock, flags);vchan_dma_desc_free_list (&c->vc, &head);Signature · 1 line
2.7.4
Signature · 1 line
~Vinod
Quoted 11 lines · Vinod Koul
Quoted 10 lines · John Stultz
From: Antonio Borneo <[email protected]>
Commit
36387a2b1f62b5c087c5fe6f0f7b23b94f722ad7("k3dma: Fix memory handling in preparation for cyclic mode") broke the logic around ds_run/ds_done in case of non-cyclic DMA.This went unnoticed as the only user of k3dma was the i2s audio driver, but with a patch set to enable dma on SPI, the issue cropped up.
Quoted 6 lines
Quoted 2 lines
This patch resolves the issue by reverting part of the problematic commit.
Can you explain the fix here, how reverting helps around with that? Right now am not able to comprehend the fix on this..
Hi Vinod,
thanks for your review.
The structure of the driver k3dma seams inspired to zx_dma that uses the same ds_run/ds_done method.
This driver k3dma was already working fine for non-cyclic use cases, like SPI. While preparing support for cyclic mode, the commit above removed some assignment to NULL for ds_run/ds_done at the end of the non-cyclic DMA transfer. As result, only the first non-cyclic DMA transfer completes successfully, the following non-cyclic DMA transfer hangs (plus it triggers one WARN_ON() because of the missing NULL initialization).
The main target of this patch is to re-add the NULL assignments.
Quoted 30 lines
Quoted 30 lines
This patch has been tested to ensure both audio playback and SPI works fine using DMA and that no memory leak is present.
Cc Vinod Koul <[email protected]>Cc Dan Williams <[email protected]>Cc Zhangfei Gao <[email protected]>Signed-off-by Antonio Borneo <[email protected]>[jstultz: Expanded commit message a bit]Signed-off-by John Stultz <[email protected]>--- drivers/dma/k3dma.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)drivers/dma/k3dma.c +0
-1@@ -223,7 +223,6 @@ static irqreturn_t k3_dma_int_handler(int irq, void *dev_id)if (c && (tc1 &BIT (i))) {spin_lock_irqsave (&c->vc.lock, flags);vchan_cookie_complete (&p->ds_run->vd); -WARN_ON_ONCE (p->ds_done); p->ds_done = p->ds_run; p->ds_run =NULL ;spin_unlock_irqrestore (&c->vc.lock, flags);@@ -274,13 +273,14 @@ static int k3_dma_start_txd(struct k3_dma_chan *c)*/ list_del (&ds->vd.node);
Quoted 4 lines
drivers/dma/k3dma.c static int k3_dma_start_txd(struct k3_dma_chan *c) · line 278
Quoted 2 lines
drivers/dma/k3dma.c +0
-2-WARN_ON_ONCE (c->phy->ds_run); -WARN_ON_ONCE (c->phy->ds_done);Not sure why
WARN_ONshould be removed?
The commit above added them. Now that the logic on ds_run/ds_done is fixed, I do not see reason for them anymore.
Best Regards
Antonio
Quoted 31 lines
Quoted 26 lines
drivers/dma/k3dma.c +4
-6c->phy->ds_run = ds; + c->phy->ds_done =NULL ;/* start dma */ k3_dma_set_desc (c->phy, &ds->desc_hw[0 ]);return 0 ; } + c->phy->ds_run =NULL ; + c->phy->ds_done =NULL ;return -EAGAIN ; }@@ -722,11 +722,7 @@ static int k3_dma_terminate_all(struct dma_chan *chan)k3_dma_free_desc (&p->ds_run->vd); p->ds_run =NULL ; } -if (p->ds_done) { -k3_dma_free_desc (&p->ds_done->vd); - p->ds_done =NULL ; - } - + p->ds_done =NULL ; }spin_unlock_irqrestore (&c->vc.lock, flags);vchan_dma_desc_free_list (&c->vc, &head); --Quoted 2 lines
2.7.4
--
~Vinod
Quoted 32 lines · Antonio Borneo
Quoted 11 lines · Vinod Koul
Quoted 10 lines · John Stultz
From: Antonio Borneo <[email protected]>
Commit
36387a2b1f62b5c087c5fe6f0f7b23b94f722ad7("k3dma: Fix memory handling in preparation for cyclic mode") broke the logic around ds_run/ds_done in case of non-cyclic DMA.This went unnoticed as the only user of k3dma was the i2s audio driver, but with a patch set to enable dma on SPI, the issue cropped up.
Quoted 6 lines
Quoted 2 lines
This patch resolves the issue by reverting part of the problematic commit.
Can you explain the fix here, how reverting helps around with that? Right now am not able to comprehend the fix on this..
Hi Vinod,
thanks for your review.
The structure of the driver k3dma seams inspired to
zx_dmathat uses the same ds_run/ds_done method.
This driver k3dma was already working fine for non-cyclic use cases, like SPI. While preparing support for cyclic mode, the commit above removed some assignment to NULL for ds_run/ds_done at the end of the non-cyclic DMA transfer. As result, only the first non-cyclic DMA transfer completes successfully, the following non-cyclic DMA transfer hangs (plus it triggers oneWARN_ON()because of the missing NULL initialization).
Quoted 1 line
The main target of this patch is to re-add the NULL assignments.
Okay so fix is only adding NULL assignments, and which was not at all clear from the changelog. The changelog need to give reviewers and maintainers and idea on why a change was done and the details of the fix.
Quoted 30 lines
Quoted 30 lines
Quoted 30 lines
This patch has been tested to ensure both audio playback and SPI works fine using DMA and that no memory leak is present.
Cc Vinod Koul <[email protected]>Cc Dan Williams <[email protected]>Cc Zhangfei Gao <[email protected]>Signed-off-by Antonio Borneo <[email protected]>[jstultz: Expanded commit message a bit]Signed-off-by John Stultz <[email protected]>--- drivers/dma/k3dma.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)drivers/dma/k3dma.c +0
-1@@ -223,7 +223,6 @@ static irqreturn_t k3_dma_int_handler(int irq, void *dev_id)if (c && (tc1 &BIT (i))) {spin_lock_irqsave (&c->vc.lock, flags);vchan_cookie_complete (&p->ds_run->vd); -WARN_ON_ONCE (p->ds_done); p->ds_done = p->ds_run; p->ds_run =NULL ;spin_unlock_irqrestore (&c->vc.lock, flags);@@ -274,13 +273,14 @@ static int k3_dma_start_txd(struct k3_dma_chan *c)*/ list_del (&ds->vd.node);
Quoted 7 lines
Quoted 4 lines
drivers/dma/k3dma.c static int k3_dma_start_txd(struct k3_dma_chan *c) · line 278
Quoted 2 lines
drivers/dma/k3dma.c +0
-2-WARN_ON_ONCE (c->phy->ds_run); -WARN_ON_ONCE (c->phy->ds_done);Not sure why
WARN_ONshould be removed?The commit above added them. Now that the logic on ds_run/ds_done is fixed, I do not see reason for them anymore.
Since this is not a revert and only fix, I would prefer this to be removed from fix, if you want to remove these please do send a second patch as this has nothing to do with the fix
While at it, also change the patch title to dmaengine: ....
Thanks
Signature · 1 line
~Vinod
Quoted 33 lines · Vinod Koul
Quoted 32 lines · Antonio Borneo
Quoted 11 lines · Vinod Koul
Quoted 10 lines · John Stultz
From: Antonio Borneo <[email protected]>
Commit
36387a2b1f62b5c087c5fe6f0f7b23b94f722ad7("k3dma: Fix memory handling in preparation for cyclic mode") broke the logic around ds_run/ds_done in case of non-cyclic DMA.This went unnoticed as the only user of k3dma was the i2s audio driver, but with a patch set to enable dma on SPI, the issue cropped up.
Quoted 6 lines
Quoted 2 lines
This patch resolves the issue by reverting part of the problematic commit.
Can you explain the fix here, how reverting helps around with that? Right now am not able to comprehend the fix on this..
Hi Vinod,
thanks for your review.
The structure of the driver k3dma seams inspired to
zx_dmathat uses the same ds_run/ds_done method.
This driver k3dma was already working fine for non-cyclic use cases, like SPI. While preparing support for cyclic mode, the commit above removed some assignment to NULL for ds_run/ds_done at the end of the non-cyclic DMA transfer. As result, only the first non-cyclic DMA transfer completes successfully, the following non-cyclic DMA transfer hangs (plus it triggers oneWARN_ON()because of the missing NULL initialization).
Quoted 5 lines
Quoted 1 line
The main target of this patch is to re-add the NULL assignments.
Okay so fix is only adding NULL assignments, and which was not at all clear from the changelog. The changelog need to give reviewers and maintainers and idea on why a change was done and the details of the fix.
Ok, I will make it clear in V2
Quoted 36 lines
Quoted 36 lines
Quoted 35 lines
Quoted 28 lines
This patch has been tested to ensure both audio playback and SPI works fine using DMA and that no memory leak is present.
Cc Vinod Koul <[email protected]>Cc Dan Williams <[email protected]>Cc Zhangfei Gao <[email protected]>Signed-off-by Antonio Borneo <[email protected]>[jstultz: Expanded commit message a bit]Signed-off-by John Stultz <[email protected]>--- drivers/dma/k3dma.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)drivers/dma/k3dma.c +0
-1@@ -223,7 +223,6 @@ static irqreturn_t k3_dma_int_handler(int irq, void *dev_id)if (c && (tc1 &BIT (i))) {spin_lock_irqsave (&c->vc.lock, flags);vchan_cookie_complete (&p->ds_run->vd); -WARN_ON_ONCE (p->ds_done); p->ds_done = p->ds_run; p->ds_run =NULL ;spin_unlock_irqrestore (&c->vc.lock, flags);drivers/dma/k3dma.c static int k3_dma_start_txd(struct k3_dma_chan *c) · line 278
Quoted 5 lines
drivers/dma/k3dma.c +0
-2@@ -274,13 +273,14 @@ static int k3_dma_start_txd(struct k3_dma_chan *c)*/ list_del (&ds->vd.node); -WARN_ON_ONCE (c->phy->ds_run); -WARN_ON_ONCE (c->phy->ds_done);Not sure why
WARN_ONshould be removed?
Quoted 8 lines
Quoted 2 lines
The commit above added them. Now that the logic on ds_run/ds_done is fixed, I do not see reason for them anymore.
Since this is not a revert and only fix, I would prefer this to be removed from fix, if you want to remove these please do send a second patch as this has nothing to do with the fix
While at it, also change the patch title to dmaengine: ....
Ok, I will split it and change the title.
Thanks
Antonio
Quoted 4 lines
Thanks
--
~Vinod
v2 cover dmaengine: k3dma: Fix non-cyclic mode
Commit 36387a2b1f62b5c087c5fe6f0f7b23b94f722ad7 ("k3dma: Fix memory handling in preparation for cyclic mode") broke the logic around ds_run/ds_done in case of non-cyclic DMA.
This v2 splits the initial patch in three parts:
- the real fix for non-cyclic mode
- another fix for a double free introduced in the same commit
- cosmetic removal of useless ON_WARN_ONCE()
Thread in https://patchwork.kernel.org/patch/9833791/
v1 -> v2
- split the patch
- change patch title to "dmaengine: ..."
Antonio Borneo (3):
dmaengine: k3dma: fix non-cyclic mode
dmaengine: k3dma: fix double free of descriptor
dmaengine: k3dma: remove useless ON_WARN_ONCE()
drivers/dma/k3dma.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
Signature · 1 line
1.9.1
PATCH v2 1/3 dmaengine: k3dma: fix non-cyclic mode
Commit 36387a2b1f62b5c087c5fe6f0f7b23b94f722ad7 ("k3dma: Fix memory handling in preparation for cyclic mode") broke the logic around ds_run/ds_done in case of non-cyclic DMA.
This went unnoticed as the only user of k3dma was the i2s audio driver but, with a patch set to enable dma on SPI, the issue popped out.
The fix re-applies the initialization to ds_run/ds_done in k3_dma_start_txd() that were removed by the commit above.
Also, one of the calls to k3_dma_start_txd() is triggered by (ds_done != NULL), so remove the noisy and useless call to WARN_ON_ONCE().
---
To: [email protected]
To: Vinod Koul <[email protected]>
To: Dan Williams <[email protected]>
Cc: [email protected]
Cc: John Stultz <[email protected]>
Cc: Zhangfei Gao <[email protected]>
--- drivers/dma/k3dma.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/dma/k3dma.c +3 -1
@@ -275,12 +275,14 @@ static int k3_dma_start_txd(struct k3_dma_chan *c)list_del (&ds->vd.node);WARN_ON_ONCE (c->phy->ds_run); -WARN_ON_ONCE (c->phy->ds_done); c->phy->ds_run = ds; + c->phy->ds_done =NULL ;/* start dma */ k3_dma_set_desc (c->phy, &ds->desc_hw[0 ]);return 0 ; } + c->phy->ds_run =NULL ; + c->phy->ds_done =NULL ;return -EAGAIN ; }
Signature · 1 line
1.9.1
PATCH v2 2/3 dmaengine: k3dma: fix double free of descriptor
In reply to Antonio BorneoCommit 36387a2b1f62b5c087c5fe6f0f7b23b94f722ad7 ("k3dma: Fix memory handling in preparation for cyclic mode") adds code to free the descriptor in ds_done.
In cyclic mode, ds_done is never used and it's always NULL, so the added code is not executed.
In non-cyclic mode, ds_done is used as a flag: when not NULL it signals that the descriptor has been consumed. No need to free it because it would be free by vchan_complete().
The fix takes back the code changed by the commit above:
- remove the free on the descriptor;
- initialize ds_done to NULL for the next run.
---
To: [email protected]
To: Vinod Koul <[email protected]>
To: Dan Williams <[email protected]>
Cc: [email protected]
Cc: John Stultz <[email protected]>
Cc: Zhangfei Gao <[email protected]>
--- drivers/dma/k3dma.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/dma/k3dma.c +1 -5
@@ -724,11 +724,7 @@ static int k3_dma_terminate_all(struct dma_chan *chan)k3_dma_free_desc (&p->ds_run->vd); p->ds_run =NULL ; } -if (p->ds_done) { -k3_dma_free_desc (&p->ds_done->vd); - p->ds_done =NULL ; - } - + p->ds_done =NULL ; }spin_unlock_irqrestore (&c->vc.lock, flags);vchan_dma_desc_free_list (&c->vc, &head);
Signature · 1 line
1.9.1
PATCH v2 3/3 dmaengine: k3dma: remove useless ON_WARN_ONCE()
In reply to Antonio BorneoCommit 36387a2b1f62b5c087c5fe6f0f7b23b94f722ad7 ("k3dma: Fix memory handling in preparation for cyclic mode") adds few calls to ON_WARN_ONCE() to track the use of ds_run/ds_done.
After the two fixes:
- dmaengine: k3dma: fix non-cyclic mode
- dmaengine: k3dma: fix re-free of the same descriptor the behaviour of ds_run/ds_done is properly fixed. The remaining ON_WARN_ONCE() are never triggered and can be removed.
---
To: [email protected]
To: Vinod Koul <[email protected]>
To: Dan Williams <[email protected]>
Cc: [email protected]
Cc: John Stultz <[email protected]>
Cc: Zhangfei Gao <[email protected]>
--- drivers/dma/k3dma.c | 2 -- 1 file changed, 2 deletions(-)
drivers/dma/k3dma.c +0 -2
@@ -223,7 +223,6 @@ static irqreturn_t k3_dma_int_handler(int irq, void *dev_id)if (c && (tc1 &BIT (i))) {spin_lock_irqsave (&c->vc.lock, flags);vchan_cookie_complete (&p->ds_run->vd); -WARN_ON_ONCE (p->ds_done); p->ds_done = p->ds_run; p->ds_run =NULL ;spin_unlock_irqrestore (&c->vc.lock, flags);
@@ -274,7 +273,6 @@ static int k3_dma_start_txd(struct k3_dma_chan *c)*/ list_del (&ds->vd.node); -WARN_ON_ONCE (c->phy->ds_run); c->phy->ds_run = ds; c->phy->ds_done =NULL ;/* start dma */
Signature · 1 line
1.9.1
Vinod Koul
AppliedRe: [PATCH v2 0/3] dmaengine: k3dma: Fix non-cyclic mode
In reply to Antonio BorneoQuoted 3 lines · Antonio Borneo
Commit
36387a2b1f62b5c087c5fe6f0f7b23b94f722ad7("k3dma: Fix memory handling in preparation for cyclic mode") broke the logic around ds_run/ds_done in case of non-cyclic DMA.
Applied, thanks
Signature · 1 line
~Vinod