From: Artur Paszkiewicz Date: Tue, 4 Apr 2017 11:13:58 +0000 (+0200) Subject: raid5-ppl: partial parity calculation optimization X-Git-Tag: v4.12-rc1~121^2^2~21 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ae1713e296449caf820635d384a99936ce281a71;p=platform%2Fkernel%2Flinux-exynos.git raid5-ppl: partial parity calculation optimization In case of read-modify-write, partial partity is the same as the result of ops_run_prexor5(), so we can just copy sh->dev[pd_idx].page into sh->ppl_page instead of calculating it again. Signed-off-by: Artur Paszkiewicz Signed-off-by: Shaohua Li --- diff --git a/drivers/md/raid5-ppl.c b/drivers/md/raid5-ppl.c index 71968cf..4eb0ebc 100644 --- a/drivers/md/raid5-ppl.c +++ b/drivers/md/raid5-ppl.c @@ -153,7 +153,7 @@ ops_run_partial_parity(struct stripe_head *sh, struct raid5_percpu *percpu, struct dma_async_tx_descriptor *tx) { int disks = sh->disks; - struct page **xor_srcs = flex_array_get(percpu->scribble, 0); + struct page **srcs = flex_array_get(percpu->scribble, 0); int count = 0, pd_idx = sh->pd_idx, i; struct async_submit_ctl submit; @@ -166,18 +166,18 @@ ops_run_partial_parity(struct stripe_head *sh, struct raid5_percpu *percpu, * differently. */ if (sh->reconstruct_state == reconstruct_state_prexor_drain_run) { - /* rmw: xor old data and parity from updated disks */ - for (i = disks; i--;) { - struct r5dev *dev = &sh->dev[i]; - if (test_bit(R5_Wantdrain, &dev->flags) || i == pd_idx) - xor_srcs[count++] = dev->page; - } + /* + * rmw: xor old data and parity from updated disks + * This is calculated earlier by ops_run_prexor5() so just copy + * the parity dev page. + */ + srcs[count++] = sh->dev[pd_idx].page; } else if (sh->reconstruct_state == reconstruct_state_drain_run) { /* rcw: xor data from all not updated disks */ for (i = disks; i--;) { struct r5dev *dev = &sh->dev[i]; if (test_bit(R5_UPTODATE, &dev->flags)) - xor_srcs[count++] = dev->page; + srcs[count++] = dev->page; } } else { return tx; @@ -188,10 +188,10 @@ ops_run_partial_parity(struct stripe_head *sh, struct raid5_percpu *percpu, + sizeof(struct page *) * (sh->disks + 2)); if (count == 1) - tx = async_memcpy(sh->ppl_page, xor_srcs[0], 0, 0, PAGE_SIZE, + tx = async_memcpy(sh->ppl_page, srcs[0], 0, 0, PAGE_SIZE, &submit); else - tx = async_xor(sh->ppl_page, xor_srcs, 0, count, PAGE_SIZE, + tx = async_xor(sh->ppl_page, srcs, 0, count, PAGE_SIZE, &submit); return tx; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index e04d7b1..f3692ff 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -2079,9 +2079,6 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) async_tx_ack(tx); } - if (test_bit(STRIPE_OP_PARTIAL_PARITY, &ops_request)) - tx = ops_run_partial_parity(sh, percpu, tx); - if (test_bit(STRIPE_OP_PREXOR, &ops_request)) { if (level < 6) tx = ops_run_prexor5(sh, percpu, tx); @@ -2089,6 +2086,9 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) tx = ops_run_prexor6(sh, percpu, tx); } + if (test_bit(STRIPE_OP_PARTIAL_PARITY, &ops_request)) + tx = ops_run_partial_parity(sh, percpu, tx); + if (test_bit(STRIPE_OP_BIODRAIN, &ops_request)) { tx = ops_run_biodrain(sh, tx); overlap_clear++;