Skip to content

Commit

Permalink
blkdebug: move post-resume handling to resume_req_by_tag
Browse files Browse the repository at this point in the history
We want to move qemu_coroutine_yield() after the loop on rules,
because QLIST_FOREACH_SAFE is wrong if the rule list is modified
while the coroutine has yielded.  Therefore move the suspended
request to the heap and clean it up from the remove side.
All that is left is for blkdebug_debug_event to handle the
yielding.

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-3-eesposit@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
  • Loading branch information
esposem authored and XanClic committed Jul 19, 2021
1 parent 69d0690 commit f48ff5a
Showing 1 changed file with 18 additions and 13 deletions.
31 changes: 18 additions & 13 deletions block/blkdebug.c
Expand Up @@ -775,25 +775,20 @@ static void blkdebug_close(BlockDriverState *bs)
static void suspend_request(BlockDriverState *bs, BlkdebugRule *rule)
{
BDRVBlkdebugState *s = bs->opaque;
BlkdebugSuspendedReq r;
BlkdebugSuspendedReq *r;

r = (BlkdebugSuspendedReq) {
.co = qemu_coroutine_self(),
.tag = g_strdup(rule->options.suspend.tag),
};
r = g_new(BlkdebugSuspendedReq, 1);

r->co = qemu_coroutine_self();
r->tag = g_strdup(rule->options.suspend.tag);

remove_rule(rule);
QLIST_INSERT_HEAD(&s->suspended_reqs, &r, next);
QLIST_INSERT_HEAD(&s->suspended_reqs, r, next);

if (!qtest_enabled()) {
printf("blkdebug: Suspended request '%s'\n", r.tag);
printf("blkdebug: Suspended request '%s'\n", r->tag);
}
qemu_coroutine_yield();
if (!qtest_enabled()) {
printf("blkdebug: Resuming request '%s'\n", r.tag);
}

g_free(r.tag);
}

static bool process_rule(BlockDriverState *bs, struct BlkdebugRule *rule,
Expand Down Expand Up @@ -880,8 +875,18 @@ static int resume_req_by_tag(BDRVBlkdebugState *s, const char *tag, bool all)
*/
QLIST_FOREACH(r, &s->suspended_reqs, next) {
if (!strcmp(r->tag, tag)) {
Coroutine *co = r->co;

if (!qtest_enabled()) {
printf("blkdebug: Resuming request '%s'\n", r->tag);
}

QLIST_REMOVE(r, next);
qemu_coroutine_enter(r->co);
g_free(r->tag);
g_free(r);

qemu_coroutine_enter(co);

if (all) {
goto retry;
}
Expand Down

0 comments on commit f48ff5a

Please sign in to comment.