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 = ∁ /* 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 = ∁ 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