diff options
author | Emanuele Giuseppe Esposito <eesposit@redhat.com> | 2021-06-14 10:29:29 +0200 |
---|---|---|
committer | Max Reitz <mreitz@redhat.com> | 2021-07-19 17:38:38 +0200 |
commit | 2196c341f7d0df161d412d3d7ea81545ab60ea2b (patch) | |
tree | e4fe190b8c73ac419cd58660744f28d868bea1f3 /block/blkdebug.c | |
parent | 51a463680d5620c15b8e88e73c75e4692553c3b5 (diff) | |
download | qemu-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>
Diffstat (limited to 'block/blkdebug.c')
-rw-r--r-- | block/blkdebug.c | 7 |
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; } |