Skip to content

Commit

Permalink
blkdebug: refactor removal of a suspended request
Browse files Browse the repository at this point in the history
Extract to a separate function.  Do not rely on FOREACH_SAFE, which is
only "safe" if the *current* node is removed---not if another node is
removed.  Instead, just walk the entire list from the beginning when
asked to resume all suspended requests with a given tag.

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>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20210614082931.24925-2-eesposit@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
  • Loading branch information
esposem authored and XanClic committed Jul 19, 2021
1 parent 7457b40 commit 69d0690
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions block/blkdebug.c
Expand Up @@ -793,7 +793,6 @@ static void suspend_request(BlockDriverState *bs, BlkdebugRule *rule)
printf("blkdebug: Resuming request '%s'\n", r.tag);
}

QLIST_REMOVE(&r, next);
g_free(r.tag);
}

Expand Down Expand Up @@ -869,25 +868,40 @@ static int blkdebug_debug_breakpoint(BlockDriverState *bs, const char *event,
return 0;
}

static int blkdebug_debug_resume(BlockDriverState *bs, const char *tag)
static int resume_req_by_tag(BDRVBlkdebugState *s, const char *tag, bool all)
{
BDRVBlkdebugState *s = bs->opaque;
BlkdebugSuspendedReq *r, *next;
BlkdebugSuspendedReq *r;

QLIST_FOREACH_SAFE(r, &s->suspended_reqs, next, next) {
retry:
/*
* No need for _SAFE, since a different coroutine can remove another node
* (not the current one) in this list, and when the current one is removed
* the iteration starts back from beginning anyways.
*/
QLIST_FOREACH(r, &s->suspended_reqs, next) {
if (!strcmp(r->tag, tag)) {
QLIST_REMOVE(r, next);
qemu_coroutine_enter(r->co);
if (all) {
goto retry;
}
return 0;
}
}
return -ENOENT;
}

static int blkdebug_debug_resume(BlockDriverState *bs, const char *tag)
{
BDRVBlkdebugState *s = bs->opaque;

return resume_req_by_tag(s, tag, false);
}

static int blkdebug_debug_remove_breakpoint(BlockDriverState *bs,
const char *tag)
{
BDRVBlkdebugState *s = bs->opaque;
BlkdebugSuspendedReq *r, *r_next;
BlkdebugRule *rule, *next;
int i, ret = -ENOENT;

Expand All @@ -900,11 +914,8 @@ static int blkdebug_debug_remove_breakpoint(BlockDriverState *bs,
}
}
}
QLIST_FOREACH_SAFE(r, &s->suspended_reqs, next, r_next) {
if (!strcmp(r->tag, tag)) {
qemu_coroutine_enter(r->co);
ret = 0;
}
if (resume_req_by_tag(s, tag, true) == 0) {
ret = 0;
}
return ret;
}
Expand Down

0 comments on commit 69d0690

Please sign in to comment.