qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH 07/17] nbd: convert to use qio_channel_yield


From: Paolo Bonzini
Subject: Re: [Qemu-devel] [PATCH 07/17] nbd: convert to use qio_channel_yield
Date: Mon, 30 Jan 2017 16:18:10 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1


On 30/01/2017 10:50, Stefan Hajnoczi wrote:
> On Fri, Jan 20, 2017 at 05:43:12PM +0100, Paolo Bonzini wrote:
>> +        aio_co_wake(s->recv_coroutine[i]);
>>  
>> -    qemu_coroutine_enter(nbd_get_client_session(bs)->send_coroutine);
>> +        /* We're woken up by the recv_coroutine itself.  */
>> +        qemu_coroutine_yield();
> 
> This relies on recv_coroutine() entering us only after we've yielded -
> otherwise QEMU will crash.  The code and comments don't make it obvious
> why this is guaranteed to be safe.

It doesn't rely on that (that's the magic hidden behind aio_co_wake),
but you're right there is a documentation problem because I needed 10
minutes to remind myself why it's correct.

It works because neither coroutine is moving context:

- if the two coroutines are in the same context, aio_co_wake queues the
coroutine for execution after the yield, which is obviously okay;

- if they are in different context, the recv_coroutine's aio_co_wake
queues the read_reply_co with aio_co_schedule.  It is then woken up
through a bottom half, which executes only after read_reply has yielded.

It is implied by the aio_co_wake and aio_co_schedule documentation; all
requirements are satisfied:

1) aio_co_wake's comment says:

   * aio_co_wake may be executed either in coroutine or non-coroutine
   * context.  The coroutine must not be entered by anyone else while
   * aio_co_wake() is active.

   read_reply_co is only woken by one recv_coroutine at a time

2) And for the case where read_reply_co and recv_coroutine are in
   different contexts, aio_co_schedule's comment says:

   * In addition the coroutine must have yielded unless ctx
   * is the context in which the coroutine is running (i.e. the value of
   * qemu_get_current_aio_context() from the coroutine itself).

   which is okay because aio_co_wake always uses "the context in
   which the coroutine is running" as the argument to aio_co_schedule.

Any suggestions on how to document this properly?  I'm not sure a
comment in the NBD driver is the best place, because similar logic will
appear soon in other networked block drivers.

Paolo



reply via email to

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