aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFiona Ebner <f.ebner@proxmox.com>2023-10-19 15:19:34 +0200
committerKevin Wolf <kwolf@redhat.com>2023-10-31 13:51:36 +0100
commit67446e605dc2cc3e14a4d212bc97e6a2038e8f6a (patch)
tree279cfdb78ea9df71cdf01c2d1f2b47a73e37ca2c
parent3be5762294bb03f6a8a284ada6cca7af3a3aeb20 (diff)
blockjob: drop AioContext lock before calling bdrv_graph_wrlock()
Same rationale as in 31b2ddfea3 ("graph-lock: Unlock the AioContext while polling"). Otherwise, a deadlock can happen. The alternative would be to pass a BlockDriverState along to bdrv_graph_wrlock(), but there is no BlockDriverState readily available and it's also better conceptually, because the lock is held for the job. The function is always called with the job's AioContext lock held, via one of the .abort, .clean, .free or .prepare job driver functions. Thus, it's safe to drop it. While mirror_exit_common() does hold a second AioContext lock while calling block_job_remove_all_bdrv(), that is for the main thread's AioContext and does not need to be dropped (bdrv_graph_wrlock(bs) also skips dropping the lock if bdrv_get_aio_context(bs) == qemu_get_aio_context()). Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Fiona Ebner <f.ebner@proxmox.com> Message-ID: <20231019131936.414246-2-f.ebner@proxmox.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r--blockjob.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/blockjob.c b/blockjob.c
index 807f992b59..953dc1b6dc 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -198,7 +198,9 @@ 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.
*/
+ aio_context_release(job->job.aio_context);
bdrv_graph_wrlock(NULL);
+ aio_context_acquire(job->job.aio_context);
while (job->nodes) {
GSList *l = job->nodes;
BdrvChild *c = l->data;