Message ID | 20230425172716.1033562-11-stefanha@redhat.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | block: remove aio_disable_external() API | expand |
Am 25.04.2023 um 19:27 hat Stefan Hajnoczi geschrieben: > For simplicity, always run BlockDevOps .drained_begin/end/poll() > callbacks in the main loop thread. This makes it easier to implement the > callbacks and avoids extra locks. > > Move the function pointer declarations from the I/O Code section to the > Global State section in block-backend-common.h. > > Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> If we're updating function pointers, we should probably update them in BdrvChildClass and BlockDriver, too. This means that a non-coroutine caller can't run in an iothread, not even the home iothread of the BlockDriverState. (I'm not sure if it was allowed previously. I don't think we're actually doing this, but in theory it could have worked.) Maybe put a GLOBAL_STATE_CODE() after handling the bdrv_co_yield_to_drain() case? Or would that look too odd? IO_OR_GS_CODE(); if (qemu_in_coroutine()) { bdrv_co_yield_to_drain(bs, true, parent, poll); return; } GLOBAL_STATE_CODE(); Kevin
On Tue, May 02, 2023 at 06:21:20PM +0200, Kevin Wolf wrote: > Am 25.04.2023 um 19:27 hat Stefan Hajnoczi geschrieben: > > For simplicity, always run BlockDevOps .drained_begin/end/poll() > > callbacks in the main loop thread. This makes it easier to implement the > > callbacks and avoids extra locks. > > > > Move the function pointer declarations from the I/O Code section to the > > Global State section in block-backend-common.h. > > > > Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> > > If we're updating function pointers, we should probably update them in > BdrvChildClass and BlockDriver, too. I'll do that in the next revision. > This means that a non-coroutine caller can't run in an iothread, not > even the home iothread of the BlockDriverState. (I'm not sure if it was > allowed previously. I don't think we're actually doing this, but in > theory it could have worked.) Maybe put a GLOBAL_STATE_CODE() after > handling the bdrv_co_yield_to_drain() case? Or would that look too odd? > > IO_OR_GS_CODE(); > > if (qemu_in_coroutine()) { > bdrv_co_yield_to_drain(bs, true, parent, poll); > return; > } > > GLOBAL_STATE_CODE(); That looks good to me, it makes explicit that IO_OR_GS_CODE() only applies until the end of the if statement. Stefan
diff --git a/include/sysemu/block-backend-common.h b/include/sysemu/block-backend-common.h index 2391679c56..780cea7305 100644 --- a/include/sysemu/block-backend-common.h +++ b/include/sysemu/block-backend-common.h @@ -59,6 +59,19 @@ typedef struct BlockDevOps { */ bool (*is_medium_locked)(void *opaque); + /* + * Runs when the backend receives a drain request. + */ + void (*drained_begin)(void *opaque); + /* + * Runs when the backend's last drain request ends. + */ + void (*drained_end)(void *opaque); + /* + * Is the device still busy? + */ + bool (*drained_poll)(void *opaque); + /* * I/O API functions. These functions are thread-safe. * @@ -76,18 +89,6 @@ typedef struct BlockDevOps { * Runs when the size changed (e.g. monitor command block_resize) */ void (*resize_cb)(void *opaque); - /* - * Runs when the backend receives a drain request. - */ - void (*drained_begin)(void *opaque); - /* - * Runs when the backend's last drain request ends. - */ - void (*drained_end)(void *opaque); - /* - * Is the device still busy? - */ - bool (*drained_poll)(void *opaque); } BlockDevOps; /* diff --git a/block/io.c b/block/io.c index 2e267a85ab..4f9fe2f808 100644 --- a/block/io.c +++ b/block/io.c @@ -335,7 +335,8 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs, if (ctx != co_ctx) { aio_context_release(ctx); } - replay_bh_schedule_oneshot_event(ctx, bdrv_co_drain_bh_cb, &data); + replay_bh_schedule_oneshot_event(qemu_get_aio_context(), + bdrv_co_drain_bh_cb, &data); qemu_coroutine_yield(); /* If we are resumed from some other event (such as an aio completion or a
For simplicity, always run BlockDevOps .drained_begin/end/poll() callbacks in the main loop thread. This makes it easier to implement the callbacks and avoids extra locks. Move the function pointer declarations from the I/O Code section to the Global State section in block-backend-common.h. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> --- include/sysemu/block-backend-common.h | 25 +++++++++++++------------ block/io.c | 3 ++- 2 files changed, 15 insertions(+), 13 deletions(-)