On Wed, May 20, 2009 at 1:08 AM, Andre Noll <maan@xxxxxxxxxxxxxxx> wrote: > On Mon, May 18, 2009 at 05:59:46PM -0700, Dan Williams wrote: > >> diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c >> @@ -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; > > Unnecessary cast as submit->scribble is void *. fixed. > >> @@ -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 { > > Don't we need to fall back to sync xor if src_cnt exceeds > what the device can handle, i.e. if it is larger than > chan->device->max_xor? async_xor_val() further down has a check for > this condition. No, we don't need this check for async_xor(). The asynchronous path of async_xor_val() has the constraint that it must be able to validate an xor block without writing to that block i.e. it is a read-only operation. The synchronous path recalculates the xor with the destination as a source and then does a memcmp() to validate that the new result is zero. To support more than ->max_xor sources for async_xor_val() we would need an engine that supported hardware continuation of validate operations (i.e. an engine with an internal buffer for the intermediate xor result) otherwise we will need to store an intermediate xor result in system memory which is no better than the synchronous path. For async_xor() we are always allowed to write the destination, so we can reuse it as a source to continue the calculation of the xor result. -- To unsubscribe from this list: send the line "unsubscribe linux-raid" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html