[Devel] [PATCH RHEL7 COMMIT] ploop: resurrect delay_fua for io_direct
Konstantin Khorenko
khorenko at virtuozzo.com
Mon Jun 27 00:10:24 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.20
------>
commit 38e947b588b7861189229abfadd8625d3ae8d6dd
Author: Maxim Patlasov <mpatlasov at virtuozzo.com>
Date: Mon Jun 27 11:10:24 2016 +0400
ploop: resurrect delay_fua for io_direct
Recent commit c2247f3745 while fixing barriers for ordinary
requests, accidentally smashed delay_fua optimization for
io_direct by:
> + bio->bi_rw |= bw.cur->bi_rw & (REQ_FLUSH | REQ_FUA);
The idea is the following: if at least one incoming bio is marked as
FUA (it is actually equivalent to (rw & REQ_FUA) check), and
eng_state == E_DATA_WBI, we can delay FUA until index update and
implement it there by REQ_FLUSH.
It is not clear if this optimization provides any benefits, but if
we lived with it for long so far, let's keep it for now.
The patch removes PLOOP_REQ_FORCE_FLUSH thoroughly because it's
easier to use REQ_FLUSH bit in preq->req_rw instead.
Signed-off-by: Maxim Patlasov <mpatlasov at virtuozzo.com>
Acked-by: Dmitry Monakhov <dmonakhov at virtuozzo.com>
---
drivers/block/ploop/io_direct.c | 15 ++++++---------
drivers/block/ploop/map.c | 25 ++++++++++++++++++-------
include/linux/ploop/ploop.h | 1 -
3 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c
index 77e2f0a..fdf7273 100644
--- a/drivers/block/ploop/io_direct.c
+++ b/drivers/block/ploop/io_direct.c
@@ -92,23 +92,19 @@ dio_submit(struct ploop_io *io, struct ploop_request * preq,
int preflush;
int postfua = 0;
int write = !!(rw & REQ_WRITE);
+ int delayed_fua = 0;
trace_submit(preq);
preflush = !!(rw & REQ_FLUSH);
- if (test_and_clear_bit(PLOOP_REQ_FORCE_FLUSH, &preq->state))
- preflush = 1;
-
if (test_and_clear_bit(PLOOP_REQ_FORCE_FUA, &preq->state))
postfua = 1;
- if (!postfua && ploop_req_delay_fua_possible(preq) && (rw & REQ_FUA)) {
-
+ if ((rw & REQ_FUA) && ploop_req_delay_fua_possible(preq)) {
/* Mark req that delayed flush required */
- set_bit(PLOOP_REQ_FORCE_FLUSH, &preq->state);
- } else if (rw & REQ_FUA) {
- postfua = 1;
+ preq->req_rw |= (REQ_FLUSH | REQ_FUA);
+ delayed_fua = 1;
}
rw &= ~(REQ_FLUSH | REQ_FUA);
@@ -223,7 +219,8 @@ flush_bio:
goto flush_bio;
}
- bio->bi_rw |= bw.cur->bi_rw & (REQ_FLUSH | REQ_FUA);
+ bio->bi_rw |= bw.cur->bi_rw &
+ (REQ_FLUSH | delayed_fua ? 0 : REQ_FUA);
bw.bv_off += copy;
size -= copy >> 9;
sec += copy >> 9;
diff --git a/drivers/block/ploop/map.c b/drivers/block/ploop/map.c
index ae6cc15..f87fb08 100644
--- a/drivers/block/ploop/map.c
+++ b/drivers/block/ploop/map.c
@@ -908,6 +908,7 @@ void ploop_index_update(struct ploop_request * preq)
int old_level;
struct page * page;
sector_t sec;
+ unsigned long rw;
/* No way back, we are going to initiate index write. */
@@ -965,8 +966,14 @@ void ploop_index_update(struct ploop_request * preq)
test_bit(PLOOP_REQ_RELOC_S, &preq->state))
set_bit(PLOOP_REQ_FORCE_FUA, &preq->state);
- top_delta->io.ops->write_page(&top_delta->io, preq, page, sec,
- preq->req_rw & REQ_FUA);
+ rw = (preq->req_rw & (REQ_FUA | REQ_FLUSH));
+
+ /* We've just set REQ_FLUSH in rw, ->write_page() below
+ will do the FLUSH */
+ preq->req_rw &= ~REQ_FLUSH;
+
+ top_delta->io.ops->write_page(&top_delta->io, preq, page, sec, rw);
+
put_page(page);
return;
@@ -1085,7 +1092,8 @@ static void map_wb_complete(struct map_node * m, int err)
int delayed = 0;
unsigned int idx;
sector_t sec;
- int fua, force_fua;
+ int force_fua;
+ unsigned long rw;
/* First, complete processing of written back indices,
* finally instantiate indices in mapping cache.
@@ -1155,7 +1163,7 @@ static void map_wb_complete(struct map_node * m, int err)
copy_index_for_wb(page, m, top_delta->level);
main_preq = NULL;
- fua = 0;
+ rw = 0;
force_fua = 0;
list_for_each_safe(cursor, tmp, &m->io_queue) {
@@ -1175,8 +1183,11 @@ static void map_wb_complete(struct map_node * m, int err)
break;
}
- if (preq->req_rw & REQ_FUA)
- fua = 1;
+ rw |= (preq->req_rw & (REQ_FLUSH | REQ_FUA));
+
+ /* We've just set REQ_FLUSH in rw, ->write_page() below
+ will do the FLUSH */
+ preq->req_rw &= ~REQ_FLUSH;
if (test_bit(PLOOP_REQ_RELOC_A, &preq->state) ||
test_bit(PLOOP_REQ_RELOC_S, &preq->state))
@@ -1211,7 +1222,7 @@ static void map_wb_complete(struct map_node * m, int err)
set_bit(PLOOP_REQ_FORCE_FUA, &main_preq->state);
top_delta->io.ops->write_page(&top_delta->io, main_preq, page, sec,
- fua ? REQ_FUA : 0);
+ rw);
put_page(page);
}
diff --git a/include/linux/ploop/ploop.h b/include/linux/ploop/ploop.h
index 3e53b35..af222f1 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -475,7 +475,6 @@ enum
PLOOP_REQ_DISCARD,
PLOOP_REQ_RSYNC,
PLOOP_REQ_FORCE_FUA, /*force fua of req write I/O by engine */
- PLOOP_REQ_FORCE_FLUSH, /*force flush by engine */
PLOOP_REQ_KAIO_FSYNC, /*force image fsync by KAIO module */
PLOOP_REQ_POST_SUBMIT, /* preq needs post_submit processing */
PLOOP_REQ_PUSH_BACKUP, /* preq was ACKed by userspace push_backup */
More information about the Devel
mailing list