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.
+ if (ret)
+ ploop_inflight_bios_ref_switch(ploop, true);
Why do we need to wait for inflight bios again on the error path?
+
+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)
--
Best regards, Pavel Tikhomirov
Senior Software Developer, Virtuozzo.
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel