From 2196c341f7d0df161d412d3d7ea81545ab60ea2b Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Mon, 14 Jun 2021 10:29:29 +0200 Subject: [PATCH] blkdebug: do not suspend in the middle of QLIST_FOREACH_SAFE That would be unsafe in case a rule other than the current one is removed while the coroutine has yielded. Keep FOREACH_SAFE because suspend_request deletes the current rule. After this patch, *all* matching rules are deleted before suspending the coroutine, rather than just one. This doesn't affect the existing testcases. Use actions_count to see how many yield to issue. Co-developed-by: Paolo Bonzini Signed-off-by: Emanuele Giuseppe Esposito Reviewed-by: Vladimir Sementsov-Ogievskiy Message-Id: <20210614082931.24925-5-eesposit@redhat.com> Signed-off-by: Max Reitz --- block/blkdebug.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/block/blkdebug.c b/block/blkdebug.c index 6bdeb2c7b3..dd82131d1e 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -789,7 +789,6 @@ static void suspend_request(BlockDriverState *bs, BlkdebugRule *rule) if (!qtest_enabled()) { printf("blkdebug: Suspended request '%s'\n", r->tag); } - qemu_coroutine_yield(); } static void process_rule(BlockDriverState *bs, struct BlkdebugRule *rule, @@ -834,6 +833,12 @@ static void blkdebug_debug_event(BlockDriverState *bs, BlkdebugEvent event) QLIST_FOREACH_SAFE(rule, &s->rules[event], next, next) { process_rule(bs, rule, actions_count); } + + while (actions_count[ACTION_SUSPEND] > 0) { + qemu_coroutine_yield(); + actions_count[ACTION_SUSPEND]--; + } + s->state = s->new_state; }