mirror of https://github.com/xemu-project/xemu.git
block: add clock_type field to ThrottleGroup
Clock type in throttling is currently inferred by the ThrottleTimer's clock type even though it is a per-ThrottleGroup property; it doesn't make sense to have different clock types in the same group. Moving this to a field in ThrottleGroup can simplify some of the throttle functions. Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
b1e1fa0c3a
commit
dbe824cc57
|
@ -61,6 +61,7 @@ typedef struct ThrottleGroup {
|
||||||
QLIST_HEAD(, BlockBackendPublic) head;
|
QLIST_HEAD(, BlockBackendPublic) head;
|
||||||
BlockBackend *tokens[2];
|
BlockBackend *tokens[2];
|
||||||
bool any_timer_armed[2];
|
bool any_timer_armed[2];
|
||||||
|
QEMUClockType clock_type;
|
||||||
|
|
||||||
/* These two are protected by the global throttle_groups_lock */
|
/* These two are protected by the global throttle_groups_lock */
|
||||||
unsigned refcount;
|
unsigned refcount;
|
||||||
|
@ -98,6 +99,12 @@ ThrottleState *throttle_group_incref(const char *name)
|
||||||
if (!tg) {
|
if (!tg) {
|
||||||
tg = g_new0(ThrottleGroup, 1);
|
tg = g_new0(ThrottleGroup, 1);
|
||||||
tg->name = g_strdup(name);
|
tg->name = g_strdup(name);
|
||||||
|
tg->clock_type = QEMU_CLOCK_REALTIME;
|
||||||
|
|
||||||
|
if (qtest_enabled()) {
|
||||||
|
/* For testing block IO throttling only */
|
||||||
|
tg->clock_type = QEMU_CLOCK_VIRTUAL;
|
||||||
|
}
|
||||||
qemu_mutex_init(&tg->lock);
|
qemu_mutex_init(&tg->lock);
|
||||||
throttle_init(&tg->ts);
|
throttle_init(&tg->ts);
|
||||||
QLIST_INIT(&tg->head);
|
QLIST_INIT(&tg->head);
|
||||||
|
@ -310,7 +317,7 @@ static void schedule_next_request(BlockBackend *blk, bool is_write)
|
||||||
token = blk;
|
token = blk;
|
||||||
} else {
|
} else {
|
||||||
ThrottleTimers *tt = &blk_get_public(token)->throttle_timers;
|
ThrottleTimers *tt = &blk_get_public(token)->throttle_timers;
|
||||||
int64_t now = qemu_clock_get_ns(tt->clock_type);
|
int64_t now = qemu_clock_get_ns(tg->clock_type);
|
||||||
timer_mod(tt->timers[is_write], now);
|
timer_mod(tt->timers[is_write], now);
|
||||||
tg->any_timer_armed[is_write] = true;
|
tg->any_timer_armed[is_write] = true;
|
||||||
}
|
}
|
||||||
|
@ -430,7 +437,7 @@ void throttle_group_config(BlockBackend *blk, ThrottleConfig *cfg)
|
||||||
if (timer_pending(tt->timers[1])) {
|
if (timer_pending(tt->timers[1])) {
|
||||||
tg->any_timer_armed[1] = false;
|
tg->any_timer_armed[1] = false;
|
||||||
}
|
}
|
||||||
throttle_config(ts, tt, cfg);
|
throttle_config(ts, tg->clock_type, tt, cfg);
|
||||||
qemu_mutex_unlock(&tg->lock);
|
qemu_mutex_unlock(&tg->lock);
|
||||||
|
|
||||||
throttle_group_restart_blk(blk);
|
throttle_group_restart_blk(blk);
|
||||||
|
@ -497,13 +504,6 @@ void throttle_group_register_blk(BlockBackend *blk, const char *groupname)
|
||||||
BlockBackendPublic *blkp = blk_get_public(blk);
|
BlockBackendPublic *blkp = blk_get_public(blk);
|
||||||
ThrottleState *ts = throttle_group_incref(groupname);
|
ThrottleState *ts = throttle_group_incref(groupname);
|
||||||
ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
|
ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
|
||||||
int clock_type = QEMU_CLOCK_REALTIME;
|
|
||||||
|
|
||||||
if (qtest_enabled()) {
|
|
||||||
/* For testing block IO throttling only */
|
|
||||||
clock_type = QEMU_CLOCK_VIRTUAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
blkp->throttle_state = ts;
|
blkp->throttle_state = ts;
|
||||||
|
|
||||||
qemu_mutex_lock(&tg->lock);
|
qemu_mutex_lock(&tg->lock);
|
||||||
|
@ -518,7 +518,7 @@ void throttle_group_register_blk(BlockBackend *blk, const char *groupname)
|
||||||
|
|
||||||
throttle_timers_init(&blkp->throttle_timers,
|
throttle_timers_init(&blkp->throttle_timers,
|
||||||
blk_get_aio_context(blk),
|
blk_get_aio_context(blk),
|
||||||
clock_type,
|
tg->clock_type,
|
||||||
read_timer_cb,
|
read_timer_cb,
|
||||||
write_timer_cb,
|
write_timer_cb,
|
||||||
blk);
|
blk);
|
||||||
|
|
|
@ -86,7 +86,7 @@ void fsdev_throttle_init(FsThrottle *fst)
|
||||||
fsdev_throttle_read_timer_cb,
|
fsdev_throttle_read_timer_cb,
|
||||||
fsdev_throttle_write_timer_cb,
|
fsdev_throttle_write_timer_cb,
|
||||||
fst);
|
fst);
|
||||||
throttle_config(&fst->ts, &fst->tt, &fst->cfg);
|
throttle_config(&fst->ts, QEMU_CLOCK_REALTIME, &fst->tt, &fst->cfg);
|
||||||
qemu_co_queue_init(&fst->throttled_reqs[0]);
|
qemu_co_queue_init(&fst->throttled_reqs[0]);
|
||||||
qemu_co_queue_init(&fst->throttled_reqs[1]);
|
qemu_co_queue_init(&fst->throttled_reqs[1]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,7 @@ bool throttle_enabled(ThrottleConfig *cfg);
|
||||||
bool throttle_is_valid(ThrottleConfig *cfg, Error **errp);
|
bool throttle_is_valid(ThrottleConfig *cfg, Error **errp);
|
||||||
|
|
||||||
void throttle_config(ThrottleState *ts,
|
void throttle_config(ThrottleState *ts,
|
||||||
|
QEMUClockType clock_type,
|
||||||
ThrottleTimers *tt,
|
ThrottleTimers *tt,
|
||||||
ThrottleConfig *cfg);
|
ThrottleConfig *cfg);
|
||||||
|
|
||||||
|
|
|
@ -228,7 +228,7 @@ static void test_config_functions(void)
|
||||||
read_timer_cb, write_timer_cb, &ts);
|
read_timer_cb, write_timer_cb, &ts);
|
||||||
/* structure reset by throttle_init previous_leak should be null */
|
/* structure reset by throttle_init previous_leak should be null */
|
||||||
g_assert(!ts.previous_leak);
|
g_assert(!ts.previous_leak);
|
||||||
throttle_config(&ts, &tt, &orig_cfg);
|
throttle_config(&ts, QEMU_CLOCK_VIRTUAL, &tt, &orig_cfg);
|
||||||
|
|
||||||
/* has previous leak been initialized by throttle_config ? */
|
/* has previous leak been initialized by throttle_config ? */
|
||||||
g_assert(ts.previous_leak);
|
g_assert(ts.previous_leak);
|
||||||
|
@ -486,7 +486,7 @@ static bool do_test_accounting(bool is_ops, /* are we testing bps or ops */
|
||||||
throttle_init(&ts);
|
throttle_init(&ts);
|
||||||
throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
|
throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
|
||||||
read_timer_cb, write_timer_cb, &ts);
|
read_timer_cb, write_timer_cb, &ts);
|
||||||
throttle_config(&ts, &tt, &cfg);
|
throttle_config(&ts, QEMU_CLOCK_VIRTUAL, &tt, &cfg);
|
||||||
|
|
||||||
/* account a read */
|
/* account a read */
|
||||||
throttle_account(&ts, false, size);
|
throttle_account(&ts, false, size);
|
||||||
|
|
|
@ -399,10 +399,12 @@ static void throttle_cancel_timer(QEMUTimer *timer)
|
||||||
/* Used to configure the throttle
|
/* Used to configure the throttle
|
||||||
*
|
*
|
||||||
* @ts: the throttle state we are working on
|
* @ts: the throttle state we are working on
|
||||||
|
* @clock_type: the group's clock_type
|
||||||
* @tt: the throttle timers we use in this aio context
|
* @tt: the throttle timers we use in this aio context
|
||||||
* @cfg: the config to set
|
* @cfg: the config to set
|
||||||
*/
|
*/
|
||||||
void throttle_config(ThrottleState *ts,
|
void throttle_config(ThrottleState *ts,
|
||||||
|
QEMUClockType clock_type,
|
||||||
ThrottleTimers *tt,
|
ThrottleTimers *tt,
|
||||||
ThrottleConfig *cfg)
|
ThrottleConfig *cfg)
|
||||||
{
|
{
|
||||||
|
@ -414,7 +416,7 @@ void throttle_config(ThrottleState *ts,
|
||||||
throttle_fix_bucket(&ts->cfg.buckets[i]);
|
throttle_fix_bucket(&ts->cfg.buckets[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ts->previous_leak = qemu_clock_get_ns(tt->clock_type);
|
ts->previous_leak = qemu_clock_get_ns(clock_type);
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
throttle_cancel_timer(tt->timers[i]);
|
throttle_cancel_timer(tt->timers[i]);
|
||||||
|
|
Loading…
Reference in New Issue