[Devel] [PATCH RH8 07/22] ploop: Introduce batch list for md pages writeback
Kirill Tkhai
ktkhai at virtuozzo.com
Wed Jun 30 13:33:28 MSK 2021
Every iteration of do_ploop_work collects changes
to md pages. On the end of work we submit all of
the md pages writeback in parallel.
https://jira.sw.ru/browse/PSBM-124550
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
drivers/md/dm-ploop-bat.c | 2 +
drivers/md/dm-ploop-cmd.c | 9 +++++++
drivers/md/dm-ploop-map.c | 57 ++++++++++++++++++++++++++++++++++++++----
drivers/md/dm-ploop-target.c | 1 +
drivers/md/dm-ploop.h | 7 +++++
5 files changed, 71 insertions(+), 5 deletions(-)
diff --git a/drivers/md/dm-ploop-bat.c b/drivers/md/dm-ploop-bat.c
index b445663c8be6..ad9c3a171dc9 100644
--- a/drivers/md/dm-ploop-bat.c
+++ b/drivers/md/dm-ploop-bat.c
@@ -79,7 +79,9 @@ static struct md_page * alloc_md_page(unsigned int id)
if (!page)
goto err_page;
INIT_LIST_HEAD(&md->wait_list);
+ INIT_LIST_HEAD(&md->wb_link);
+ md->status = 0;
md->bat_levels = levels;
md->piwb = NULL;
md->page = page;
diff --git a/drivers/md/dm-ploop-cmd.c b/drivers/md/dm-ploop-cmd.c
index bf9e2c04138a..183524f61243 100644
--- a/drivers/md/dm-ploop-cmd.c
+++ b/drivers/md/dm-ploop-cmd.c
@@ -266,6 +266,13 @@ static int ploop_write_zero_cluster_sync(struct ploop *ploop,
return ploop_write_cluster_sync(ploop, pio, clu);
}
+static void ploop_make_md_wb(struct ploop *ploop, struct md_page *md)
+{
+ write_lock_irq(&ploop->bat_rwlock);
+ md->status |= MD_WRITEBACK;
+ write_unlock_irq(&ploop->bat_rwlock);
+}
+
static int ploop_grow_relocate_cluster(struct ploop *ploop,
struct ploop_index_wb *piwb,
struct ploop_cmd *cmd)
@@ -308,6 +315,7 @@ static int ploop_grow_relocate_cluster(struct ploop *ploop,
goto out;
}
+ ploop_make_md_wb(ploop, piwb->md);
/* Write new index on disk */
ploop_submit_index_wb_sync(ploop, piwb);
ret = blk_status_to_errno(piwb->bi_status);
@@ -360,6 +368,7 @@ static int ploop_grow_update_header(struct ploop *ploop,
offset = hdr->m_FirstBlockOffset = cpu_to_le32(first_block_off);
kunmap_atomic(hdr);
+ ploop_make_md_wb(ploop, piwb->md);
ploop_submit_index_wb_sync(ploop, piwb);
ret = blk_status_to_errno(piwb->bi_status);
if (!ret) {
diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index 877e29226a45..d91baef66973 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -463,6 +463,23 @@ static void unlink_completed_pio(struct ploop *ploop, struct pio *pio)
dispatch_pios(ploop, NULL, &pio_list);
}
+static bool ploop_md_make_dirty(struct ploop *ploop, struct md_page *md)
+{
+ unsigned long flags;
+ bool new = false;
+
+ write_lock_irqsave(&ploop->bat_rwlock, flags);
+ WARN_ON_ONCE((md->status & MD_WRITEBACK));
+ if (!(md->status & MD_DIRTY)) {
+ md->status |= MD_DIRTY;
+ list_add_tail(&md->wb_link, &ploop->wb_batch_list);
+ new = true;
+ }
+ write_unlock_irqrestore(&ploop->bat_rwlock, flags);
+
+ return new;
+}
+
static bool pio_endio_if_all_zeros(struct pio *pio)
{
struct bvec_iter bi = {
@@ -695,6 +712,8 @@ static void ploop_advance_local_after_bat_wb(struct ploop *ploop,
}
}
+ WARN_ON_ONCE(!(md->status & MD_WRITEBACK));
+ md->status &= ~MD_WRITEBACK;
list_splice_tail_init(&md->wait_list, &list);
write_unlock_irqrestore(&ploop->bat_rwlock, flags);
kunmap_atomic(dst_clu);
@@ -1259,6 +1278,7 @@ static void submit_cow_index_wb(struct ploop_cow *cow,
/* No index wb in process. Prepare a new one */
if (ploop_prepare_bat_update(ploop, page_id, piwb, PIWB_TYPE_ALLOC) < 0)
goto err_resource;
+ ploop_md_make_dirty(ploop, md);
}
clu -= page_id * PAGE_SIZE / sizeof(map_index_t) - PLOOP_MAP_OFFSET;
@@ -1354,6 +1374,9 @@ static bool locate_new_cluster_and_attach_pio(struct ploop *ploop,
goto error;
}
+ if (bat_update_prepared)
+ ploop_md_make_dirty(ploop, md);
+
ploop_attach_end_action(pio, piwb);
attached = true;
out:
@@ -1497,6 +1520,9 @@ static void process_one_discard_pio(struct ploop *ploop, struct pio *pio,
list_add_tail(&pio->list, &piwb->ready_data_pios);
}
kunmap_atomic(to);
+
+ if (bat_update_prepared)
+ ploop_md_make_dirty(ploop, md);
out:
return;
err:
@@ -1524,6 +1550,31 @@ static void process_resubmit_pios(struct ploop *ploop, struct list_head *pios)
}
}
+static void submit_metadata_writeback(struct ploop *ploop)
+{
+ struct md_page *md;
+
+ while (1) {
+ write_lock_irq(&ploop->bat_rwlock);
+ md = list_first_entry_or_null(&ploop->wb_batch_list,
+ struct md_page, wb_link);
+ if (!md) {
+ write_unlock_irq(&ploop->bat_rwlock);
+ break;
+ }
+ list_del_init(&md->wb_link);
+ /* L1L2 mustn't be redirtyed, when wb in-flight! */
+ WARN_ON_ONCE(!(md->status & MD_DIRTY) ||
+ (md->status & MD_WRITEBACK));
+ md->status |= MD_WRITEBACK;
+ md->status &= ~MD_DIRTY;
+ write_unlock_irq(&ploop->bat_rwlock);
+
+ ploop_submit_index_wb_sync(ploop, md->piwb);
+ ploop_reset_bat_update(md->piwb);
+ }
+}
+
void do_ploop_work(struct work_struct *ws)
{
struct ploop *ploop = container_of(ws, struct ploop, worker);
@@ -1555,11 +1606,7 @@ void do_ploop_work(struct work_struct *ws)
process_discard_pios(ploop, &discard_pios, &piwb);
process_delta_wb(ploop, &cow_pios, &piwb);
- if (piwb.page_id != PAGE_NR_NONE) {
- /* Index wb was prepared -- submit and wait it */
- ploop_submit_index_wb_sync(ploop, &piwb);
- ploop_reset_bat_update(&piwb);
- }
+ submit_metadata_writeback(ploop);
current->flags = (current->flags & ~PF_IO_THREAD) | pf_io_thread;
}
diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c
index d4413ff259a5..705f2252e822 100644
--- a/drivers/md/dm-ploop-target.c
+++ b/drivers/md/dm-ploop-target.c
@@ -334,6 +334,7 @@ static int ploop_ctr(struct dm_target *ti, unsigned int argc, char **argv)
INIT_LIST_HEAD(&ploop->resubmit_pios);
INIT_LIST_HEAD(&ploop->enospc_pios);
INIT_LIST_HEAD(&ploop->cluster_lk_list);
+ INIT_LIST_HEAD(&ploop->wb_batch_list);
ploop->bat_entries = RB_ROOT;
timer_setup(&ploop->enospc_timer, ploop_enospc_timer, 0);
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index 879d7c5b25e7..babdfdb7f672 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -110,9 +110,14 @@ struct ploop_index_wb {
struct md_page {
struct rb_node node;
unsigned int id; /* Number of this page starting from hdr */
+#define MD_DIRTY (1U << 1) /* Page contains changes and wants writeback */
+#define MD_WRITEBACK (1U << 2) /* Writeback was submitted */
+ unsigned int status;
struct page *page;
u8 *bat_levels;
struct list_head wait_list;
+
+ struct list_head wb_link;
struct ploop_index_wb *piwb;
};
@@ -146,6 +151,8 @@ struct ploop {
unsigned int hb_nr; /* holes_bitmap size in bits */
rwlock_t bat_rwlock;
+ struct list_head wb_batch_list;
+
void *tracking_bitmap;
unsigned int tb_nr; /* tracking_bitmap size in bits */
unsigned int tb_cursor;
More information about the Devel
mailing list