lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 18 Aug 2016 17:59:59 -0700
From:   Stephen Barber <smbarber@...omium.org>
To:     Vinod Koul <vinod.koul@...el.com>
Cc:     Dan Williams <dan.j.williams@...el.com>, dmaengine@...r.kernel.org,
        linux-kernel@...r.kernel.org,
        Douglas Anderson <dianders@...omium.org>,
        Hsin-Yu Chao <hychao@...omium.org>,
        Stephen Barber <smbarber@...omium.org>
Subject: [PATCH] dmaengine: pl330: fix residual for non-running BUSY descriptors

Only one descriptor in the work list should be running at
any given time, but it's possible to have an enqueued BUSY
descriptor that has not yet transferred any data, or for
a BUSY descriptor to linger briefly before transitioning
to DONE. These cases should be handled to keep residual
calculations consistent even with the non-running BUSY
descriptors in the work list.

Signed-off-by: Stephen Barber <smbarber@...omium.org>
---
 drivers/dma/pl330.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 372b435..ff8f889 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2274,7 +2274,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 {
 	enum dma_status ret;
 	unsigned long flags;
-	struct dma_pl330_desc *desc, *running = NULL;
+	struct dma_pl330_desc *desc, *running = NULL, *last_enq = NULL;
 	struct dma_pl330_chan *pch = to_pchan(chan);
 	unsigned int transferred, residual = 0;
 
@@ -2291,6 +2291,8 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	if (pch->thread->req_running != -1)
 		running = pch->thread->req[pch->thread->req_running].desc;
 
+	last_enq = pch->thread->req[pch->thread->lstenq].desc;
+
 	/* Check in pending list */
 	list_for_each_entry(desc, &pch->work_list, node) {
 		if (desc->status == DONE)
@@ -2298,6 +2300,15 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 		else if (running && desc == running)
 			transferred =
 				pl330_get_current_xferred_count(pch, desc);
+		else if (desc->status == BUSY)
+			/*
+			 * Busy but not running means either just enqueued,
+			 * or finished and not yet marked done
+			 */
+			if (desc == last_enq)
+				transferred = 0;
+			else
+				transferred = desc->bytes_requested;
 		else
 			transferred = 0;
 		residual += desc->bytes_requested - transferred;
-- 
2.8.0.rc3.226.g39d4020

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