[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 03/10] util/async: aio_co_enter(): do aio_co_schedule in gener
From: |
Vladimir Sementsov-Ogievskiy |
Subject: |
[PATCH v2 03/10] util/async: aio_co_enter(): do aio_co_schedule in general case |
Date: |
Thu, 8 Apr 2021 17:08:20 +0300 |
With the following patch we want to call aio_co_wake() from thread.
And it works bad.
Assume we have no iothreads.
Assume we have a coroutine A, which waits in the yield point for external
aio_co_wake(), and no progress can be done until it happen.
Main thread is in blocking aio_poll() (for example, in blk_read()).
Now, in a separate thread we do aio_co_wake(). It calls aio_co_enter(),
which goes through last "else" branch and do aio_context_acquire(ctx).
Now we have a deadlock, as aio_poll() will not release the context lock
until some progress is done, and progress can't be done until
aio_co_wake() wake the coroutine A. And it can't because it wait for
aio_context_acquire().
Still, aio_co_schedule() works well in parallel with blocking
aio_poll(). So let's use it in generic case and drop
aio_context_acquire/aio_context_release branch from aio_co_enter().
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
util/async.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/util/async.c b/util/async.c
index 674dbefb7c..f05b883a39 100644
--- a/util/async.c
+++ b/util/async.c
@@ -614,19 +614,12 @@ void aio_co_wake(struct Coroutine *co)
void aio_co_enter(AioContext *ctx, struct Coroutine *co)
{
- if (ctx != qemu_get_current_aio_context()) {
- aio_co_schedule(ctx, co);
- return;
- }
-
- if (qemu_in_coroutine()) {
+ if (ctx == qemu_get_current_aio_context() && qemu_in_coroutine()) {
Coroutine *self = qemu_coroutine_self();
assert(self != co);
QSIMPLEQ_INSERT_TAIL(&self->co_queue_wakeup, co, co_queue_next);
} else {
- aio_context_acquire(ctx);
- qemu_aio_coroutine_enter(ctx, co);
- aio_context_release(ctx);
+ aio_co_schedule(ctx, co);
}
}
--
2.29.2
- Re: [PATCH v2 02/10] block/nbd: BDRVNBDState: drop unused connect_err and connect_status, (continued)
- [PATCH v2 07/10] block/nbd: make nbd_co_establish_connection_cancel() bs-independent, Vladimir Sementsov-Ogievskiy, 2021/04/08
- [PATCH v2 09/10] block/nbd: introduce nbd_client_connection_new(), Vladimir Sementsov-Ogievskiy, 2021/04/08
- [PATCH v2 10/10] nbd: move connection code from block/nbd to nbd/client-connection, Vladimir Sementsov-Ogievskiy, 2021/04/08
- [PATCH v2 06/10] block/nbd: bs-independent interface for nbd_co_establish_connection(), Vladimir Sementsov-Ogievskiy, 2021/04/08
- [PATCH v2 03/10] util/async: aio_co_enter(): do aio_co_schedule in general case,
Vladimir Sementsov-Ogievskiy <=
- Re: [PATCH v2 00/10] block/nbd: move connection code to separate file, Roman Kagan, 2021/04/08