[Devel] [PATCH RHEL8 COMMIT] ploop: Delay bio if md page is BUSY

Konstantin Khorenko khorenko at virtuozzo.com
Tue Jun 29 16:08:18 MSK 2021


The commit is pushed to "branch-rh8-4.18.0-240.1.1.vz8.5.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-240.1.1.vz8.5.50
------>
commit 46a6e184a006d45698cc8fd18dfe216e51004f1e
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date:   Tue Jun 29 16:08:18 2021 +0300

    ploop: Delay bio if md page is BUSY
    
    This is preparation for #PSBM-124550.
    
    We want to make md write async. This patch
    introduces dependencies between md page and
    pio wanted for wb finish.
    
    Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
    
    ==========================
    Preparation for #PSBM-124550 (part 2)
    
    Kirill Tkhai (14):
          ploop: Kill "get_delta_name" alias
          ploop: Use initial pio for COW
          ploop: Rename cluster_pio into aux_pio
          ploop: Shorten variable names
          ploop: Rename in submit_cluster_write()
          ploop: Use defer_pios() instead of manual code
          ploop: Use array of pios instead of separate lists
          ploop: Generalize dispatch_pios usage
          ploop: Unify process_delta_wb()
          ploop: Remove unused struct member
          ploop: Rename page_nr
          ploop: Return md page from ploop_bat_entries()
          ploop: Kill dead check in ploop_attach_end_action()
          ploop: Delay bio if md page is BUSY
---
 drivers/md/dm-ploop-bat.c |  1 +
 drivers/md/dm-ploop-map.c | 53 +++++++++++++++++++++++++++--------------------
 drivers/md/dm-ploop.h     |  1 +
 3 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/drivers/md/dm-ploop-bat.c b/drivers/md/dm-ploop-bat.c
index df3f81c4ebd9..602842b2440c 100644
--- a/drivers/md/dm-ploop-bat.c
+++ b/drivers/md/dm-ploop-bat.c
@@ -78,6 +78,7 @@ static struct md_page * alloc_md_page(unsigned int id)
 	page = alloc_page(GFP_KERNEL);
 	if (!page)
 		goto err_page;
+	INIT_LIST_HEAD(&md->wait_list);
 
 	md->bat_levels = levels;
 	md->page = page;
diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index ab23e10ead6b..cab9dea72fd8 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -23,22 +23,6 @@ static void handle_cleanup(struct ploop *ploop, struct pio *pio);
 
 #define DM_MSG_PREFIX "ploop"
 
