aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmanuele Giuseppe Esposito <eesposit@redhat.com>2021-06-14 10:29:29 +0200
committerMax Reitz <mreitz@redhat.com>2021-07-19 17:38:38 +0200
commit2196c341f7d0df161d412d3d7ea81545ab60ea2b (patch)
treee4fe190b8c73ac419cd58660744f28d868bea1f3
parent51a463680d5620c15b8e88e73c75e4692553c3b5 (diff)
downloadqemu-2196c341f7d0df161d412d3d7ea81545ab60ea2b.zip
qemu-2196c341f7d0df161d412d3d7ea81545ab60ea2b.tar.gz
qemu-2196c341f7d0df161d412d3d7ea81545ab60ea2b.tar.bz2
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 <pbonzini@redhat.com> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Message-Id: <20210614082931.24925-5-eesposit@redhat.com> Signed-off-by: Max Reitz <mreitz@redhat.com>
-rw-r--r--block/blkdebug.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 6bdeb2c..dd82131 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;
}