qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC PATCH v2 0/8] Removal of AioContext lock, bs->parents and ->chi


From: Stefan Hajnoczi
Subject: Re: [RFC PATCH v2 0/8] Removal of AioContext lock, bs->parents and ->children: new rwlock
Date: Thu, 28 Apr 2022 11:45:24 +0100

On Wed, Apr 27, 2022 at 08:55:35AM +0200, Emanuele Giuseppe Esposito wrote:
> 
> 
> Am 26/04/2022 um 10:51 schrieb Emanuele Giuseppe Esposito:
> > Luckly, most of the cases where we recursively go through a graph are
> > the BlockDriverState callback functions in block_int-common.h
> > In order to understand what to protect, I categorized the callbacks in
> > block_int-common.h depending on the type of function that calls them:
> > 
> > 1) If the caller is a generated_co_wrapper, this function must be
> >    protected by rdlock. The reason is that generated_co_wrapper create
> >    coroutines that run in the given bs AioContext, so it doesn't matter
> >    if we are running in the main loop or not, the coroutine might run
> >    in an iothread.
> > 2) If the caller calls it directly, and has the GLOBAL_STATE_CODE() macro,
> >    then the function is safe. The main loop is the writer and thus won't
> >    read and write at the same time.
> > 3) If the caller calls it directly, but has not the GLOBAL_STATE_CODE()
> >    macro, then we need to check the callers and see case-by-case if the
> >    caller is in the main loop, if it needs to take the lock, or delegate
> >    this duty to its caller (to reduce the places where to take it).
> > 
> > I used the vrc script (https://github.com/bonzini/vrc) to get help finding
> > all the callers of a callback. Using its filter function, I can
> > omit all functions protected by the added lock to avoid having duplicates
> > when querying for new callbacks.
> 
> I was wondering, if a function is in category (3) and runs in an
> Iothread but the function itself is not (currently) recursive, meaning
> it doesn't really traverse the graph or calls someone that traverses it,
> should I add the rdlock anyways or not?
> 
> Example: bdrv_co_drain_end
> 
> Pros:
>    + Covers if in future a new recursive callback for a new/existing
>      BlockDriver is implemented.
>    + Covers also the case where I or someone missed the recursive part.
> 
> Cons:
>    - Potentially introducing an unnecessary critical section.
> 
> What do you think?

->bdrv_co_drain_end() is a callback function. Do you mean whether its
caller, bdrv_drain_invoke_entry(), should take the rdlock around
->bdrv_co_drain_end()?

Going up further in the call chain (and maybe switching threads),
bdrv_do_drained_end() has QLIST_FOREACH(child, &bs->children, next) so
it needs protection. If the caller of bdrv_do_drained_end() holds then
rdlock then I think none of the child functions (including
->bdrv_co_drain_end()) need to take it explicitly.

Stefan

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]