Am 08.05.2025 um 16:09 hat Fiona Ebner geschrieben:
> For convenience, allow indicating whether the write-locked section
> should also be a drained section directly when taking the write
> lock.
> 
> Signed-off-by: Fiona Ebner <f.eb...@proxmox.com>

Good idea, the pattern seems to be common enough.

> In bdrv_graph_wrlock() there is a comment that it uses
> bdrv_drain_all_begin_nopoll() to make sure that constantly arriving
> new I/O doesn't cause starvation. The changes from this series are at
> odds with that, but there doesn't seem to be any (new) test failures.

I don't see why they are at odds with it? Draining an already drained
node isn't a problem, it just increases the counter without doing
anything else.

> The following script was used:
> 
> > find . -name '*.c' -exec sed -i -z 
> > 's/bdrv_drain_all_begin();\n\s*bdrv_graph_wrlock();/bdrv_graph_wrlock(true);/g'
> >  {} ';'
> > find . -name '*.c' -exec sed -i -z 
> > 's/bdrv_graph_wrunlock();\n\s*bdrv_drain_all_end();/bdrv_graph_wrunlock(true);/g'
> >  {} ';'
> > find . -name '*.c' -exec sed -i -z 
> > 's/bdrv_graph_wrlock();/bdrv_graph_wrlock(false);/g' {} ';'
> > find . -name '*.c' -exec sed -i -z 
> > 's/bdrv_graph_wrunlock();/bdrv_graph_wrunlock(false);/g' {} ';'
> 
>  block.c                            | 62 ++++++++++++------------------
>  block/backup.c                     |  6 +--
>  block/blklogwrites.c               | 12 ++----
>  block/blkverify.c                  |  6 +--
>  block/block-backend.c              | 12 ++----
>  block/commit.c                     | 20 ++++------
>  block/graph-lock.c                 | 22 ++++++++---
>  block/mirror.c                     | 27 ++++++-------
>  block/qcow2.c                      |  6 +--
>  block/quorum.c                     | 12 ++----
>  block/replication.c                | 21 ++++------
>  block/snapshot.c                   |  6 +--
>  block/stream.c                     | 16 +++-----
>  block/vmdk.c                       | 30 +++++----------
>  blockdev.c                         | 10 ++---
>  blockjob.c                         | 18 +++------
>  include/block/graph-lock.h         |  8 +++-
>  scripts/block-coroutine-wrapper.py |  4 +-
>  tests/unit/test-bdrv-drain.c       | 58 ++++++++++------------------
>  tests/unit/test-bdrv-graph-mod.c   | 30 +++++----------
>  20 files changed, 152 insertions(+), 234 deletions(-)

> diff --git a/include/block/graph-lock.h b/include/block/graph-lock.h
> index 2c26c72108..f291ccbc97 100644
> --- a/include/block/graph-lock.h
> +++ b/include/block/graph-lock.h
> @@ -108,17 +108,21 @@ void unregister_aiocontext(AioContext *ctx);
>   *
>   * The wrlock can only be taken from the main loop, with BQL held, as only 
> the
>   * main loop is allowed to modify the graph.
> + *
> + * @drain whether bdrv_drain_all_begin() should be called before taking the 
> lock
>   */
>  void no_coroutine_fn TSA_ACQUIRE(graph_lock) TSA_NO_TSA
> -bdrv_graph_wrlock(void);
> +bdrv_graph_wrlock(bool drain);

I would prefer having two separate functions instead of a bool
parameter.

bdrv_graph_wrlock() could stay as it is, and bdrv_graph_wrlock_drained()
could be the convenience wrapper that drains first.

>  /*
>   * bdrv_graph_wrunlock:
>   * Write finished, reset global has_writer to 0 and restart
>   * all readers that are waiting.
> + *
> + * @drain whether bdrv_drain_all_end() should be called after releasing the 
> lock
>   */
>  void no_coroutine_fn TSA_RELEASE(graph_lock) TSA_NO_TSA
> -bdrv_graph_wrunlock(void);
> +bdrv_graph_wrunlock(bool drain);

Here I would prefer to only keep the old bdrv_graph_wrunlock() without
a parameter. Can we just remember @drain from bdrv_graph_wrlock() in a
global variable? This would prevent callers from mismatching lock and
unlock variants (which TSA wouldn't be able to catch).

Kevin


Reply via email to