[Devel] [PATCH rh7 5/9] ploop: resurrect delay_fua for io_direct

Maxim Patlasov mpatlasov at virtuozzo.com
Thu Jun 23 22:40:20 PDT 2016


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>
---
 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 db82a61..1ea2008 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);
@@ -222,7 +218,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