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 <mpatla...@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 */

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to