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 <[email protected]>
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 <[email protected]>
    
    ==========================
    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 {
_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to