block: Add bdrv_co_enter()/leave()
Add a pair of functions to temporarily move the current coroutine to the AioContext of a given BlockDriverState. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Message-Id: <20201005155855.256490-13-kwolf@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
parent
26b0b698c0
commit
e336fd4c4b
23
block.c
23
block.c
@ -6303,6 +6303,29 @@ AioContext *bdrv_get_aio_context(BlockDriverState *bs)
|
|||||||
return bs ? bs->aio_context : qemu_get_aio_context();
|
return bs ? bs->aio_context : qemu_get_aio_context();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AioContext *coroutine_fn bdrv_co_enter(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
Coroutine *self = qemu_coroutine_self();
|
||||||
|
AioContext *old_ctx = qemu_coroutine_get_aio_context(self);
|
||||||
|
AioContext *new_ctx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Increase bs->in_flight to ensure that this operation is completed before
|
||||||
|
* moving the node to a different AioContext. Read new_ctx only afterwards.
|
||||||
|
*/
|
||||||
|
bdrv_inc_in_flight(bs);
|
||||||
|
|
||||||
|
new_ctx = bdrv_get_aio_context(bs);
|
||||||
|
aio_co_reschedule_self(new_ctx);
|
||||||
|
return old_ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx)
|
||||||
|
{
|
||||||
|
aio_co_reschedule_self(old_ctx);
|
||||||
|
bdrv_dec_in_flight(bs);
|
||||||
|
}
|
||||||
|
|
||||||
void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co)
|
void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co)
|
||||||
{
|
{
|
||||||
aio_co_enter(bdrv_get_aio_context(bs), co);
|
aio_co_enter(bdrv_get_aio_context(bs), co);
|
||||||
|
@ -640,6 +640,23 @@ bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag);
|
|||||||
*/
|
*/
|
||||||
AioContext *bdrv_get_aio_context(BlockDriverState *bs);
|
AioContext *bdrv_get_aio_context(BlockDriverState *bs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move the current coroutine to the AioContext of @bs and return the old
|
||||||
|
* AioContext of the coroutine. Increase bs->in_flight so that draining @bs
|
||||||
|
* will wait for the operation to proceed until the corresponding
|
||||||
|
* bdrv_co_leave().
|
||||||
|
*
|
||||||
|
* Consequently, you can't call drain inside a bdrv_co_enter/leave() section as
|
||||||
|
* this will deadlock.
|
||||||
|
*/
|
||||||
|
AioContext *coroutine_fn bdrv_co_enter(BlockDriverState *bs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends a section started by bdrv_co_enter(). Move the current coroutine back
|
||||||
|
* to old_ctx and decrease bs->in_flight again.
|
||||||
|
*/
|
||||||
|
void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transfer control to @co in the aio context of @bs
|
* Transfer control to @co in the aio context of @bs
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user