qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
To: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>,
	qemu-block@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>,
	John Snow <jsnow@redhat.com>, Eric Blake <eblake@redhat.com>,
	Fam Zheng <fam@euphon.net>,
	qemu-devel@nongnu.org, Paolo Bonzini <pbonzini@redhat.com>
Subject: Re: [PATCH v2 1/9] block: call bdrv_co_drain_begin in a coroutine
Date: Tue, 8 Nov 2022 17:06:07 +0100	[thread overview]
Message-ID: <9eda82a1-4cf4-f65c-08c5-ceaaa1f52f91@redhat.com> (raw)
In-Reply-To: <119e4895-1ee9-ef31-6004-e25d05024210@yandex-team.ru>



Am 08/11/2022 um 16:52 schrieb Vladimir Sementsov-Ogievskiy:
> On 11/8/22 18:13, Emanuele Giuseppe Esposito wrote:
>>
>>
>> Am 08/11/2022 um 15:33 schrieb Vladimir Sementsov-Ogievskiy:
>>> On 11/4/22 12:56, Emanuele Giuseppe Esposito wrote:
>>>> It seems that bdrv_open_driver() forgot to create a coroutine
>>>> where to call bs->drv->bdrv_co_drain_begin(), a callback
>>>> marked as coroutine_fn.
>>>>
>>>> Because there is no active I/O at this point, the coroutine
>>>> should end right after entering, so the caller does not need
>>>> to poll until it is finished.
>>>
>>> Hmm. I see your point. But isn't it better to go the generic way and use
>>> a generated coroutine wrapper? Nothing guarantees that
>>> .bdrv_co_drain_begin() handlers will never do any yield point even on
>>> driver open...
>>>
>>> Look for example at bdrv_co_check(). It has a generated wrapper
>>> bdrv_check(), declared in include/block/block-io.h
>>>
>>> So you just need to declare the wrapper, and use it in
>>> bdrv_open_driver(), the code would be clearer too.
>>
>> I think (and this is a repetition from my previous email) it confuses
>> the code. It is clear, but then you don't know if we are in a coroutine
>> context or not.
> 
> Hmm. But same thing is true for all callers of coroutine wrappers.
> 
> I agree that "coroutine wrapper" is a workaround for the design problem.
> Really, the fact that in many places we don't know are we in coroutine
> or not is very uncomfortable.

And the only way to figure if it's a coroutine or not is by adding
assertions and pray that the iotests don't fail *and* cover all cases.

> 
> But still, I'm not sure that's it good to avoid this workaround in one
> place and continue to use it in all other places. I think following
> common design is better. Or rework it deeply by getting rid of the
> wrappers somehow.

Well, one step at the time :) it's already difficult to verify that such
replacement cover and is correct for all cases :)

> 
>>
>> I am very well aware of what you did with your script, and I am working
>> on extending your g_c_w class with g_c_w_simple, where we drop the
>> if(qemu_in_coroutine()) case and leave just the coroutine creation.
>> Therefore, coroutine functions we use only the _co_ function, otherwise
>> we use g_c_w_simple.
>> In this way code is clear as you point out, but there is no confusion.
> 
> Hmm sounds good, I missed it. Why not use g_c_w_simple here than?

Because I came up with it this morning.

Thank you,
Emanuele

