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