29.06.2020 16:56, Stefan Hajnoczi wrote:
On Mon, Jun 29, 2020 at 10:55:06AM +0300, Vladimir Sementsov-Ogievskiy wrote:
Also, why in block/io.c we kick the main context, but not bs->aio_context?

 From AIO_WAIT_WHILE():

  * The caller's thread must be the IOThread that owns @ctx or the main loop
  * thread (with @ctx acquired exactly once).  This function cannot be used to
  * wait on conditions between two IOThreads since that could lead to deadlock,
  * go via the main loop instead.

Case 1: IOThread

   while ((cond)) {                                           \
       aio_poll(ctx_, true);                                  \
       waited_ = true;                                        \
   }                                                          \

In this case aio_poll() returns after every event loop iteration and we
will re-evaluate cond. Therefore we don't need to be kicked.

Case 2: Main loop thread

In this case we need the kick since we're waiting on the main loop
AioContext, not the IOThread AioContext that is doing the actual work.
aio_wait_kick() schedules a dummy BH to wake up the main loop thread.

There is no harm in scheduling the dummy BH in the main loop thread when
AIO_WAIT_WHILE() is called from an IOThread.

Hope this helps,

Thanks!

Looking at this all again, I think that client->recv_coroutine == NULL is a bad 
marker of finish, as it's not directly bound to _put. I'll try another approach, 
to make nbd_export_close_all() be synchronous instead by waiting for all export to 
be actually freed.


--
Best regards,
Vladimir

Reply via email to