public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Dan Williams <dan.j.williams@intel.com>
To: neilb@suse.de, linux-raid@vger.kernel.org
Cc: maan@systemlinux.org, linux-kernel@vger.kernel.org,
	yur@emcraft.com, hpa@zytor.com
Subject: [PATCH v2 04/11] async_xor: permit callers to pass in a 'dma/page scribble' region
Date: Mon, 18 May 2009 17:59:46 -0700	[thread overview]
Message-ID: <20090519005946.4104.28803.stgit@dwillia2-linux.ch.intel.com> (raw)
In-Reply-To: <20090519005647.4104.81119.stgit@dwillia2-linux.ch.intel.com>

async_xor() needs space to perform dma and page address conversions.  In
most cases the code can simply reuse the struct page * array because the
size of the native pointer matches the size of a dma/page address.  In
order to support archs where sizeof(dma_addr_t) is larger than
sizeof(struct page *), or to preserve the input parameters, we utilize a
memory region passed in by the caller.

Since the code is now prepared to handle the case where it cannot
perform address conversions on the stack, we no longer need the
!HIGHMEM64G dependency in drivers/dma/Kconfig.

[ Impact: don't clobber input buffers for address conversions ]

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 crypto/async_tx/async_xor.c |   59 ++++++++++++++++++++-----------------------
 drivers/dma/Kconfig         |    2 +
 2 files changed, 29 insertions(+), 32 deletions(-)

diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c
index 6290d05..3caecdd 100644
--- a/crypto/async_tx/async_xor.c
+++ b/crypto/async_tx/async_xor.c
@@ -33,11 +33,10 @@
 /* do_async_xor - dma map the pages and perform the xor with an engine */
 static __async_inline struct dma_async_tx_descriptor *
 do_async_xor(struct dma_chan *chan, struct page *dest, struct page **src_list,
-	     unsigned int offset, int src_cnt, size_t len,
+	     unsigned int offset, int src_cnt, size_t len, dma_addr_t *dma_src,
 	     struct async_submit_ctl *submit)
 {
 	struct dma_device *dma = chan->device;
-	dma_addr_t *dma_src = (dma_addr_t *) src_list;
 	struct dma_async_tx_descriptor *tx = NULL;
 	int src_off = 0;
 	int i;
@@ -125,9 +124,14 @@ do_sync_xor(struct page *dest, struct page **src_list, unsigned int offset,
 	int xor_src_cnt;
 	int src_off = 0;
 	void *dest_buf;
-	void **srcs = (void **) src_list;
+	void **srcs;
 
-	/* reuse the 'src_list' array to convert to buffer pointers */
+	if (submit->scribble)
+		srcs = (void **) submit->scribble;
+	else
+		srcs = (void **) src_list;
+
+	/* convert to buffer pointers */
 	for (i = 0; i < src_cnt; i++)
 		srcs[i] = page_address(src_list[i]) + offset;
 
@@ -171,17 +175,26 @@ async_xor(struct page *dest, struct page **src_list, unsigned int offset,
 	struct dma_chan *chan = async_tx_find_channel(submit, DMA_XOR,
 						      &dest, 1, src_list,
 						      src_cnt, len);
+	dma_addr_t *dma_src = NULL;
+
 	BUG_ON(src_cnt <= 1);
 
-	if (chan) {
+	if (submit->scribble)
+		dma_src = submit->scribble;
+	else if (sizeof(dma_addr_t) <= sizeof(struct page *))
+		dma_src = (dma_addr_t *) src_list;
+
+	if (dma_src && chan) {
 		/* run the xor asynchronously */
 		pr_debug("%s (async): len: %zu\n", __func__, len);
 
 		return do_async_xor(chan, dest, src_list, offset, src_cnt, len,
-				    submit);
+				    dma_src, submit);
 	} else {
 		/* run the xor synchronously */
 		pr_debug("%s (sync): len: %zu\n", __func__, len);
+		WARN_ONCE(chan, "%s: no space for dma address conversion\n",
+			  __func__);
 
 		/* in the sync case the dest is an implied source
 		 * (assumes the dest is the first source)
@@ -229,11 +242,16 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
 						      src_cnt, len);
 	struct dma_device *device = chan ? chan->device : NULL;
 	struct dma_async_tx_descriptor *tx = NULL;
+	dma_addr_t *dma_src = NULL;
 
 	BUG_ON(src_cnt <= 1);
 
-	if (device && src_cnt <= device->max_xor) {
-		dma_addr_t *dma_src = (dma_addr_t *) src_list;
+	if (submit->scribble)
+		dma_src = submit->scribble;
+	else if (sizeof(dma_addr_t) <= sizeof(struct page *))
+		dma_src = (dma_addr_t *) src_list;
+
+	if (dma_src && device && src_cnt <= device->max_xor) {
 		unsigned long dma_prep_flags;
 		int i;
 
@@ -263,6 +281,8 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
 		enum async_tx_flags flags_orig = submit->flags;
 
 		pr_debug("%s: (sync) len: %zu\n", __func__, len);
+		WARN_ONCE(device && src_cnt <= device->max_xor,
+			  "%s: no space for dma address conversion\n", __func__);
 
 		submit->flags |= ASYNC_TX_XOR_DROP_DST;
 		submit->flags &= ~ASYNC_TX_ACK;
@@ -281,29 +301,6 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
 }
 EXPORT_SYMBOL_GPL(async_xor_val);
 
-static int __init async_xor_init(void)
-{
-	#ifdef CONFIG_DMA_ENGINE
-	/* To conserve stack space the input src_list (array of page pointers)
-	 * is reused to hold the array of dma addresses passed to the driver.
-	 * This conversion is only possible when dma_addr_t is less than the
-	 * the size of a pointer.  HIGHMEM64G is known to violate this
-	 * assumption.
-	 */
-	BUILD_BUG_ON(sizeof(dma_addr_t) > sizeof(struct page *));
-	#endif
-
-	return 0;
-}
-
-static void __exit async_xor_exit(void)
-{
-	do { } while (0);
-}
-
-module_init(async_xor_init);
-module_exit(async_xor_exit);
-
 MODULE_AUTHOR("Intel Corporation");
 MODULE_DESCRIPTION("asynchronous xor/xor-zero-sum api");
 MODULE_LICENSE("GPL");
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 3b3c01b..912a51b 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -4,7 +4,7 @@
 
 menuconfig DMADEVICES
 	bool "DMA Engine support"
-	depends on !HIGHMEM64G && HAS_DMA
+	depends on HAS_DMA
 	help
 	  DMA engines can do asynchronous data transfers without
 	  involving the host CPU.  Currently, this framework can be


  parent reply	other threads:[~2009-05-19  1:00 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-19  0:59 [PATCH v2 00/11] Asynchronous raid6 acceleration (part 1 of 3) Dan Williams
2009-05-19  0:59 ` [PATCH v2 01/11] async_tx: rename zero_sum to val Dan Williams
     [not found]   ` <f12847240905200110x63b22601idbbdf3369984fa9a@mail.gmail.com>
2009-05-29 13:41     ` Sosnowski, Maciej
2009-05-19  0:59 ` [PATCH v2 02/11] async_tx: kill ASYNC_TX_DEP_ACK flag Dan Williams
     [not found]   ` <f12847240905250320w74897dabo6576b4b48bd19c0c@mail.gmail.com>
2009-05-29 13:41     ` Sosnowski, Maciej
2009-05-19  0:59 ` [PATCH v2 03/11] async_tx: structify submission arguments, add scribble Dan Williams
     [not found]   ` <f12847240905250321v774c4e8dscd7a466cd2e61168@mail.gmail.com>
2009-05-29 13:41     ` Sosnowski, Maciej
2009-05-19  0:59 ` Dan Williams [this message]
     [not found]   ` <f12847240905250320w523fc657w3bca47f23442f46e@mail.gmail.com>
2009-05-29 13:41     ` [PATCH v2 04/11] async_xor: permit callers to pass in a 'dma/page scribble' region Sosnowski, Maciej
2009-05-19  0:59 ` [PATCH v2 05/11] md/raid5: add scribble region for buffer lists Dan Williams
2009-06-04  6:11   ` Neil Brown
2009-06-05 19:19     ` Dan Williams
2009-06-08 17:25       ` Jody McIntyre
2009-05-19  0:59 ` [PATCH v2 06/11] async_tx: add sum check flags Dan Williams
     [not found]   ` <f12847240905200111p54382735v6941b52825cf4d7e@mail.gmail.com>
2009-05-29 13:41     ` Sosnowski, Maciej
2009-05-19  1:00 ` [PATCH v2 07/11] async_tx: kill needless module_{init|exit} Dan Williams
     [not found]   ` <f12847240905250323o21113fb9xbc4c16eea07b215@mail.gmail.com>
2009-05-29 13:42     ` Sosnowski, Maciej
2009-05-19  1:00 ` [PATCH v2 08/11] async_tx: add support for asynchronous GF multiplication Dan Williams
     [not found]   ` <f12847240905200111q37457b29lb9e30879e251888@mail.gmail.com>
2009-05-29 13:42     ` Sosnowski, Maciej
2009-05-19  1:00 ` [PATCH v2 09/11] async_tx: add support for asynchronous RAID6 recovery operations Dan Williams
     [not found]   ` <f12847240905250323q2e14efd6q69022a62cc7fd01f@mail.gmail.com>
2009-05-29 13:42     ` Sosnowski, Maciej
2009-05-19  1:00 ` [PATCH v2 10/11] dmatest: add pq support Dan Williams
     [not found]   ` <f12847240905250324t1a55b757hc8cd06d6b9663efe@mail.gmail.com>
2009-05-29 13:42     ` Sosnowski, Maciej
2009-05-19  1:00 ` [PATCH v2 11/11] async_tx: raid6 recovery self test Dan Williams
     [not found]   ` <f12847240905250324k2b4a0c7as9ac9b084d3707ce5@mail.gmail.com>
2009-05-29 13:42     ` Sosnowski, Maciej

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090519005946.4104.28803.stgit@dwillia2-linux.ch.intel.com \
    --to=dan.j.williams@intel.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-raid@vger.kernel.org \
    --cc=maan@systemlinux.org \
    --cc=neilb@suse.de \
    --cc=yur@emcraft.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox