Message ID | 20230817125020.208339-20-kwolf@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Graph locking part 4 (node management) | expand |
Am 17/08/2023 um 14:50 schrieb Kevin Wolf: > Instead of taking the writer lock internally, require callers to already > hold it when calling bdrv_root_unref_child(). These callers will > typically already hold the graph lock once the locking work is > completed, which means that they can't call functions that take it > internally. > > Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
On Thu, Aug 17, 2023 at 02:50:18PM +0200, Kevin Wolf wrote: > Instead of taking the writer lock internally, require callers to already > hold it when calling bdrv_root_unref_child(). These callers will > typically already hold the graph lock once the locking work is > completed, which means that they can't call functions that take it > internally. > > Signed-off-by: Kevin Wolf <kwolf@redhat.com> > --- > include/block/block_int-global-state.h | 2 +- > block.c | 6 +++--- > block/block-backend.c | 3 +++ > blockjob.c | 2 ++ > 4 files changed, 9 insertions(+), 4 deletions(-) Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
diff --git a/include/block/block_int-global-state.h b/include/block/block_int-global-state.h index e2304db58b..074b677838 100644 --- a/include/block/block_int-global-state.h +++ b/include/block/block_int-global-state.h @@ -202,7 +202,7 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs, BdrvChildRole child_role, uint64_t perm, uint64_t shared_perm, void *opaque, Error **errp); -void bdrv_root_unref_child(BdrvChild *child); +void GRAPH_WRLOCK bdrv_root_unref_child(BdrvChild *child); void GRAPH_RDLOCK bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm, uint64_t *shared_perm); diff --git a/block.c b/block.c index c0a8460434..0bb0c84c0e 100644 --- a/block.c +++ b/block.c @@ -3266,7 +3266,6 @@ void bdrv_root_unref_child(BdrvChild *child) BlockDriverState *child_bs = child->bs; GLOBAL_STATE_CODE(); - bdrv_graph_wrlock(NULL); bdrv_replace_child_noperm(child, NULL); bdrv_child_free(child); @@ -3286,8 +3285,7 @@ void bdrv_root_unref_child(BdrvChild *child) NULL); } - bdrv_graph_wrunlock(); - bdrv_unref(child_bs); + bdrv_schedule_unref(child_bs); } typedef struct BdrvSetInheritsFrom { @@ -3364,8 +3362,10 @@ void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child) return; } + bdrv_graph_wrlock(NULL); bdrv_unset_inherits_from(parent, child, NULL); bdrv_root_unref_child(child); + bdrv_graph_wrunlock(); } diff --git a/block/block-backend.c b/block/block-backend.c index 8d0282a5d9..c2636f4351 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -915,7 +915,10 @@ void blk_remove_bs(BlockBackend *blk) blk_drain(blk); root = blk->root; blk->root = NULL; + + bdrv_graph_wrlock(NULL); bdrv_root_unref_child(root); + bdrv_graph_wrunlock(); } /* diff --git a/blockjob.c b/blockjob.c index 25fe8e625d..58c5d64539 100644 --- a/blockjob.c +++ b/blockjob.c @@ -198,6 +198,7 @@ void block_job_remove_all_bdrv(BlockJob *job) * one to make sure that such a concurrent access does not attempt * to process an already freed BdrvChild. */ + bdrv_graph_wrlock(NULL); while (job->nodes) { GSList *l = job->nodes; BdrvChild *c = l->data; @@ -209,6 +210,7 @@ void block_job_remove_all_bdrv(BlockJob *job) g_slist_free_1(l); } + bdrv_graph_wrunlock(); } bool block_job_has_bdrv(BlockJob *job, BlockDriverState *bs)
Instead of taking the writer lock internally, require callers to already hold it when calling bdrv_root_unref_child(). These callers will typically already hold the graph lock once the locking work is completed, which means that they can't call functions that take it internally. Signed-off-by: Kevin Wolf <kwolf@redhat.com> --- include/block/block_int-global-state.h | 2 +- block.c | 6 +++--- block/block-backend.c | 3 +++ blockjob.c | 2 ++ 4 files changed, 9 insertions(+), 4 deletions(-)