From 5ac724184c286b367525035eabf4b8bb4a386c54 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Date: Wed, 4 Nov 2015 15:15:35 +0200 Subject: [PATCH] throttle: Check for pending requests in throttle_group_unregister_bs() throttle_group_unregister_bs() removes a BlockDriverState from its throttling group and destroys the timers. This means that there must be no pending throttled requests at that point (because it would be impossible to complete them), so the caller has to drain them first. At the moment throttle_group_unregister_bs() is only called from bdrv_io_limits_disable(), which already takes care of draining the requests, so there's nothing to worry about, but this patch makes this invariant explicit in the documentation and adds the relevant assertions. Signed-off-by: Alberto Garcia Signed-off-by: Kevin Wolf --- block/throttle-groups.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/block/throttle-groups.c b/block/throttle-groups.c index 3419af7d96..13b5baa5d7 100644 --- a/block/throttle-groups.c +++ b/block/throttle-groups.c @@ -437,6 +437,9 @@ void throttle_group_register_bs(BlockDriverState *bs, const char *groupname) * list, destroying the timers and setting the throttle_state pointer * to NULL. * + * The BlockDriverState must not have pending throttled requests, so + * the caller has to drain them first. + * * The group will be destroyed if it's empty after this operation. * * @bs: the BlockDriverState to remove @@ -446,6 +449,10 @@ void throttle_group_unregister_bs(BlockDriverState *bs) ThrottleGroup *tg = container_of(bs->throttle_state, ThrottleGroup, ts); int i; + assert(bs->pending_reqs[0] == 0 && bs->pending_reqs[1] == 0); + assert(qemu_co_queue_empty(&bs->throttled_reqs[0])); + assert(qemu_co_queue_empty(&bs->throttled_reqs[1])); + qemu_mutex_lock(&tg->lock); for (i = 0; i < 2; i++) { if (tg->tokens[i] == bs) { -- 2.30.2