Commit 5157b4aa5b7de8787b6318e61bcc285031bb9088

Authored by Dan Williams
Committed by Linus Torvalds
1 parent 7ebd467551

raid6: fix recovery performance regression

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: <stable@kernel.org>
Acked-by: NeilBrown <neilb@suse.de>
Reported-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 13 additions and 8 deletions Side-by-side Diff

crypto/async_tx/async_raid6_recov.c
... ... @@ -324,6 +324,7 @@
324 324 async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
325 325 struct page **blocks, struct async_submit_ctl *submit)
326 326 {
  327 + void *scribble = submit->scribble;
327 328 int non_zero_srcs, i;
328 329  
329 330 BUG_ON(faila == failb);
330 331  
... ... @@ -332,11 +333,13 @@
332 333  
333 334 pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes);
334 335  
335   - /* we need to preserve the contents of 'blocks' for the async
336   - * case, so punt to synchronous if a scribble buffer is not available
  336 + /* if a dma resource is not available or a scribble buffer is not
  337 + * available punt to the synchronous path. In the 'dma not
  338 + * available' case be sure to use the scribble buffer to
  339 + * preserve the content of 'blocks' as the caller intended.
337 340 */
338   - if (!submit->scribble) {
339   - void **ptrs = (void **) blocks;
  341 + if (!async_dma_find_channel(DMA_PQ) || !scribble) {
  342 + void **ptrs = scribble ? scribble : (void **) blocks;
340 343  
341 344 async_tx_quiesce(&submit->depend_tx);
342 345 for (i = 0; i < disks; i++)
343 346  
... ... @@ -406,11 +409,13 @@
406 409  
407 410 pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes);
408 411  
409   - /* we need to preserve the contents of 'blocks' for the async
410   - * case, so punt to synchronous if a scribble buffer is not available
  412 + /* if a dma resource is not available or a scribble buffer is not
  413 + * available punt to the synchronous path. In the 'dma not
  414 + * available' case be sure to use the scribble buffer to
  415 + * preserve the content of 'blocks' as the caller intended.
411 416 */
412   - if (!scribble) {
413   - void **ptrs = (void **) blocks;
  417 + if (!async_dma_find_channel(DMA_PQ) || !scribble) {
  418 + void **ptrs = scribble ? scribble : (void **) blocks;
414 419  
415 420 async_tx_quiesce(&submit->depend_tx);
416 421 for (i = 0; i < disks; i++)