mirror of https://github.com/xemu-project/xemu.git
throttle-groups: Don't allow timers without throttled requests
Commit 6fccbb475b
fixed a bug caused by
QEMU attempting to remove a throttle group member with no pending
requests but an active timer set. This was the result of a previous
bdrv_drained_begin() call processing the throttled requests but
leaving the timer untouched.
Although the commit does solve the problem, the situation shouldn't
happen in the first place. If we try to drain a throttle group member
which has a timer set, we should cancel the timer instead of ignoring
it.
Signed-off-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
3db3e9c621
commit
25b8e4db7f
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
static void throttle_group_obj_init(Object *obj);
|
static void throttle_group_obj_init(Object *obj);
|
||||||
static void throttle_group_obj_complete(UserCreatable *obj, Error **errp);
|
static void throttle_group_obj_complete(UserCreatable *obj, Error **errp);
|
||||||
|
static void timer_cb(ThrottleGroupMember *tgm, bool is_write);
|
||||||
|
|
||||||
/* The ThrottleGroup structure (with its ThrottleState) is shared
|
/* The ThrottleGroup structure (with its ThrottleState) is shared
|
||||||
* among different ThrottleGroupMembers and it's independent from
|
* among different ThrottleGroupMembers and it's independent from
|
||||||
|
@ -424,15 +425,31 @@ static void throttle_group_restart_queue(ThrottleGroupMember *tgm, bool is_write
|
||||||
rd->tgm = tgm;
|
rd->tgm = tgm;
|
||||||
rd->is_write = is_write;
|
rd->is_write = is_write;
|
||||||
|
|
||||||
|
/* This function is called when a timer is fired or when
|
||||||
|
* throttle_group_restart_tgm() is called. Either way, there can
|
||||||
|
* be no timer pending on this tgm at this point */
|
||||||
|
assert(!timer_pending(tgm->throttle_timers.timers[is_write]));
|
||||||
|
|
||||||
co = qemu_coroutine_create(throttle_group_restart_queue_entry, rd);
|
co = qemu_coroutine_create(throttle_group_restart_queue_entry, rd);
|
||||||
aio_co_enter(tgm->aio_context, co);
|
aio_co_enter(tgm->aio_context, co);
|
||||||
}
|
}
|
||||||
|
|
||||||
void throttle_group_restart_tgm(ThrottleGroupMember *tgm)
|
void throttle_group_restart_tgm(ThrottleGroupMember *tgm)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (tgm->throttle_state) {
|
if (tgm->throttle_state) {
|
||||||
throttle_group_restart_queue(tgm, 0);
|
for (i = 0; i < 2; i++) {
|
||||||
throttle_group_restart_queue(tgm, 1);
|
QEMUTimer *t = tgm->throttle_timers.timers[i];
|
||||||
|
if (timer_pending(t)) {
|
||||||
|
/* If there's a pending timer on this tgm, fire it now */
|
||||||
|
timer_del(t);
|
||||||
|
timer_cb(tgm, i);
|
||||||
|
} else {
|
||||||
|
/* Else run the next request from the queue manually */
|
||||||
|
throttle_group_restart_queue(tgm, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,16 +584,11 @@ void throttle_group_unregister_tgm(ThrottleGroupMember *tgm)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(tgm->pending_reqs[0] == 0 && tgm->pending_reqs[1] == 0);
|
|
||||||
assert(qemu_co_queue_empty(&tgm->throttled_reqs[0]));
|
|
||||||
assert(qemu_co_queue_empty(&tgm->throttled_reqs[1]));
|
|
||||||
|
|
||||||
qemu_mutex_lock(&tg->lock);
|
qemu_mutex_lock(&tg->lock);
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
if (timer_pending(tgm->throttle_timers.timers[i])) {
|
assert(tgm->pending_reqs[i] == 0);
|
||||||
tg->any_timer_armed[i] = false;
|
assert(qemu_co_queue_empty(&tgm->throttled_reqs[i]));
|
||||||
schedule_next_request(tgm, i);
|
assert(!timer_pending(tgm->throttle_timers.timers[i]));
|
||||||
}
|
|
||||||
if (tg->tokens[i] == tgm) {
|
if (tg->tokens[i] == tgm) {
|
||||||
token = throttle_group_next_tgm(tgm);
|
token = throttle_group_next_tgm(tgm);
|
||||||
/* Take care of the case where this is the last tgm in the group */
|
/* Take care of the case where this is the last tgm in the group */
|
||||||
|
|
Loading…
Reference in New Issue