Like in “rbd: Run co BH CB in the coroutine’s AioContext”, drop the completion flag, yield exactly once, and run the BH in the coroutine’s AioContext.
(Can be reproduced with multiqueue by adding a usleep(100000) before the `while (!task.complete)` loops.) Like in “iscsi: Run co BH CB in the coroutine’s AioContext”, this makes nfs_co_generic_bh_cb() trivial, and we could just run aio_co_wake() directly from nfs_co_generic_cb(). Like in iscsi, we don’t do that, so as to keep the replay_bh_schedule_oneshot_event(), but we should at least run the BH in the coroutine’s context to remove further BH indirection. Cc: [email protected] Signed-off-by: Hanna Czenczek <[email protected]> --- block/nfs.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/block/nfs.c b/block/nfs.c index 0a7d38db09..4667d49416 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -69,7 +69,6 @@ typedef struct NFSClient { typedef struct NFSRPC { BlockDriverState *bs; int ret; - int complete; QEMUIOVector *iov; struct stat *st; Coroutine *co; @@ -233,8 +232,6 @@ static void coroutine_fn nfs_co_init_task(BlockDriverState *bs, NFSRPC *task) static void nfs_co_generic_bh_cb(void *opaque) { NFSRPC *task = opaque; - - task->complete = 1; aio_co_wake(task->co); } @@ -256,7 +253,7 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data, if (task->ret < 0) { error_report("NFS Error: %s", nfs_get_error(nfs)); } - replay_bh_schedule_oneshot_event(task->client->aio_context, + replay_bh_schedule_oneshot_event(qemu_coroutine_get_aio_context(task->co), nfs_co_generic_bh_cb, task); } @@ -278,9 +275,7 @@ static int coroutine_fn nfs_co_preadv(BlockDriverState *bs, int64_t offset, nfs_set_events(client); } - while (!task.complete) { - qemu_coroutine_yield(); - } + qemu_coroutine_yield(); if (task.ret < 0) { return task.ret; @@ -328,9 +323,7 @@ static int coroutine_fn nfs_co_pwritev(BlockDriverState *bs, int64_t offset, nfs_set_events(client); } - while (!task.complete) { - qemu_coroutine_yield(); - } + qemu_coroutine_yield(); if (my_buffer) { g_free(buf); @@ -358,9 +351,7 @@ static int coroutine_fn nfs_co_flush(BlockDriverState *bs) nfs_set_events(client); } - while (!task.complete) { - qemu_coroutine_yield(); - } + qemu_coroutine_yield(); return task.ret; } @@ -723,7 +714,7 @@ nfs_get_allocated_file_size_cb(int ret, struct nfs_context *nfs, void *data, if (task->ret < 0) { error_report("NFS Error: %s", nfs_get_error(nfs)); } - replay_bh_schedule_oneshot_event(task->client->aio_context, + replay_bh_schedule_oneshot_event(qemu_coroutine_get_aio_context(task->co), nfs_co_generic_bh_cb, task); } @@ -748,9 +739,7 @@ static int64_t coroutine_fn nfs_co_get_allocated_file_size(BlockDriverState *bs) nfs_set_events(client); } - while (!task.complete) { - qemu_coroutine_yield(); - } + qemu_coroutine_yield(); return (task.ret < 0 ? task.ret : st.st_blocks * 512); } -- 2.51.0
