diff options
Diffstat (limited to 'block/nbd.c')
-rw-r--r-- | block/nbd.c | 55 |
1 files changed, 15 insertions, 40 deletions
diff --git a/block/nbd.c b/block/nbd.c index fdfb1ff..653af62 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -87,12 +87,6 @@ typedef enum NBDConnectThreadState { typedef struct NBDConnectThread { /* Initialization constants */ SocketAddress *saddr; /* address to connect to */ - /* - * Bottom half to schedule on completion. Scheduled only if bh_ctx is not - * NULL - */ - QEMUBHFunc *bh_func; - void *bh_opaque; /* * Result of last attempt. Valid in FAIL and SUCCESS states. @@ -101,10 +95,15 @@ typedef struct NBDConnectThread { QIOChannelSocket *sioc; Error *err; - /* state and bh_ctx are protected by mutex */ QemuMutex mutex; + /* All further fields are protected by mutex */ NBDConnectThreadState state; /* current state of the thread */ - AioContext *bh_ctx; /* where to schedule bh (NULL means don't schedule) */ + + /* + * wait_co: if non-NULL, which coroutine to wake in + * nbd_co_establish_connection() after yield() + */ + Coroutine *wait_co; } NBDConnectThread; typedef struct BDRVNBDState { @@ -138,7 +137,6 @@ typedef struct BDRVNBDState { char *x_dirty_bitmap; bool alloc_depth; - bool wait_connect; NBDConnectThread *connect_thread; } BDRVNBDState; @@ -370,15 +368,6 @@ static bool nbd_client_connecting_wait(BDRVNBDState *s) return qatomic_load_acquire(&s->state) == NBD_CLIENT_CONNECTING_WAIT; } -static void connect_bh(void *opaque) -{ - BDRVNBDState *state = opaque; - - assert(state->wait_connect); - state->wait_connect = false; - aio_co_wake(state->connection_co); -} - static void nbd_init_connect_thread(BDRVNBDState *s) { s->connect_thread = g_new(NBDConnectThread, 1); @@ -386,8 +375,6 @@ static void nbd_init_connect_thread(BDRVNBDState *s) *s->connect_thread = (NBDConnectThread) { .saddr = QAPI_CLONE(SocketAddress, s->saddr), .state = CONNECT_THREAD_NONE, - .bh_func = connect_bh, - .bh_opaque = s, }; qemu_mutex_init(&s->connect_thread->mutex); @@ -427,11 +414,9 @@ static void *connect_thread_func(void *opaque) switch (thr->state) { case CONNECT_THREAD_RUNNING: thr->state = ret < 0 ? CONNECT_THREAD_FAIL : CONNECT_THREAD_SUCCESS; - if (thr->bh_ctx) { - aio_bh_schedule_oneshot(thr->bh_ctx, thr->bh_func, thr->bh_opaque); - - /* play safe, don't reuse bh_ctx on further connection attempts */ - thr->bh_ctx = NULL; + if (thr->wait_co) { + aio_co_wake(thr->wait_co); + thr->wait_co = NULL; } break; case CONNECT_THREAD_RUNNING_DETACHED: @@ -485,20 +470,14 @@ nbd_co_establish_connection(BlockDriverState *bs, Error **errp) abort(); } - thr->bh_ctx = qemu_get_current_aio_context(); + thr->wait_co = qemu_coroutine_self(); qemu_mutex_unlock(&thr->mutex); - /* * We are going to wait for connect-thread finish, but * nbd_client_co_drain_begin() can interrupt. - * - * Note that wait_connect variable is not visible for connect-thread. It - * doesn't need mutex protection, it used only inside home aio context of - * bs. */ - s->wait_connect = true; qemu_coroutine_yield(); qemu_mutex_lock(&thr->mutex); @@ -553,23 +532,19 @@ static void nbd_co_establish_connection_cancel(BlockDriverState *bs) { BDRVNBDState *s = bs->opaque; NBDConnectThread *thr = s->connect_thread; - bool wake = false; + Coroutine *wait_co = NULL; qemu_mutex_lock(&thr->mutex); if (thr->state == CONNECT_THREAD_RUNNING) { /* We can cancel only in running state, when bh is not yet scheduled */ - thr->bh_ctx = NULL; - if (s->wait_connect) { - s->wait_connect = false; - wake = true; - } + wait_co = g_steal_pointer(&thr->wait_co); } qemu_mutex_unlock(&thr->mutex); - if (wake) { - aio_co_wake(s->connection_co); + if (wait_co) { + aio_co_wake(wait_co); } } |