[Devel] [PATCH RHEL7 COMMIT] ploop: fix barriers for ordinary requests
Konstantin Khorenko
khorenko at virtuozzo.com
Wed Jun 22 05:42:43 PDT 2016
The commit is pushed to "branch-rh7-3.10.0-327.18.2.vz7.14.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.18.2.vz7.14.17
------>
commit c2247f374581173c476bf88e82b9650ba263b37d
Author: Maxim Patlasov <mpatlasov at virtuozzo.com>
Date: Wed Jun 22 16:42:43 2016 +0400
ploop: fix barriers for ordinary requests
The way how io_direct.c handles FLUSH|FUA: b1:FLUSH,b2,b3,b4,b5:FLUSH|FUA
is completely wrong: to make sure that b1:FLUSH made effect we have to
wait for its completion. Similarly, even if we're sure that FUA will be
processed as post-FLUSH (also dubious!), we have to wait for completion
b1..b4 to make sure that that flush will cover them.
The patch fixes all these issues pretty simple: let's mark outgouing
bio-s with FLUSH|FUA based on those flags in *corresponing* incoming
bio-s.
Signed-off-by: Maxim Patlasov <mpatlasov at virtuozzo.com>
Acked-by: Dmitry Monakhov <dmonakhov at virtuozzo.com>
khorenko@:
v2 changes:
Drop 2 hunks like:
> - submit_bio(rw, b);
> + submit_bio(rw | b->bi_rw, b);
This is redundant ^^^^^^^^^^^^^
submit_bio looks like following:
void submit_bio(int rw, struct bio *bio)
{
bio->bi_rw |= rw;
...
---
drivers/block/ploop/dev.c | 1 -
drivers/block/ploop/io_direct.c | 43 +++++++++++++----------------------------
2 files changed, 13 insertions(+), 31 deletions(-)
diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index 2ef1449..6b5702f 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -498,7 +498,6 @@ ploop_bio_queue(struct ploop_device * plo, struct bio * bio,
preq->req_sector = bio->bi_sector;
preq->req_size = bio->bi_size >> 9;
preq->req_rw = bio->bi_rw;
- bio->bi_rw &= ~(REQ_FLUSH | REQ_FUA);
preq->eng_state = PLOOP_E_ENTRY;
preq->state = 0;
preq->error = 0;
diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c
index 6ef9cd8..50c0ed1 100644
--- a/drivers/block/ploop/io_direct.c
+++ b/drivers/block/ploop/io_direct.c
@@ -92,7 +92,6 @@ dio_submit(struct ploop_io *io, struct ploop_request * preq,
int preflush;
int postfua = 0;
int write = !!(rw & REQ_WRITE);
- int bio_num;
trace_submit(preq);
@@ -233,13 +232,13 @@ flush_bio:
goto flush_bio;
}
+ bio->bi_rw |= bw.cur->bi_rw & (REQ_FLUSH | REQ_FUA);
bw.bv_off += copy;
size -= copy >> 9;
sec += copy >> 9;
}
ploop_extent_put(em);
- bio_num = 0;
while (bl.head) {
struct bio * b = bl.head;
unsigned long rw2 = rw;
@@ -255,11 +254,10 @@ flush_bio:
preflush = 0;
}
if (unlikely(postfua && !bl.head))
- rw2 |= (REQ_FUA | ((bio_num) ? REQ_FLUSH : 0));
+ rw2 |= REQ_FUA;
ploop_acc_ff_out(preq->plo, rw2 | b->bi_rw);
submit_bio(rw2, b);
- bio_num++;
}
ploop_complete_io_request(preq);
@@ -567,7 +565,6 @@ dio_submit_pad(struct ploop_io *io, struct ploop_request * preq,
sector_t sec, end_sec, nsec, start, end;
struct bio_list_walk bw;
int err;
- int preflush = !!(preq->req_rw & REQ_FLUSH);
bio_list_init(&bl);
@@ -598,14 +595,17 @@ dio_submit_pad(struct ploop_io *io, struct ploop_request * preq,
while (sec < end_sec) {
struct page * page;
unsigned int poff, plen;
+ bool zero_page;
if (sec < start) {
+ zero_page = true;
page = ZERO_PAGE(0);
poff = 0;
plen = start - sec;
if (plen > (PAGE_SIZE>>9))
plen = (PAGE_SIZE>>9);
} else if (sec >= end) {
+ zero_page = true;
page = ZERO_PAGE(0);
poff = 0;
plen = end_sec - sec;
@@ -614,6 +614,7 @@ dio_submit_pad(struct ploop_io *io, struct ploop_request * preq,
} else {
/* sec >= start && sec < end */
struct bio_vec * bv;
+ zero_page = false;
if (sec == start) {
bw.cur = sbl->head;
@@ -672,6 +673,10 @@ flush_bio:
goto flush_bio;
}
+ /* Handle FLUSH here, dio_post_submit will handle FUA */
+ if (!zero_page)
+ bio->bi_rw |= bw.cur->bi_rw & REQ_FLUSH;
+
bw.bv_off += (plen<<9);
BUG_ON(plen == 0);
sec += plen;
@@ -688,11 +693,7 @@ flush_bio:
b->bi_private = preq;
b->bi_end_io = dio_endio_async;
- rw = sbl->head->bi_rw | WRITE;
- if (unlikely(preflush)) {
- rw |= REQ_FLUSH;
- preflush = 0;
- }
+ rw = preq->req_rw & ~(REQ_FLUSH | REQ_FUA);
ploop_acc_ff_out(preq->plo, rw | b->bi_rw);
submit_bio(rw, b);
}
@@ -1422,13 +1423,6 @@ dio_io_page(struct ploop_io * io, unsigned long rw,
sector_t nsec;
int err;
int off;
- int postfua;
- int bio_num;
- int preflush;
-
- preflush = !!(rw & REQ_FLUSH);
- postfua = !!(rw & REQ_FUA);
- rw &= ~(REQ_FUA|REQ_FLUSH);
bio_list_init(&bl);
bio = NULL;
@@ -1481,27 +1475,16 @@ flush_bio:
if (em)
ploop_extent_put(em);
- bio_num = 0;
while (bl.head) {
- unsigned long rw2 = rw;
struct bio * b = bl.head;
bl.head = b->bi_next;
- if (unlikely(preflush)) {
- rw2 |= REQ_FLUSH;
- preflush = 0;
- }
-
- if (unlikely(postfua && !bl.head))
- rw2 |= (REQ_FUA | ((bio_num) ? REQ_FLUSH : 0));
-
b->bi_next = NULL;
b->bi_end_io = dio_endio_async;
b->bi_private = preq;
atomic_inc(&preq->io_count);
- ploop_acc_ff_out(preq->plo, rw2 | b->bi_rw);
- submit_bio(rw2, b);
- bio_num++;
+ ploop_acc_ff_out(preq->plo, rw | b->bi_rw);
+ submit_bio(rw, b);
}
ploop_complete_io_request(preq);
More information about the Devel
mailing list