mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 07:13:54 -06:00
block: Mark drain related functions GRAPH_RDLOCK
Draining recursively traverses the graph, therefore we need to make sure that also such accesses to the graph are protected by the graph rdlock. There are 3 different drain callers to consider: 1. drain in the main loop: no issue at all, rdlock is nop. 2. drain in an iothread: rdlock only works in main loop or coroutines, so disallow it. 3. drain in a coroutine (regardless of AioContext): the drain mechanism takes care of scheduling a BH in the bs->aio_context that will then take care of perform the actual draining. This is wrong, because as pointed in (2) if bs->aio_context is an iothread then rdlock won't work. Therefore change bdrv_co_yield_to_drain to schedule the BH in the main loop. Caller (2) also implies that we need to modify test-bdrv-drain.c to disallow draining in the iothreads. For some places, we know that they will hold the lock, but we don't have the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock() with a FIXME comment. These places will be removed once everything is properly annotated. Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Message-ID: <20230929145157.45443-6-kwolf@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
2b3912f135
commit
d05ab380db
5 changed files with 54 additions and 17 deletions
|
@ -370,7 +370,7 @@ bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
|
|||
*
|
||||
* Begin a quiesced section for the parent of @c.
|
||||
*/
|
||||
void bdrv_parent_drained_begin_single(BdrvChild *c);
|
||||
void GRAPH_RDLOCK bdrv_parent_drained_begin_single(BdrvChild *c);
|
||||
|
||||
/**
|
||||
* bdrv_parent_drained_poll_single:
|
||||
|
@ -378,14 +378,14 @@ void bdrv_parent_drained_begin_single(BdrvChild *c);
|
|||
* Returns true if there is any pending activity to cease before @c can be
|
||||
* called quiesced, false otherwise.
|
||||
*/
|
||||
bool bdrv_parent_drained_poll_single(BdrvChild *c);
|
||||
bool GRAPH_RDLOCK bdrv_parent_drained_poll_single(BdrvChild *c);
|
||||
|
||||
/**
|
||||
* bdrv_parent_drained_end_single:
|
||||
*
|
||||
* End a quiesced section for the parent of @c.
|
||||
*/
|
||||
void bdrv_parent_drained_end_single(BdrvChild *c);
|
||||
void GRAPH_RDLOCK bdrv_parent_drained_end_single(BdrvChild *c);
|
||||
|
||||
/**
|
||||
* bdrv_drain_poll:
|
||||
|
@ -398,8 +398,9 @@ void bdrv_parent_drained_end_single(BdrvChild *c);
|
|||
*
|
||||
* This is part of bdrv_drained_begin.
|
||||
*/
|
||||
bool bdrv_drain_poll(BlockDriverState *bs, BdrvChild *ignore_parent,
|
||||
bool ignore_bds_parents);
|
||||
bool GRAPH_RDLOCK
|
||||
bdrv_drain_poll(BlockDriverState *bs, BdrvChild *ignore_parent,
|
||||
bool ignore_bds_parents);
|
||||
|
||||
/**
|
||||
* bdrv_drained_begin:
|
||||
|
@ -407,6 +408,12 @@ bool bdrv_drain_poll(BlockDriverState *bs, BdrvChild *ignore_parent,
|
|||
* Begin a quiesced section for exclusive access to the BDS, by disabling
|
||||
* external request sources including NBD server, block jobs, and device model.
|
||||
*
|
||||
* This function can only be invoked by the main loop or a coroutine
|
||||
* (regardless of the AioContext where it is running).
|
||||
* If the coroutine is running in an Iothread AioContext, this function will
|
||||
* just schedule a BH to run in the main loop.
|
||||
* However, it cannot be directly called by an Iothread.
|
||||
*
|
||||
* This function can be recursive.
|
||||
*/
|
||||
void bdrv_drained_begin(BlockDriverState *bs);
|
||||
|
@ -423,6 +430,12 @@ void bdrv_do_drained_begin_quiesce(BlockDriverState *bs, BdrvChild *parent);
|
|||
* bdrv_drained_end:
|
||||
*
|
||||
* End a quiescent section started by bdrv_drained_begin().
|
||||
*
|
||||
* This function can only be invoked by the main loop or a coroutine
|
||||
* (regardless of the AioContext where it is running).
|
||||
* If the coroutine is running in an Iothread AioContext, this function will
|
||||
* just schedule a BH to run in the main loop.
|
||||
* However, it cannot be directly called by an Iothread.
|
||||
*/
|
||||
void bdrv_drained_end(BlockDriverState *bs);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue