[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180528100258.317133820@linuxfoundation.org>
Date: Mon, 28 May 2018 12:04:05 +0200
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org,
Nguyen Viet Dung <dung.nguyen.aj@...esas.com>,
Yoshihiro Shimoda <yoshihiro.shimoda.uh@...esas.com>,
Vinod Koul <vinod.koul@...el.com>,
Sasha Levin <alexander.levin@...rosoft.com>
Subject: [PATCH 4.16 212/272] dmaengine: rcar-dmac: Check the done lists in rcar_dmac_chan_get_residue()
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@...esas.com>
[ Upstream commit 3e081628d510b2ddbe493371d9c574d9275da17e ]
This patch fixes an issue that a race condition happens between a client
driver and the rcar-dmac driver:
- The rcar_dmac_isr_transfer_end() is called.
- The done list appears, and desc.running is the next active list.
- rcar_dmac_chan_get_residue() is called by a client driver before
rcar_dmac_isr_channel_thread() is called.
- The rcar_dmac_chan_get_residue() will not find any descriptors.
- And, the following WARNING happens:
WARN(1, "No descriptor for cookie!");
The sh-sci driver with HSCIF (921,600bps) on R-Car H3 can cause this
situation.
So, this patch checks the done lists in rcar_dmac_chan_get_residue()
and returns zero if the done lists has the argument cookie.
Tested-by: Nguyen Viet Dung <dung.nguyen.aj@...esas.com>
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@...esas.com>
Signed-off-by: Vinod Koul <vinod.koul@...el.com>
Signed-off-by: Sasha Levin <alexander.levin@...rosoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
drivers/dma/sh/rcar-dmac.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/drivers/dma/sh/rcar-dmac.c
+++ b/drivers/dma/sh/rcar-dmac.c
@@ -1301,8 +1301,17 @@ static unsigned int rcar_dmac_chan_get_r
* If the cookie doesn't correspond to the currently running transfer
* then the descriptor hasn't been processed yet, and the residue is
* equal to the full descriptor size.
+ * Also, a client driver is possible to call this function before
+ * rcar_dmac_isr_channel_thread() runs. In this case, the "desc.running"
+ * will be the next descriptor, and the done list will appear. So, if
+ * the argument cookie matches the done list's cookie, we can assume
+ * the residue is zero.
*/
if (cookie != desc->async_tx.cookie) {
+ list_for_each_entry(desc, &chan->desc.done, node) {
+ if (cookie == desc->async_tx.cookie)
+ return 0;
+ }
list_for_each_entry(desc, &chan->desc.pending, node) {
if (cookie == desc->async_tx.cookie)
return desc->size;
Powered by blists - more mailing lists