[Devel] [PATCH RH8 14/22] ploop: Async md writeback
Kirill Tkhai
ktkhai at virtuozzo.com
Wed Jun 30 13:34:05 MSK 2021
Do not wait till md writeback completed.
https://jira.sw.ru/browse/PSBM-124550
Signed-off-by: Kirill Tkhai <ktkhai at 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;
More information about the Devel
mailing list