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-prev] [thread-next>] [day] [month] [year] [list]
Message-id: <1352109631-3385-8-git-send-email-b.zolnierkie@samsung.com>
Date:	Mon, 05 Nov 2012 11:00:18 +0100
From:	Bartlomiej Zolnierkiewicz <b.zolnierkie@...sung.com>
To:	linux-kernel@...r.kernel.org
Cc:	djbw@...com, dwmw2@...radead.org, hskinnemoen@...il.com,
	iws@...o.caltech.edu, vinod.koul@...el.com, vipin.kumar@...com,
	t.figa@...sung.com, kyungmin.park@...sung.com,
	Bartlomiej Zolnierkiewicz <b.zolnierkie@...sung.com>
Subject: [PATCH 07/20] async_tx: do DMA unmap in core for MEMCPY operations

Add orig_callback and orig_callback_param to struct
dma_async_tx_descriptor for storing original dma_async_tx_callback
function and its parameter.  Teach async_tx_submit() about these
new parameters, to allow passing them to async_tx_submit(), rename
the function to __async_tx_submit(), add the new async_tx_submit()
wrapper to preserve the original functionality and convert core
async_tx code (async_memcpy()) to do DMA unmapping itself using
the ->callback functionality.

Cc: Dan Williams <djbw@...com>
Cc: Tomasz Figa <t.figa@...sung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@...sung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@...sung.com>
---
 crypto/async_tx/async_memcpy.c | 24 +++++++++++++++++++++---
 crypto/async_tx/async_tx.c     | 25 +++++++++++++++++++++----
 include/linux/async_tx.h       |  4 ++++
 include/linux/dmaengine.h      |  4 ++++
 4 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/crypto/async_tx/async_memcpy.c b/crypto/async_tx/async_memcpy.c
index 9e62fef..b6d5dab 100644
--- a/crypto/async_tx/async_memcpy.c
+++ b/crypto/async_tx/async_memcpy.c
@@ -30,6 +30,18 @@
 #include <linux/dma-mapping.h>
 #include <linux/async_tx.h>
 
+static void async_memcpy_cb(void *dma_async_param)
+{
+	struct dma_async_tx_descriptor *tx = dma_async_param;
+	struct dma_device *dev = tx->chan->device;
+
+	dma_unmap_page(dev->dev, tx->dma_src, tx->dma_len, DMA_TO_DEVICE);
+	dma_unmap_page(dev->dev, tx->dma_dst, tx->dma_len, DMA_FROM_DEVICE);
+
+	if (tx->orig_callback)
+		tx->orig_callback(tx->orig_callback_param);
+}
+
 /**
  * async_memcpy - attempt to copy memory with a dma engine.
  * @dest: destination page
@@ -50,10 +62,11 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset,
 						      &dest, 1, &src, 1, len);
 	struct dma_device *device = chan ? chan->device : NULL;
 	struct dma_async_tx_descriptor *tx = NULL;
+	dma_addr_t dma_dest, dma_src;
 
 	if (device && is_dma_copy_aligned(device, src_offset, dest_offset, len)) {
-		dma_addr_t dma_dest, dma_src;
-		unsigned long dma_prep_flags = 0;
+		unsigned long dma_prep_flags = DMA_COMPL_SKIP_SRC_UNMAP |
+					       DMA_COMPL_SKIP_DEST_UNMAP;
 
 		if (submit->cb_fn)
 			dma_prep_flags |= DMA_PREP_INTERRUPT;
@@ -77,7 +90,12 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset,
 
 	if (tx) {
 		pr_debug("%s: (async) len: %zu\n", __func__, len);
-		async_tx_submit(chan, tx, submit);
+
+		tx->dma_src = dma_src;
+		tx->dma_dst = dma_dest;
+		tx->dma_len = len;
+
+		__async_tx_submit(chan, tx, async_memcpy_cb, tx, submit);
 	} else {
 		void *dest_buf, *src_buf;
 		pr_debug("%s: (sync) len: %zu\n", __func__, len);
diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c
index 8421209..d4335fe 100644
--- a/crypto/async_tx/async_tx.c
+++ b/crypto/async_tx/async_tx.c
@@ -153,13 +153,22 @@ enum submit_disposition {
 };
 
 void
-async_tx_submit(struct dma_chan *chan, struct dma_async_tx_descriptor *tx,
-		struct async_submit_ctl *submit)
+__async_tx_submit(struct dma_chan *chan, struct dma_async_tx_descriptor *tx,
+		  dma_async_tx_callback cb_fn, void *cb_param,
+		  struct async_submit_ctl *submit)
 {
 	struct dma_async_tx_descriptor *depend_tx = submit->depend_tx;
 
-	tx->callback = submit->cb_fn;
-	tx->callback_param = submit->cb_param;
+	if (cb_fn) {
+		tx->orig_callback = submit->cb_fn;
+		tx->orig_callback_param = submit->cb_param;
+
+		tx->callback = cb_fn;
+		tx->callback_param = cb_param;
+	} else {
+		tx->callback = submit->cb_fn;
+		tx->callback_param = submit->cb_param;
+	}
 
 	if (depend_tx) {
 		enum submit_disposition s;
@@ -220,6 +229,14 @@ async_tx_submit(struct dma_chan *chan, struct dma_async_tx_descriptor *tx,
 	if (depend_tx)
 		async_tx_ack(depend_tx);
 }
+EXPORT_SYMBOL_GPL(__async_tx_submit);
+
+void
+async_tx_submit(struct dma_chan *chan, struct dma_async_tx_descriptor *tx,
+		struct async_submit_ctl *submit)
+{
+	__async_tx_submit(chan, tx, NULL, NULL, submit);
+}
 EXPORT_SYMBOL_GPL(async_tx_submit);
 
 /**
diff --git a/include/linux/async_tx.h b/include/linux/async_tx.h
index a1c486a..cf21d49 100644
--- a/include/linux/async_tx.h
+++ b/include/linux/async_tx.h
@@ -165,6 +165,10 @@ init_async_submit(struct async_submit_ctl *args, enum async_tx_flags flags,
 	args->scribble = scribble;
 }
 
+void __async_tx_submit(struct dma_chan *chan,
+		       struct dma_async_tx_descriptor *tx,
+		       dma_async_tx_callback cb_fn, void *cb_param,
+		       struct async_submit_ctl *submit);
 void async_tx_submit(struct dma_chan *chan, struct dma_async_tx_descriptor *tx,
 		     struct async_submit_ctl *submit);
 
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 8741d57..440b609 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -408,6 +408,8 @@ typedef void (*dma_async_tx_callback)(void *dma_async_param);
  * @callback: routine to call after this operation is complete
  * @callback_param: general parameter to pass to the callback routine
  * ---async_tx api specific fields---
+ * @orig_callback: optional routine to call from the callback routine
+ * @orig_callback_param: parameter to pass to the orig_callback routine
  * @next: at completion submit this descriptor
  * @parent: pointer to the next level up in the dependency chain
  * @lock: protect the parent and next pointers
@@ -423,6 +425,8 @@ struct dma_async_tx_descriptor {
 	size_t dma_len;
 	dma_async_tx_callback callback;
 	void *callback_param;
+	dma_async_tx_callback orig_callback;
+	void *orig_callback_param;
 #ifdef CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH
 	struct dma_async_tx_descriptor *next;
 	struct dma_async_tx_descriptor *parent;
-- 
1.8.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