Do not wait till md writeback completed.

https://jira.sw.ru/browse/PSBM-124550

Signed-off-by: Kirill Tkhai <ktk...@virtuozzo.com>
---
 drivers/md/dm-ploop-cmd.c |   12 +++++++-
 drivers/md/dm-ploop-map.c |   66 +++++++++++++++++++++++++++++++--------------
 drivers/md/dm-ploop.h     |    3 +-
 3 files changed, 57 insertions(+), 24 deletions(-)

diff --git a/drivers/md/dm-ploop-cmd.c b/drivers/md/dm-ploop-cmd.c
index 8f2e76c0e1a8..7a5012bbe2fb 100644
--- a/drivers/md/dm-ploop-cmd.c
+++ b/drivers/md/dm-ploop-cmd.c
@@ -279,6 +279,7 @@ static int ploop_grow_relocate_cluster(struct ploop *ploop,
        unsigned int new_dst, clu, dst_clu;
        struct pio *pio = cmd->resize.pio;
        struct ploop_index_wb *piwb;
+       struct completion comp;
        struct md_page *md;
        bool is_locked;
        int ret = 0;
@@ -317,10 +318,13 @@ static int ploop_grow_relocate_cluster(struct ploop 
*ploop,
        }
 
        ploop_make_md_wb(ploop, md);
+       init_completion(&comp);
+       piwb->comp = &comp;
        /* Write new index on disk */
        ploop_submit_index_wb_sync(ploop, piwb);
+       wait_for_completion(&comp);
+
        ret = blk_status_to_errno(piwb->bi_status);
-       ploop_break_bat_update(ploop, md);
        if (ret)
                goto out;
 
@@ -349,6 +353,7 @@ static int ploop_grow_update_header(struct ploop *ploop,
        struct ploop_pvd_header *hdr;
        struct ploop_index_wb *piwb;
        u32 nr_be, offset, clus;
+       struct completion comp;
        struct md_page *md;
        u64 sectors;
        int ret;
@@ -372,7 +377,11 @@ static int ploop_grow_update_header(struct ploop *ploop,
        kunmap_atomic(hdr);
 
        ploop_make_md_wb(ploop, md);
+       init_completion(&comp);
+       piwb->comp = &comp;
        ploop_submit_index_wb_sync(ploop, piwb);
+       wait_for_completion(&comp);
+
        ret = blk_status_to_errno(piwb->bi_status);
        if (!ret) {
                /* Now update our cached page */
@@ -383,7 +392,6 @@ static int ploop_grow_update_header(struct ploop *ploop,
                kunmap_atomic(hdr);
        }
 
-       ploop_break_bat_update(ploop, md);
        return ret;
 }
 
diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index 2c71ed501236..319acfa831eb 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -42,7 +42,7 @@ static unsigned int pio_nr_segs(struct pio *pio)
 void ploop_index_wb_init(struct ploop_index_wb *piwb, struct ploop *ploop)
 {
        piwb->ploop = ploop;
-       init_completion(&piwb->comp);
+       piwb->comp = NULL;
        spin_lock_init(&piwb->lock);
        piwb->md = NULL;
        piwb->bat_page = NULL;
@@ -716,6 +716,7 @@ static void ploop_advance_local_after_bat_wb(struct ploop 
*ploop,
 
        WARN_ON_ONCE(!(md->status & MD_WRITEBACK));
        md->status &= ~MD_WRITEBACK;
+       md->piwb = NULL;
        list_splice_tail_init(&md->wait_list, &list);
        write_unlock_irqrestore(&ploop->bat_rwlock, flags);
        kunmap_atomic(dst_clu);
@@ -725,6 +726,13 @@ static void ploop_advance_local_after_bat_wb(struct ploop 
*ploop,
                dispatch_pios(ploop, NULL, &list);
 }
 
+static void free_piwb(struct ploop_index_wb *piwb)
+{
+       kfree(piwb->pio);
+       put_page(piwb->bat_page);
+       kfree(piwb);
+}
+
 static void put_piwb(struct ploop_index_wb *piwb)
 {
        if (atomic_dec_and_test(&piwb->count)) {
@@ -736,7 +744,9 @@ static void put_piwb(struct ploop_index_wb *piwb)
                if (piwb->bi_status)
                        ploop_advance_local_after_bat_wb(ploop, piwb, false);
 
-               complete(&piwb->comp);
+               if (piwb->comp)
+                       complete(piwb->comp);
+               free_piwb(piwb);
        }
 }
 
@@ -797,6 +807,7 @@ static int ploop_prepare_bat_update(struct ploop *ploop, 
struct md_page *md,
        bool is_last_page = true;
        u32 page_id = md->id;
        struct page *page;
+       struct pio *pio;
        map_index_t *to;
 
        piwb = kmalloc(sizeof(*piwb), GFP_NOIO);
@@ -805,8 +816,10 @@ static int ploop_prepare_bat_update(struct ploop *ploop, 
struct md_page *md,
        ploop_index_wb_init(piwb, ploop);
 
        piwb->bat_page = page = alloc_page(GFP_NOIO);
-       if (!page)
+       piwb->pio = pio = kmalloc(sizeof(*pio), GFP_NOIO);
+       if (!page || !pio)
                goto err;
+       init_pio(ploop, REQ_OP_WRITE, pio);
 
        bat_entries = kmap_atomic(md->page);
 
@@ -851,7 +864,7 @@ static int ploop_prepare_bat_update(struct ploop *ploop, 
struct md_page *md,
        piwb->type = type;
        return 0;
 err:
-       kfree(piwb);
+       free_piwb(piwb);
        return -ENOMEM;
 }
 
@@ -862,12 +875,10 @@ void ploop_break_bat_update(struct ploop *ploop, struct 
md_page *md)
 
        write_lock_irqsave(&ploop->bat_rwlock, flags);
        piwb = md->piwb;
-       md->piwb->md = NULL;
        md->piwb = NULL;
        write_unlock_irqrestore(&ploop->bat_rwlock, flags);
 
-       put_page(piwb->bat_page);
-       kfree(piwb);
+       free_piwb(piwb);
 }
 
 static void ploop_bat_page_zero_cluster(struct ploop *ploop,
@@ -1466,25 +1477,39 @@ static int process_one_deferred_bio(struct ploop 
*ploop, struct pio *pio)
        return 0;
 }
 
-void ploop_submit_index_wb_sync(struct ploop *ploop,
-                               struct ploop_index_wb *piwb)
+static void md_write_endio(struct pio *pio, void *piwb_ptr, blk_status_t 
bi_status)
 {
-       blk_status_t status = BLK_STS_OK;
+       struct ploop_index_wb *piwb = piwb_ptr;
+       struct ploop *ploop = piwb->ploop;
        u32 dst_clu;
-       int ret;
 
-       /* track_bio() will be called in ploop_bat_write_complete() */
+       dst_clu = POS_TO_CLU(ploop, (u64)piwb->page_id << PAGE_SHIFT);
+       track_dst_cluster(ploop, dst_clu);
 
-       ret = ploop_rw_page_sync(WRITE, top_delta(ploop)->file,
-                                piwb->page_id, piwb->bat_page);
-       if (ret)
-               status = errno_to_blk_status(ret);
+       ploop_bat_write_complete(piwb, bi_status);
+}
 
-       dst_clu = ((u64)piwb->page_id << PAGE_SHIFT) / CLU_SIZE(ploop);
-       track_dst_cluster(ploop, dst_clu);
+void ploop_submit_index_wb_sync(struct ploop *ploop,
+                               struct ploop_index_wb *piwb)
+{
+       loff_t pos = (loff_t)piwb->page_id << PAGE_SHIFT;
+       struct pio *pio = piwb->pio;
+       struct bio_vec bvec = {
+               .bv_page = piwb->bat_page,
+               .bv_len = PAGE_SIZE,
+               .bv_offset = 0,
+       };
 
-       ploop_bat_write_complete(piwb, status);
-       wait_for_completion(&piwb->comp);
+       pio->bi_iter.bi_sector = to_sector(pos);
+       pio->bi_iter.bi_size = PAGE_SIZE;
+       pio->bi_iter.bi_idx = 0;
+       pio->bi_iter.bi_bvec_done = 0;
+       pio->bi_io_vec = &bvec;
+       pio->level = top_level(ploop);
+       pio->endio_cb = md_write_endio;
+       pio->endio_cb_data = piwb;
+
+       submit_rw_mapped(ploop, pio);
 }
 
 static void process_deferred_pios(struct ploop *ploop, struct list_head *pios)
@@ -1584,7 +1609,6 @@ static void submit_metadata_writeback(struct ploop *ploop)
                write_unlock_irq(&ploop->bat_rwlock);
 
                ploop_submit_index_wb_sync(ploop, md->piwb);
-               ploop_break_bat_update(ploop, md);
        }
 }
 
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index 1b76e74b60b7..1634ba8fc5da 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -93,10 +93,11 @@ enum piwb_type {
 
 struct ploop_index_wb {
        struct ploop *ploop;
-       struct completion comp;
+       struct completion *comp;
        enum piwb_type type;
        spinlock_t lock;
        struct md_page *md;
+       struct pio *pio;
        struct page *bat_page;
        struct list_head ready_data_pios;
        struct list_head cow_list;


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

Reply via email to