-#define ploop_bat_lock(ploop, exclusive, flags)					\
-	do {									\
-		if (exclusive)							\
-			write_lock_irqsave(&ploop->bat_rwlock, flags);		\
-		else								\
-			read_lock_irqsave(&ploop->bat_rwlock, flags);		\
-	} while (0)
-
-#define ploop_bat_unlock(ploop, exclusive, flags)				\
-	do {									\
-		if (exclusive)							\
-			write_unlock_irqrestore(&ploop->bat_rwlock, flags);	\
-		else								\
-			read_unlock_irqrestore(&ploop->bat_rwlock, flags);	\
-	} while (0)
-
 static unsigned int pio_nr_segs(struct pio *pio)
 {
 	struct bvec_iter bi = {
@@ -270,6 +254,18 @@ void dispatch_pios(struct ploop *ploop, struct pio *pio, struct list_head *pio_l
 	queue_work(ploop->wq, &ploop->worker);
 }
 
+/* FIXME: check wb, make bool ... */
+static void delay_on_md_busy(struct ploop *ploop, struct md_page *md, struct pio *pio)
+{
+	unsigned long flags;
+
+	WARN_ON_ONCE(!list_empty(&pio->list));
+
+	write_lock_irqsave(&ploop->bat_rwlock, flags);
+	list_add_tail(&pio->list, &md->wait_list);
+	write_unlock_irqrestore(&ploop->bat_rwlock, flags);
+}
+
 void track_dst_cluster(struct ploop *ploop, u32 dst_clu)
 {
 	unsigned long flags;
@@ -650,6 +646,7 @@ static void ploop_advance_local_after_bat_wb(struct ploop *ploop,
 	unsigned int i, last, *bat_entries;
 	map_index_t *dst_clu, off;
 	unsigned long flags;
+	LIST_HEAD(list);
 
 	BUG_ON(!md);
 	bat_entries = kmap_atomic(md->page);
@@ -667,7 +664,7 @@ static void ploop_advance_local_after_bat_wb(struct ploop *ploop,
 		i = PLOOP_MAP_OFFSET;
 
 	dst_clu = kmap_atomic(piwb->bat_page);
-	ploop_bat_lock(ploop, success, flags);
+	write_lock_irqsave(&ploop->bat_rwlock, flags);
 
 	for (; i < last; i++) {
 		if (piwb->type == PIWB_TYPE_DISCARD) {
@@ -697,9 +694,13 @@ static void ploop_advance_local_after_bat_wb(struct ploop *ploop,
 		}
 	}
 
-	ploop_bat_unlock(ploop, success, flags);
+	list_splice_tail_init(&md->wait_list, &list);
+	write_unlock_irqrestore(&ploop->bat_rwlock, flags);
 	kunmap_atomic(dst_clu);
 	kunmap_atomic(bat_entries);
+
+	if (!list_empty(&list))
+		dispatch_pios(ploop, NULL, &list);
 }
 
 static void put_piwb(struct ploop_index_wb *piwb)
@@ -1230,6 +1231,7 @@ static void submit_cow_index_wb(struct ploop_cow *cow,
 	unsigned int clu = cow_pio->clu;
 	struct ploop *ploop = cow->ploop;
 	unsigned int page_id;
+	struct md_page *md;
 	map_index_t *to;
 
 	page_id = bat_clu_to_page_nr(clu);
@@ -1242,8 +1244,9 @@ static void submit_cow_index_wb(struct ploop_cow *cow,
 
 	if (piwb->page_id != page_id || piwb->type != PIWB_TYPE_ALLOC) {
 		/* Another BAT page wb is in process */
-		cow->aux_pio->queue_list_id = PLOOP_LIST_COW;
-		dispatch_pios(ploop, cow->aux_pio, NULL);
+		WARN_ON_ONCE(cow->aux_pio->queue_list_id != PLOOP_LIST_COW);
+		md = md_page_find(ploop, piwb->page_id);
+		delay_on_md_busy(ploop, md, cow->aux_pio);
 		goto out;
 	}
 
@@ -1320,6 +1323,7 @@ static bool locate_new_cluster_and_attach_pio(struct ploop *ploop,
 	bool bat_update_prepared = false;
 	bool attached = false;
 	unsigned int page_id;
+	struct md_page *md;
 
 	page_id = bat_clu_to_page_nr(clu);
 
@@ -1334,7 +1338,9 @@ static bool locate_new_cluster_and_attach_pio(struct ploop *ploop,
 
 	if (piwb->page_id != page_id || piwb->type != PIWB_TYPE_ALLOC) {
 		/* Another BAT page wb is in process */
-		dispatch_pios(ploop, pio, NULL);
+		WARN_ON_ONCE(pio->queue_list_id != PLOOP_LIST_DEFERRED);
+		md = md_page_find(ploop, piwb->page_id);
+		delay_on_md_busy(ploop, md, pio);
 		goto out;
 	}
 
@@ -1455,6 +1461,7 @@ static int process_one_discard_pio(struct ploop *ploop, struct pio *pio,
 {
 	unsigned int page_id, clu;
 	bool bat_update_prepared;
+	struct md_page *md;
 	map_index_t *to;
 
 	WARN_ON(ploop->nr_deltas != 1);
@@ -1475,7 +1482,9 @@ static int process_one_discard_pio(struct ploop *ploop, struct pio *pio,
 	}
 
 	if (piwb->page_id != page_id || piwb->type != PIWB_TYPE_DISCARD) {
-		queue_discard_index_wb(ploop, pio);
+		WARN_ON_ONCE(pio->queue_list_id != PLOOP_LIST_DISCARD);
+		md = md_page_find(ploop, piwb->page_id);
+		delay_on_md_busy(ploop, md, pio);
 		goto out;
 	}
 
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index ebe0c134c148..698da3f887e4 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -111,6 +111,7 @@ struct md_page {
 	unsigned int id; /* Number of this page starting from hdr */
 	struct page *page;
 	u8 *bat_levels;
+	struct list_head wait_list;
 };
 
 enum {


More information about the Devel mailing list