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 <artur.paszkiewicz@intel.com>
Signed-off-by: Shaohua Li <shli@fb.com>
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 @@
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 @@
* 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 @@
+ 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 @@
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 @@
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++;