Skip to content

Commit

Permalink
raid6: fix recovery performance regression
Browse files Browse the repository at this point in the history
The raid6 recovery code should immediately drop back to the optimized
synchronous path when a p+q dma resource is not available.  Otherwise we
run the non-optimized/multi-pass async code in sync mode.

Verified with raid6test (NDISKS=255)

Applies to kernels >= 2.6.32.

Cc: <[email protected]>
Acked-by: NeilBrown <[email protected]>
Reported-by: H. Peter Anvin <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
djbw authored and torvalds committed May 5, 2010
1 parent 7ebd467 commit 5157b4a
Showing 1 changed file with 13 additions and 8 deletions.
21 changes: 13 additions & 8 deletions crypto/async_tx/async_raid6_recov.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ struct dma_async_tx_descriptor *
async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
struct page **blocks, struct async_submit_ctl *submit)
{
void *scribble = submit->scribble;
int non_zero_srcs, i;

BUG_ON(faila == failb);
Expand All @@ -332,11 +333,13 @@ async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,

pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes);

/* we need to preserve the contents of 'blocks' for the async
* case, so punt to synchronous if a scribble buffer is not available
/* if a dma resource is not available or a scribble buffer is not
* available punt to the synchronous path. In the 'dma not
* available' case be sure to use the scribble buffer to
* preserve the content of 'blocks' as the caller intended.
*/
if (!submit->scribble) {
void **ptrs = (void **) blocks;
if (!async_dma_find_channel(DMA_PQ) || !scribble) {
void **ptrs = scribble ? scribble : (void **) blocks;

async_tx_quiesce(&submit->depend_tx);
for (i = 0; i < disks; i++)
Expand Down Expand Up @@ -406,11 +409,13 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila,

pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes);

/* we need to preserve the contents of 'blocks' for the async
* case, so punt to synchronous if a scribble buffer is not available
/* if a dma resource is not available or a scribble buffer is not
* available punt to the synchronous path. In the 'dma not
* available' case be sure to use the scribble buffer to
* preserve the content of 'blocks' as the caller intended.
*/
if (!scribble) {
void **ptrs = (void **) blocks;
if (!async_dma_find_channel(DMA_PQ) || !scribble) {
void **ptrs = scribble ? scribble : (void **) blocks;

async_tx_quiesce(&submit->depend_tx);
for (i = 0; i < disks; i++)
Expand Down

0 comments on commit 5157b4a

Please sign in to comment.