[Devel] [PATCH VZ9 2/3] drivers/md/ploop: add inflight metadata writeback counter

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Wed Jul 16 05:36:48 MSK 2025



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.zhadchenko at 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.



More information about the Devel mailing list