> 
>>
>> Thank you,
>> Emanuele
>>>
>>>>
>>>> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
>>>> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
>>>> ---
>>>>    block.c | 36 +++++++++++++++++++++++++++++++-----
>>>>    1 file changed, 31 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/block.c b/block.c
>>>> index 5311b21f8e..d2b2800039 100644
>>>> --- a/block.c
>>>> +++ b/block.c
>>>> @@ -1637,12 +1637,34 @@ out:
>>>>        g_free(gen_node_name);
>>>>    }
>>>>    +typedef struct DrainCo {
>>>> +    BlockDriverState *bs;
>>>> +    int ret;
>>>> +} DrainCo;
>>>> +
>>>> +static void coroutine_fn bdrv_co_drain_begin(void *opaque)
>>>> +{
>>>> +    int i;
>>>> +    DrainCo *co = opaque;
>>>> +    BlockDriverState *bs = co->bs;
>>>> +
>>>> +    for (i = 0; i < bs->quiesce_counter; i++) {
>>>> +        bs->drv->bdrv_co_drain_begin(bs);
>>>> +    }
>>>> +    co->ret = 0;
>>>> +}
>>>> +
>>>>    static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv,
>>>>                                const char *node_name, QDict *options,
>>>>                                int open_flags, Error **errp)
>>>>    {
>>>>        Error *local_err = NULL;
>>>> -    int i, ret;
>>>> +    int ret;
>>>> +    Coroutine *co;
>>>> +    DrainCo dco = {
>>>> +        .bs = bs,
>>>> +        .ret = NOT_DONE,
>>>> +    };
>>>>        GLOBAL_STATE_CODE();
>>>>          bdrv_assign_node_name(bs, node_name, &local_err);
>>>> @@ -1690,10 +1712,14 @@ static int bdrv_open_driver(BlockDriverState
>>>> *bs, BlockDriver *drv,
>>>>        assert(bdrv_min_mem_align(bs) != 0);
>>>>        assert(is_power_of_2(bs->bl.request_alignment));
>>>>    -    for (i = 0; i < bs->quiesce_counter; i++) {
>>>> -        if (drv->bdrv_co_drain_begin) {
>>>> -            drv->bdrv_co_drain_begin(bs);
>>>> -        }
>>>> +    if (drv->bdrv_co_drain_begin) {
>>>> +        co = qemu_coroutine_create(bdrv_co_drain_begin, &dco);
>>>> +        qemu_coroutine_enter(co);
>>>> +        /*
>>>> +         * There should be no reason for drv->bdrv_co_drain_begin to
>>>> wait at
>>>> +         * this point, because the device does not have any active
>>>> I/O.
>>>> +         */
>>>> +        assert(dco.ret != NOT_DONE);
>>>>        }
>>>>          return 0;
>>>
>>
> 



  reply	other threads:[~2022-11-08 16:07 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-04  9:56 [PATCH v2 0/9] Still more coroutine and various fixes in block layer Emanuele Giuseppe Esposito
2022-11-04  9:56 ` [PATCH v2 1/9] block: call bdrv_co_drain_begin in a coroutine Emanuele Giuseppe Esposito
2022-11-08 14:33   ` Vladimir Sementsov-Ogievskiy
2022-11-08 15:13     ` Emanuele Giuseppe Esposito
2022-11-08 15:52       ` Vladimir Sementsov-Ogievskiy
2022-11-08 16:06         ` Emanuele Giuseppe Esposito [this message]
2022-11-08 15:20     ` Kevin Wolf
2022-11-04  9:56 ` [PATCH v2 2/9] block-copy: add missing coroutine_fn annotations Emanuele Giuseppe Esposito
2022-11-08 14:48   ` Vladimir Sementsov-Ogievskiy
2022-11-08 15:09     ` Emanuele Giuseppe Esposito
2022-11-08 16:19       ` Vladimir Sementsov-Ogievskiy
2022-11-08 16:30         ` Vladimir Sementsov-Ogievskiy
2022-11-09 12:23         ` Emanuele Giuseppe Esposito
2022-11-09 23:52           ` Alberto Faria
2022-11-10 10:52           ` Paolo Bonzini
2022-11-15 15:41             ` Emanuele Giuseppe Esposito
2022-11-16 16:40               ` Paolo Bonzini
2022-11-04  9:56 ` [PATCH v2 3/9] nbd/server.c: " Emanuele Giuseppe Esposito
2022-11-08 14:54   ` Vladimir Sementsov-Ogievskiy
2022-11-04  9:56 ` [PATCH v2 4/9] block-backend: replace bdrv_*_above with blk_*_above Emanuele Giuseppe Esposito
2022-11-04  9:56 ` [PATCH v2 5/9] block: distinguish between bdrv_create running in coroutine and not Emanuele Giuseppe Esposito
2022-11-08 14:59   ` Vladimir Sementsov-Ogievskiy
2022-11-04  9:56 ` [PATCH v2 6/9] block/vmdk: add missing coroutine_fn annotations Emanuele Giuseppe Esposito
2022-11-04  9:56 ` [PATCH v2 7/9] block: bdrv_create_file is a coroutine_fn Emanuele Giuseppe Esposito
2022-11-04  9:56 ` [PATCH v2 8/9] block: bdrv_create is never called in non-coroutine context Emanuele Giuseppe Esposito
2022-11-08 15:23   ` Kevin Wolf
2022-11-04  9:57 ` [PATCH v2 9/9] block/dirty-bitmap: remove unnecessary qemu_in_coroutine() case Emanuele Giuseppe Esposito
2022-11-04 13:16 ` [PATCH v2 0/9] Still more coroutine and various fixes in block layer Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9eda82a1-4cf4-f65c-08c5-ceaaa1f52f91@redhat.com \
    --to=eesposit@redhat.com \
    --cc=eblake@redhat.com \
    --cc=fam@euphon.net \
    --cc=hreitz@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=vsementsov@yandex-team.ru \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).