This function is called in two different places: - timer callback, which does not take the graph rdlock. - bdrv_qed_drain_begin(), which is a .bdrv_drain_begin() callback that will soon take the lock.
Since it calls recursive functions that traverse the graph, we need to protect them with the graph rdlock. Signed-off-by: Emanuele Giuseppe Esposito <eespo...@redhat.com> --- block/qed.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/block/qed.c b/block/qed.c index c2691a85b1..778b23d0f6 100644 --- a/block/qed.c +++ b/block/qed.c @@ -282,11 +282,13 @@ static void coroutine_fn qed_unplug_allocating_write_reqs(BDRVQEDState *s) qemu_co_mutex_unlock(&s->table_lock); } +/* Called with graph rdlock taken */ static void coroutine_fn qed_need_check_timer(BDRVQEDState *s) { int ret; trace_qed_need_check_timer_cb(s); + assert_bdrv_graph_readable(); if (!qed_plug_allocating_write_reqs(s)) { return; @@ -312,6 +314,7 @@ static void coroutine_fn qed_need_check_timer(BDRVQEDState *s) static void coroutine_fn qed_need_check_timer_entry(void *opaque) { BDRVQEDState *s = opaque; + GRAPH_RDLOCK_GUARD(); qed_need_check_timer(opaque); bdrv_dec_in_flight(s->bs); -- 2.31.1