On 7/16/25 04:36, Pavel Tikhomirov wrote:


On 7/15/25 22:20, Andrey Zhadchenko wrote:
and use it during ploop_suspend_submitting_pios() to wait for all
writeback to flush

https://virtuozzo.atlassian.net/browse/VSTOR-108540
Signed-off-by: Andrey Zhadchenko <andrey.zhadche...@virtuozzo.com>
---
  drivers/md/dm-ploop-cmd.c    | 9 +++++++++
  drivers/md/dm-ploop-map.c    | 5 +++++
  drivers/md/dm-ploop-target.c | 2 ++
  drivers/md/dm-ploop.h        | 3 +++
  4 files changed, 19 insertions(+)

diff --git a/drivers/md/dm-ploop-cmd.c b/drivers/md/dm-ploop-cmd.c
index 85bb69714ca8..37cc0b656ece 100644
--- a/drivers/md/dm-ploop-cmd.c
+++ b/drivers/md/dm-ploop-cmd.c
@@ -151,6 +151,15 @@ static int ploop_suspend_submitting_pios(struct ploop *ploop)
      spin_unlock_irq(&ploop->deferred_lock);
      ret = ploop_inflight_bios_ref_switch(ploop, true);
+    if (ret)
+        goto out;
+
+    ret = wait_event_interruptible(ploop->inflight_md_wq,
+                       !atomic_read(&ploop->inflight_md));

How do we prevent situation that the above wait finishes successfully, and just after that ploop_prepare_bat_update() generates a new inflight piwb. E.g. for regular pios we also prevent submitting new ones.

We rely on the fact that regular pios are not submitted anymore AND we waited for all of them to finish. So nobody can generate new piwb at the moment, as new metadata writes are created during pio processing.


+    if (ret)
+        ploop_inflight_bios_ref_switch(ploop, true);

Why do we need to wait for inflight bios again on the error path?
Actually we do not, so i will drop this.


+
+out:
      if (ret)
          ploop_resume_submitting_pios(ploop);
      return ret;
diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index f21a3ae5ba4a..7604b3c8d644 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -936,6 +936,8 @@ static void ploop_put_piwb(struct ploop_index_wb *piwb)
           * zero keeps it as is
           */
+        if (atomic_dec_and_test(&piwb->ploop->inflight_md))
+            wake_up_interruptible(&piwb->ploop->inflight_md_wq);
          ploop_free_piwb(piwb);
      }
  }
@@ -1094,6 +1096,7 @@ static int ploop_prepare_bat_update(struct ploop *ploop, struct md_page *md,
      kunmap_local(to);
      piwb->type = type;
+    atomic_inc(&ploop->inflight_md);
      return 0;
  err:
      ploop_free_piwb(piwb);
@@ -1113,6 +1116,8 @@ void ploop_break_bat_update(struct ploop *ploop, struct md_page *md,
      spin_unlock(&md->md_lock);
      spin_unlock_irqrestore(&ploop->bat_lock, flags);
+    if (atomic_dec_and_test(&ploop->inflight_md))
+        wake_up_interruptible(&ploop->inflight_md_wq);
      ploop_free_piwb(piwb);
  }
diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c
index af0658a455ce..6d1881ea3828 100644
--- a/drivers/md/dm-ploop-target.c
+++ b/drivers/md/dm-ploop-target.c
@@ -566,8 +566,10 @@ static int ploop_ctr(struct dm_target *ti, unsigned int argc, char **argv)
      init_waitqueue_head(&ploop->dispatcher_wq_data);
      init_waitqueue_head(&ploop->dispatcher_wq_fsync);
      init_waitqueue_head(&ploop->dispatcher_wq_prealloc);
+    init_waitqueue_head(&ploop->inflight_md_wq);
      ploop->prealloc_size = 0;
      ploop->prealloc_in_progress = 0;
+    atomic_set(&ploop->inflight_md, 0);
      ploop->kt_worker = ploop_worker_create(ploop, ploop_worker, "d", 0);
      if (!ploop->kt_worker)
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index b66672eef5ee..5a88664feb68 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -267,6 +267,9 @@ struct ploop {
      loff_t prealloc_size;
      loff_t prealloc_in_progress;
      struct wait_queue_head dispatcher_wq_prealloc;
+
+    atomic_t inflight_md;
+    struct wait_queue_head inflight_md_wq;
  };
  #define ploop_blk_queue(p) ((p)->ti->table->md->queue)


_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to