mirror of
https://github.com/qemu/qemu.git
synced 2024-11-30 07:13:38 +08:00
block: Move I/O throttling configuration functions to BlockBackend
Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Alberto Garcia <berto@igalia.com> Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
441565b279
commit
97148076e8
2
block.c
2
block.c
@ -2123,7 +2123,7 @@ static void bdrv_close(BlockDriverState *bs)
|
||||
|
||||
/* Disable I/O limits and drain all pending throttled requests */
|
||||
if (bs->blk && blk_get_public(bs->blk)->throttle_state) {
|
||||
bdrv_io_limits_disable(bs);
|
||||
blk_io_limits_disable(bs->blk);
|
||||
}
|
||||
|
||||
bdrv_drained_begin(bs); /* complete I/O */
|
||||
|
@ -442,7 +442,7 @@ void blk_remove_bs(BlockBackend *blk)
|
||||
|
||||
blk_update_root_state(blk);
|
||||
if (blk->public.throttle_state) {
|
||||
bdrv_io_limits_disable(blk->root->bs);
|
||||
blk_io_limits_disable(blk);
|
||||
}
|
||||
|
||||
blk->root->bs->blk = NULL;
|
||||
@ -1556,7 +1556,7 @@ void blk_apply_root_state(BlockBackend *blk, BlockDriverState *bs)
|
||||
{
|
||||
bs->detect_zeroes = blk->root_state.detect_zeroes;
|
||||
if (blk->root_state.throttle_group) {
|
||||
bdrv_io_limits_enable(bs, blk->root_state.throttle_group);
|
||||
blk_io_limits_enable(blk, blk->root_state.throttle_group);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1620,3 +1620,42 @@ int blk_flush_all(void)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* throttling disk I/O limits */
|
||||
void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg)
|
||||
{
|
||||
throttle_group_config(blk, cfg);
|
||||
}
|
||||
|
||||
void blk_io_limits_disable(BlockBackend *blk)
|
||||
{
|
||||
assert(blk->public.throttle_state);
|
||||
bdrv_no_throttling_begin(blk_bs(blk));
|
||||
throttle_group_unregister_blk(blk);
|
||||
bdrv_no_throttling_end(blk_bs(blk));
|
||||
}
|
||||
|
||||
/* should be called before blk_set_io_limits if a limit is set */
|
||||
void blk_io_limits_enable(BlockBackend *blk, const char *group)
|
||||
{
|
||||
assert(!blk->public.throttle_state);
|
||||
throttle_group_register_blk(blk, group);
|
||||
}
|
||||
|
||||
void blk_io_limits_update_group(BlockBackend *blk, const char *group)
|
||||
{
|
||||
/* this BB is not part of any group */
|
||||
if (!blk->public.throttle_state) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* this BB is a part of the same group than the one we want */
|
||||
if (!g_strcmp0(throttle_group_get_name(blk), group)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* need to change the group this bs belong to */
|
||||
blk_io_limits_disable(blk);
|
||||
blk_io_limits_enable(blk, group);
|
||||
}
|
||||
|
41
block/io.c
41
block/io.c
@ -46,13 +46,6 @@ static void coroutine_fn bdrv_co_do_rw(void *opaque);
|
||||
static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
|
||||
int64_t sector_num, int nb_sectors, BdrvRequestFlags flags);
|
||||
|
||||
/* throttling disk I/O limits */
|
||||
void bdrv_set_io_limits(BlockDriverState *bs,
|
||||
ThrottleConfig *cfg)
|
||||
{
|
||||
throttle_group_config(bs, cfg);
|
||||
}
|
||||
|
||||
void bdrv_no_throttling_begin(BlockDriverState *bs)
|
||||
{
|
||||
if (!bs->blk) {
|
||||
@ -77,40 +70,6 @@ void bdrv_no_throttling_end(BlockDriverState *bs)
|
||||
--blkp->io_limits_disabled;
|
||||
}
|
||||
|
||||
void bdrv_io_limits_disable(BlockDriverState *bs)
|
||||
{
|
||||
assert(blk_get_public(bs->blk)->throttle_state);
|
||||
bdrv_no_throttling_begin(bs);
|
||||
throttle_group_unregister_blk(bs->blk);
|
||||
bdrv_no_throttling_end(bs);
|
||||
}
|
||||
|
||||
/* should be called before bdrv_set_io_limits if a limit is set */
|
||||
void bdrv_io_limits_enable(BlockDriverState *bs, const char *group)
|
||||
{
|
||||
BlockBackendPublic *blkp = blk_get_public(bs->blk);
|
||||
|
||||
assert(!blkp->throttle_state);
|
||||
throttle_group_register_blk(bs->blk, group);
|
||||
}
|
||||
|
||||
void bdrv_io_limits_update_group(BlockDriverState *bs, const char *group)
|
||||
{
|
||||
/* this bs is not part of any group */
|
||||
if (!blk_get_public(bs->blk)->throttle_state) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* this bs is a part of the same group than the one we want */
|
||||
if (!g_strcmp0(throttle_group_get_name(bs->blk), group)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* need to change the group this bs belong to */
|
||||
bdrv_io_limits_disable(bs);
|
||||
bdrv_io_limits_enable(bs, group);
|
||||
}
|
||||
|
||||
void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
BlockDriver *drv = bs->drv;
|
||||
|
@ -70,7 +70,7 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
|
||||
if (bs->blk && blk_get_public(bs->blk)->throttle_state) {
|
||||
ThrottleConfig cfg;
|
||||
|
||||
throttle_group_get_config(bs, &cfg);
|
||||
throttle_group_get_config(bs->blk, &cfg);
|
||||
|
||||
info->bps = cfg.buckets[THROTTLE_BPS_TOTAL].avg;
|
||||
info->bps_rd = cfg.buckets[THROTTLE_BPS_READ].avg;
|
||||
|
@ -337,12 +337,12 @@ void throttle_group_restart_blk(BlockBackend *blk)
|
||||
* to throttle_config(), but guarantees atomicity within the
|
||||
* throttling group.
|
||||
*
|
||||
* @bs: a BlockDriverState that is member of the group
|
||||
* @blk: a BlockBackend that is a member of the group
|
||||
* @cfg: the configuration to set
|
||||
*/
|
||||
void throttle_group_config(BlockDriverState *bs, ThrottleConfig *cfg)
|
||||
void throttle_group_config(BlockBackend *blk, ThrottleConfig *cfg)
|
||||
{
|
||||
BlockBackendPublic *blkp = blk_get_public(bs->blk);
|
||||
BlockBackendPublic *blkp = blk_get_public(blk);
|
||||
ThrottleTimers *tt = &blkp->throttle_timers;
|
||||
ThrottleState *ts = blkp->throttle_state;
|
||||
ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
|
||||
@ -365,12 +365,12 @@ void throttle_group_config(BlockDriverState *bs, ThrottleConfig *cfg)
|
||||
* throttle_get_config(), but guarantees atomicity within the
|
||||
* throttling group.
|
||||
*
|
||||
* @bs: a BlockDriverState that is member of the group
|
||||
* @blk: a BlockBackend that is a member of the group
|
||||
* @cfg: the configuration will be written here
|
||||
*/
|
||||
void throttle_group_get_config(BlockDriverState *bs, ThrottleConfig *cfg)
|
||||
void throttle_group_get_config(BlockBackend *blk, ThrottleConfig *cfg)
|
||||
{
|
||||
BlockBackendPublic *blkp = blk_get_public(bs->blk);
|
||||
BlockBackendPublic *blkp = blk_get_public(blk);
|
||||
ThrottleState *ts = blkp->throttle_state;
|
||||
ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
|
||||
qemu_mutex_lock(&tg->lock);
|
||||
|
16
blockdev.c
16
blockdev.c
@ -616,8 +616,8 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
|
||||
if (!throttling_group) {
|
||||
throttling_group = blk_name(blk);
|
||||
}
|
||||
bdrv_io_limits_enable(bs, throttling_group);
|
||||
bdrv_set_io_limits(bs, &cfg);
|
||||
blk_io_limits_enable(blk, throttling_group);
|
||||
blk_set_io_limits(blk, &cfg);
|
||||
}
|
||||
|
||||
if (bdrv_key_required(bs)) {
|
||||
@ -2726,16 +2726,16 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
|
||||
if (throttle_enabled(&cfg)) {
|
||||
/* Enable I/O limits if they're not enabled yet, otherwise
|
||||
* just update the throttling group. */
|
||||
if (!blk_get_public(bs->blk)->throttle_state) {
|
||||
bdrv_io_limits_enable(bs, has_group ? group : device);
|
||||
if (!blk_get_public(blk)->throttle_state) {
|
||||
blk_io_limits_enable(blk, has_group ? group : device);
|
||||
} else if (has_group) {
|
||||
bdrv_io_limits_update_group(bs, group);
|
||||
blk_io_limits_update_group(blk, group);
|
||||
}
|
||||
/* Set the new throttling configuration */
|
||||
bdrv_set_io_limits(bs, &cfg);
|
||||
} else if (blk_get_public(bs->blk)->throttle_state) {
|
||||
blk_set_io_limits(blk, &cfg);
|
||||
} else if (blk_get_public(blk)->throttle_state) {
|
||||
/* If all throttling settings are set to 0, disable I/O limits */
|
||||
bdrv_io_limits_disable(bs);
|
||||
blk_io_limits_disable(blk);
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -187,10 +187,6 @@ void bdrv_stats_print(Monitor *mon, const QObject *data);
|
||||
void bdrv_info_stats(Monitor *mon, QObject **ret_data);
|
||||
|
||||
/* disk I/O throttling */
|
||||
void bdrv_io_limits_enable(BlockDriverState *bs, const char *group);
|
||||
void bdrv_io_limits_disable(BlockDriverState *bs);
|
||||
void bdrv_io_limits_update_group(BlockDriverState *bs, const char *group);
|
||||
|
||||
void bdrv_init(void);
|
||||
void bdrv_init_with_whitelist(void);
|
||||
bool bdrv_uses_whitelist(void);
|
||||
|
@ -525,8 +525,7 @@ int get_tmp_filename(char *filename, int size);
|
||||
BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
|
||||
const char *filename);
|
||||
|
||||
void bdrv_set_io_limits(BlockDriverState *bs,
|
||||
ThrottleConfig *cfg);
|
||||
bool bdrv_start_throttled_reqs(BlockDriverState *bs);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -33,8 +33,8 @@ const char *throttle_group_get_name(BlockBackend *blk);
|
||||
ThrottleState *throttle_group_incref(const char *name);
|
||||
void throttle_group_unref(ThrottleState *ts);
|
||||
|
||||
void throttle_group_config(BlockDriverState *bs, ThrottleConfig *cfg);
|
||||
void throttle_group_get_config(BlockDriverState *bs, ThrottleConfig *cfg);
|
||||
void throttle_group_config(BlockBackend *blk, ThrottleConfig *cfg);
|
||||
void throttle_group_get_config(BlockBackend *blk, ThrottleConfig *cfg);
|
||||
|
||||
void throttle_group_register_blk(BlockBackend *blk, const char *groupname);
|
||||
void throttle_group_unregister_blk(BlockBackend *blk);
|
||||
|
@ -212,4 +212,9 @@ BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
|
||||
BlockCompletionFunc *cb,
|
||||
void *opaque, int ret);
|
||||
|
||||
void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg);
|
||||
void blk_io_limits_disable(BlockBackend *blk);
|
||||
void blk_io_limits_enable(BlockBackend *blk, const char *group);
|
||||
void blk_io_limits_update_group(BlockBackend *blk, const char *group);
|
||||
|
||||
#endif
|
||||
|
@ -577,15 +577,11 @@ static void test_groups(void)
|
||||
ThrottleConfig cfg1, cfg2;
|
||||
BlockBackend *blk1, *blk2, *blk3;
|
||||
BlockBackendPublic *blkp1, *blkp2, *blkp3;
|
||||
BlockDriverState *bdrv1, *bdrv3;
|
||||
|
||||
blk1 = blk_new_with_bs(&error_abort);
|
||||
blk2 = blk_new_with_bs(&error_abort);
|
||||
blk3 = blk_new_with_bs(&error_abort);
|
||||
|
||||
bdrv1 = blk_bs(blk1);
|
||||
bdrv3 = blk_bs(blk3);
|
||||
|
||||
blkp1 = blk_get_public(blk1);
|
||||
blkp2 = blk_get_public(blk2);
|
||||
blkp3 = blk_get_public(blk3);
|
||||
@ -612,20 +608,20 @@ static void test_groups(void)
|
||||
cfg1.buckets[THROTTLE_BPS_WRITE].avg = 285000;
|
||||
cfg1.buckets[THROTTLE_OPS_READ].avg = 20000;
|
||||
cfg1.buckets[THROTTLE_OPS_WRITE].avg = 12000;
|
||||
throttle_group_config(bdrv1, &cfg1);
|
||||
throttle_group_config(blk1, &cfg1);
|
||||
|
||||
throttle_group_get_config(bdrv1, &cfg1);
|
||||
throttle_group_get_config(bdrv3, &cfg2);
|
||||
throttle_group_get_config(blk1, &cfg1);
|
||||
throttle_group_get_config(blk3, &cfg2);
|
||||
g_assert(!memcmp(&cfg1, &cfg2, sizeof(cfg1)));
|
||||
|
||||
cfg2.buckets[THROTTLE_BPS_READ].avg = 4547;
|
||||
cfg2.buckets[THROTTLE_BPS_WRITE].avg = 1349;
|
||||
cfg2.buckets[THROTTLE_OPS_READ].avg = 123;
|
||||
cfg2.buckets[THROTTLE_OPS_WRITE].avg = 86;
|
||||
throttle_group_config(bdrv3, &cfg1);
|
||||
throttle_group_config(blk3, &cfg1);
|
||||
|
||||
throttle_group_get_config(bdrv1, &cfg1);
|
||||
throttle_group_get_config(bdrv3, &cfg2);
|
||||
throttle_group_get_config(blk1, &cfg1);
|
||||
throttle_group_get_config(blk3, &cfg2);
|
||||
g_assert(!memcmp(&cfg1, &cfg2, sizeof(cfg1)));
|
||||
|
||||
throttle_group_unregister_blk(blk1);
|
||||
|
Loading…
Reference in New Issue
Block a user