aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid5.c59
1 files changed, 34 insertions, 25 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 0ef5362c8d02..e1920f23579f 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -499,11 +499,14 @@ async_copy_data(int frombio, struct bio *bio, struct page *page,
499 struct page *bio_page; 499 struct page *bio_page;
500 int i; 500 int i;
501 int page_offset; 501 int page_offset;
502 struct async_submit_ctl submit;
502 503
503 if (bio->bi_sector >= sector) 504 if (bio->bi_sector >= sector)
504 page_offset = (signed)(bio->bi_sector - sector) * 512; 505 page_offset = (signed)(bio->bi_sector - sector) * 512;
505 else 506 else
506 page_offset = (signed)(sector - bio->bi_sector) * -512; 507 page_offset = (signed)(sector - bio->bi_sector) * -512;
508
509 init_async_submit(&submit, 0, tx, NULL, NULL, NULL);
507 bio_for_each_segment(bvl, bio, i) { 510 bio_for_each_segment(bvl, bio, i) {
508 int len = bio_iovec_idx(bio, i)->bv_len; 511 int len = bio_iovec_idx(bio, i)->bv_len;
509 int clen; 512 int clen;
@@ -525,13 +528,14 @@ async_copy_data(int frombio, struct bio *bio, struct page *page,
525 bio_page = bio_iovec_idx(bio, i)->bv_page; 528 bio_page = bio_iovec_idx(bio, i)->bv_page;
526 if (frombio) 529 if (frombio)
527 tx = async_memcpy(page, bio_page, page_offset, 530 tx = async_memcpy(page, bio_page, page_offset,
528 b_offset, clen, 0, 531 b_offset, clen, &submit);
529 tx, NULL, NULL);
530 else 532 else
531 tx = async_memcpy(bio_page, page, b_offset, 533 tx = async_memcpy(bio_page, page, b_offset,
532 page_offset, clen, 0, 534 page_offset, clen, &submit);
533 tx, NULL, NULL);
534 } 535 }
536 /* chain the operations */
537 submit.depend_tx = tx;
538
535 if (clen < len) /* hit end of page */ 539 if (clen < len) /* hit end of page */
536 break; 540 break;
537 page_offset += len; 541 page_offset += len;
@@ -590,6 +594,7 @@ static void ops_run_biofill(struct stripe_head *sh)
590{ 594{
591 struct dma_async_tx_descriptor *tx = NULL; 595 struct dma_async_tx_descriptor *tx = NULL;
592 raid5_conf_t *conf = sh->raid_conf; 596 raid5_conf_t *conf = sh->raid_conf;
597 struct async_submit_ctl submit;
593 int i; 598 int i;
594 599
595 pr_debug("%s: stripe %llu\n", __func__, 600 pr_debug("%s: stripe %llu\n", __func__,
@@ -613,7 +618,8 @@ static void ops_run_biofill(struct stripe_head *sh)
613 } 618 }
614 619
615 atomic_inc(&sh->count); 620 atomic_inc(&sh->count);
616 async_trigger_callback(ASYNC_TX_ACK, tx, ops_complete_biofill, sh); 621 init_async_submit(&submit, ASYNC_TX_ACK, tx, ops_complete_biofill, sh, NULL);
622 async_trigger_callback(&submit);
617} 623}
618 624
619static void ops_complete_compute5(void *stripe_head_ref) 625static void ops_complete_compute5(void *stripe_head_ref)
@@ -645,6 +651,7 @@ static struct dma_async_tx_descriptor *ops_run_compute5(struct stripe_head *sh)
645 struct page *xor_dest = tgt->page; 651 struct page *xor_dest = tgt->page;
646 int count = 0; 652 int count = 0;
647 struct dma_async_tx_descriptor *tx; 653 struct dma_async_tx_descriptor *tx;
654 struct async_submit_ctl submit;
648 int i; 655 int i;
649 656
650 pr_debug("%s: stripe %llu block: %d\n", 657 pr_debug("%s: stripe %llu block: %d\n",
@@ -657,13 +664,12 @@ static struct dma_async_tx_descriptor *ops_run_compute5(struct stripe_head *sh)
657 664
658 atomic_inc(&sh->count); 665 atomic_inc(&sh->count);
659 666
667 init_async_submit(&submit, ASYNC_TX_XOR_ZERO_DST, NULL,
668 ops_complete_compute5, sh, NULL);
660 if (unlikely(count == 1)) 669 if (unlikely(count == 1))
661 tx = async_memcpy(xor_dest, xor_srcs[0], 0, 0, STRIPE_SIZE, 670 tx = async_memcpy(xor_dest, xor_srcs[0], 0, 0, STRIPE_SIZE, &submit);
662 0, NULL, ops_complete_compute5, sh);
663 else 671 else
664 tx = async_xor(xor_dest, xor_srcs, 0, count, STRIPE_SIZE, 672 tx = async_xor(xor_dest, xor_srcs, 0, count, STRIPE_SIZE, &submit);
665 ASYNC_TX_XOR_ZERO_DST, NULL,
666 ops_complete_compute5, sh);
667 673
668 return tx; 674 return tx;
669} 675}
@@ -683,6 +689,7 @@ ops_run_prexor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
683 int disks = sh->disks; 689 int disks = sh->disks;
684 struct page *xor_srcs[disks]; 690 struct page *xor_srcs[disks];
685 int count = 0, pd_idx = sh->pd_idx, i; 691 int count = 0, pd_idx = sh->pd_idx, i;
692 struct async_submit_ctl submit;
686 693
687 /* existing parity data subtracted */ 694 /* existing parity data subtracted */
688 struct page *xor_dest = xor_srcs[count++] = sh->dev[pd_idx].page; 695 struct page *xor_dest = xor_srcs[count++] = sh->dev[pd_idx].page;
@@ -697,9 +704,9 @@ ops_run_prexor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
697 xor_srcs[count++] = dev->page; 704 xor_srcs[count++] = dev->page;
698 } 705 }
699 706
700 tx = async_xor(xor_dest, xor_srcs, 0, count, STRIPE_SIZE, 707 init_async_submit(&submit, ASYNC_TX_XOR_DROP_DST, tx,
701 ASYNC_TX_XOR_DROP_DST, tx, 708 ops_complete_prexor, sh, NULL);
702 ops_complete_prexor, sh); 709 tx = async_xor(xor_dest, xor_srcs, 0, count, STRIPE_SIZE, &submit);
703 710
704 return tx; 711 return tx;
705} 712}
@@ -772,7 +779,7 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
772 /* kernel stack size limits the total number of disks */ 779 /* kernel stack size limits the total number of disks */
773 int disks = sh->disks; 780 int disks = sh->disks;
774 struct page *xor_srcs[disks]; 781 struct page *xor_srcs[disks];
775 782 struct async_submit_ctl submit;
776 int count = 0, pd_idx = sh->pd_idx, i; 783 int count = 0, pd_idx = sh->pd_idx, i;
777 struct page *xor_dest; 784 struct page *xor_dest;
778 int prexor = 0; 785 int prexor = 0;
@@ -811,13 +818,11 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
811 818
812 atomic_inc(&sh->count); 819 atomic_inc(&sh->count);
813 820
814 if (unlikely(count == 1)) { 821 init_async_submit(&submit, flags, tx, ops_complete_postxor, sh, NULL);
815 flags &= ~(ASYNC_TX_XOR_DROP_DST | ASYNC_TX_XOR_ZERO_DST); 822 if (unlikely(count == 1))
816 tx = async_memcpy(xor_dest, xor_srcs[0], 0, 0, STRIPE_SIZE, 823 tx = async_memcpy(xor_dest, xor_srcs[0], 0, 0, STRIPE_SIZE, &submit);
817 flags, tx, ops_complete_postxor, sh); 824 else
818 } else 825 tx = async_xor(xor_dest, xor_srcs, 0, count, STRIPE_SIZE, &submit);
819 tx = async_xor(xor_dest, xor_srcs, 0, count, STRIPE_SIZE,
820 flags, tx, ops_complete_postxor, sh);
821} 826}
822 827
823static void ops_complete_check(void *stripe_head_ref) 828static void ops_complete_check(void *stripe_head_ref)
@@ -838,6 +843,7 @@ static void ops_run_check(struct stripe_head *sh)
838 int disks = sh->disks; 843 int disks = sh->disks;
839 struct page *xor_srcs[disks]; 844 struct page *xor_srcs[disks];
840 struct dma_async_tx_descriptor *tx; 845 struct dma_async_tx_descriptor *tx;
846 struct async_submit_ctl submit;
841 847
842 int count = 0, pd_idx = sh->pd_idx, i; 848 int count = 0, pd_idx = sh->pd_idx, i;
843 struct page *xor_dest = xor_srcs[count++] = sh->dev[pd_idx].page; 849 struct page *xor_dest = xor_srcs[count++] = sh->dev[pd_idx].page;
@@ -851,12 +857,13 @@ static void ops_run_check(struct stripe_head *sh)
851 xor_srcs[count++] = dev->page; 857 xor_srcs[count++] = dev->page;
852 } 858 }
853 859
860 init_async_submit(&submit, 0, NULL, NULL, NULL, NULL);
854 tx = async_xor_val(xor_dest, xor_srcs, 0, count, STRIPE_SIZE, 861 tx = async_xor_val(xor_dest, xor_srcs, 0, count, STRIPE_SIZE,
855 &sh->ops.zero_sum_result, 0, NULL, NULL, NULL); 862 &sh->ops.zero_sum_result, &submit);
856 863
857 atomic_inc(&sh->count); 864 atomic_inc(&sh->count);
858 tx = async_trigger_callback(ASYNC_TX_ACK, tx, 865 init_async_submit(&submit, ASYNC_TX_ACK, tx, ops_complete_check, sh, NULL);
859 ops_complete_check, sh); 866 tx = async_trigger_callback(&submit);
860} 867}
861 868
862static void raid5_run_ops(struct stripe_head *sh, unsigned long ops_request) 869static void raid5_run_ops(struct stripe_head *sh, unsigned long ops_request)
@@ -2664,6 +2671,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh,
2664 if (i != sh->pd_idx && i != sh->qd_idx) { 2671 if (i != sh->pd_idx && i != sh->qd_idx) {
2665 int dd_idx, j; 2672 int dd_idx, j;
2666 struct stripe_head *sh2; 2673 struct stripe_head *sh2;
2674 struct async_submit_ctl submit;
2667 2675
2668 sector_t bn = compute_blocknr(sh, i, 1); 2676 sector_t bn = compute_blocknr(sh, i, 1);
2669 sector_t s = raid5_compute_sector(conf, bn, 0, 2677 sector_t s = raid5_compute_sector(conf, bn, 0,
@@ -2683,9 +2691,10 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh,
2683 } 2691 }
2684 2692
2685 /* place all the copies on one channel */ 2693 /* place all the copies on one channel */
2694 init_async_submit(&submit, 0, tx, NULL, NULL, NULL);
2686 tx = async_memcpy(sh2->dev[dd_idx].page, 2695 tx = async_memcpy(sh2->dev[dd_idx].page,
2687 sh->dev[i].page, 0, 0, STRIPE_SIZE, 2696 sh->dev[i].page, 0, 0, STRIPE_SIZE,
2688 0, tx, NULL, NULL); 2697 &submit);
2689 2698
2690 set_bit(R5_Expanded, &sh2->dev[dd_idx].flags); 2699 set_bit(R5_Expanded, &sh2->dev[dd_idx].flags);
2691 set_bit(R5_UPTODATE, &sh2->dev[dd_idx].flags); 2700 set_bit(R5_UPTODATE, &sh2->dev[dd_idx].flags);