From: Kevin Wolf <kwolf@redhat.com>
To: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
Cc: zwu.kernel@gmail.com, ryanh@us.ibm.com, qemu-devel@nongnu.org,
stefanha@linux.vnet.ibm.com
Subject: Re: [Qemu-devel] [PATCH v12 4/5] hmp/qmp: add block_set_io_throttle
Date: Mon, 07 Nov 2011 16:26:20 +0100 [thread overview]
Message-ID: <4EB7F89C.2020406@redhat.com> (raw)
In-Reply-To: <1320310649-7639-5-git-send-email-wuzhy@linux.vnet.ibm.com>
Am 03.11.2011 09:57, schrieb Zhi Yong Wu:
> Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
> Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> ---
> block.c | 15 +++++++++++++
> blockdev.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> blockdev.h | 2 +
> hmp-commands.hx | 15 +++++++++++++
> hmp.c | 10 +++++++++
> qapi-schema.json | 16 +++++++++++++-
> qerror.c | 4 +++
> qerror.h | 3 ++
> qmp-commands.hx | 53 +++++++++++++++++++++++++++++++++++++++++++++++-
> 9 files changed, 175 insertions(+), 2 deletions(-)
>
> diff --git a/block.c b/block.c
> index b2af48f..ed6fe20 100644
> --- a/block.c
> +++ b/block.c
> @@ -1971,6 +1971,21 @@ BlockInfoList *qmp_query_block(Error **errp)
> info->value->inserted->has_backing_file = true;
> info->value->inserted->backing_file = g_strdup(bs->backing_file);
> }
> +
> + if (bs->io_limits_enabled) {
> + info->value->inserted->bps =
> + bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL];
> + info->value->inserted->bps_rd =
> + bs->io_limits.bps[BLOCK_IO_LIMIT_READ];
> + info->value->inserted->bps_wr =
> + bs->io_limits.bps[BLOCK_IO_LIMIT_WRITE];
> + info->value->inserted->iops =
> + bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL];
> + info->value->inserted->iops_rd =
> + bs->io_limits.iops[BLOCK_IO_LIMIT_READ];
> + info->value->inserted->iops_wr =
> + bs->io_limits.iops[BLOCK_IO_LIMIT_WRITE];
> + }
> }
>
> /* XXX: waiting for the qapi to support GSList */
> diff --git a/blockdev.c b/blockdev.c
> index 651828c..95d1faa 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -757,6 +757,65 @@ int do_change_block(Monitor *mon, const char *device,
> return monitor_read_bdrv_key_start(mon, bs, NULL, NULL);
> }
>
> +/* throttling disk I/O limits */
> +int do_block_set_io_throttle(Monitor *mon,
> + const QDict *qdict, QObject **ret_data)
> +{
> + BlockIOLimit io_limits;
> + const char *devname = qdict_get_str(qdict, "device");
> + BlockDriverState *bs;
> +
> + io_limits.bps[BLOCK_IO_LIMIT_TOTAL]
> + = qdict_get_try_int(qdict, "bps", -1);
> + io_limits.bps[BLOCK_IO_LIMIT_READ]
> + = qdict_get_try_int(qdict, "bps_rd", -1);
> + io_limits.bps[BLOCK_IO_LIMIT_WRITE]
> + = qdict_get_try_int(qdict, "bps_wr", -1);
> + io_limits.iops[BLOCK_IO_LIMIT_TOTAL]
> + = qdict_get_try_int(qdict, "iops", -1);
> + io_limits.iops[BLOCK_IO_LIMIT_READ]
> + = qdict_get_try_int(qdict, "iops_rd", -1);
> + io_limits.iops[BLOCK_IO_LIMIT_WRITE]
> + = qdict_get_try_int(qdict, "iops_wr", -1);
> +
> + bs = bdrv_find(devname);
> + if (!bs) {
> + qerror_report(QERR_DEVICE_NOT_FOUND, devname);
> + return -1;
> + }
> +
> + if ((io_limits.bps[BLOCK_IO_LIMIT_TOTAL] == -1)
> + || (io_limits.bps[BLOCK_IO_LIMIT_READ] == -1)
> + || (io_limits.bps[BLOCK_IO_LIMIT_WRITE] == -1)
> + || (io_limits.iops[BLOCK_IO_LIMIT_TOTAL] == -1)
> + || (io_limits.iops[BLOCK_IO_LIMIT_READ] == -1)
> + || (io_limits.iops[BLOCK_IO_LIMIT_WRITE] == -1)) {
> + qerror_report(QERR_MISSING_PARAMETER,
> + "bps/bps_rd/bps_wr/iops/iops_rd/iops_wr");
> + return -1;
> + }
Here you require that all parameters are set...
> +
> + if (!do_check_io_limits(&io_limits)) {
> + qerror_report(QERR_INVALID_PARAMETER_COMBINATION);
> + return -1;
> + }
> +
> + bs->io_limits = io_limits;
> + bs->slice_time = BLOCK_IO_SLICE_TIME;
> +
> + if (!bs->io_limits_enabled && bdrv_io_limits_enabled(bs)) {
> + bdrv_io_limits_enable(bs);
> + } else if (bs->io_limits_enabled && !bdrv_io_limits_enabled(bs)) {
> + bdrv_io_limits_disable(bs);
> + } else {
> + if (bs->block_timer) {
> + qemu_mod_timer(bs->block_timer, qemu_get_clock_ns(vm_clock));
> + }
> + }
> +
> + return 0;
> +}
> +
> int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
> {
> const char *id = qdict_get_str(qdict, "id");
> diff --git a/blockdev.h b/blockdev.h
> index 3587786..1b48a75 100644
> --- a/blockdev.h
> +++ b/blockdev.h
> @@ -63,6 +63,8 @@ int do_block_set_passwd(Monitor *mon, const QDict *qdict, QObject **ret_data);
> int do_change_block(Monitor *mon, const char *device,
> const char *filename, const char *fmt);
> int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
> +int do_block_set_io_throttle(Monitor *mon,
> + const QDict *qdict, QObject **ret_data);
> int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data);
> int do_block_resize(Monitor *mon, const QDict *qdict, QObject **ret_data);
>
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 089c1ac..48f3c21 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1207,6 +1207,21 @@ ETEXI
> },
>
> STEXI
> +@item block_set_io_throttle @var{device} @var{bps} @var{bps_rd} @var{bps_wr} @var{iops} @var{iops_rd} @var{iops_wr}
> +@findex block_set_io_throttle
> +Change I/O throttle limits for a block drive to @var{bps} @var{bps_rd} @var{bps_wr} @var{iops} @var{iops_rd} @var{iops_wr}
> +ETEXI
> +
> + {
> + .name = "block_set_io_throttle",
> + .args_type = "device:B,bps:i?,bps_rd:i?,bps_wr:i?,iops:i?,iops_rd:i?,iops_wr:i?",
> + .params = "device [bps] [bps_rd] [bps_wr] [iops] [iops_rd] [iops_wr]",
> + .help = "change I/O throttle limits for a block drive",
> + .user_print = monitor_user_noop,
> + .mhandler.cmd_new = do_block_set_io_throttle,
> + },
> +
...but here....
> +STEXI
> @item block_passwd @var{device} @var{password}
> @findex block_passwd
> Set the encrypted device @var{device} password to @var{password}
> diff --git a/hmp.c b/hmp.c
> index 443d3a7..dfab7ad 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -216,6 +216,16 @@ void hmp_info_block(Monitor *mon)
> info->value->inserted->ro,
> info->value->inserted->drv,
> info->value->inserted->encrypted);
> +
> + monitor_printf(mon, " bps=%" PRId64 " bps_rd=%" PRId64
> + " bps_wr=%" PRId64 " iops=%" PRId64
> + " iops_rd=%" PRId64 " iops_wr=%" PRId64,
> + info->value->inserted->bps,
> + info->value->inserted->bps_rd,
> + info->value->inserted->bps_wr,
> + info->value->inserted->iops,
> + info->value->inserted->iops_rd,
> + info->value->inserted->iops_wr);
> } else {
> monitor_printf(mon, " [not inserted]");
> }
> diff --git a/qapi-schema.json b/qapi-schema.json
> index cb1ba77..734076b 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -370,13 +370,27 @@
> #
> # @encrypted: true if the backing device is encrypted
> #
> +# @bps: #optional if total throughput limit in bytes per second is specified
> +#
> +# @bps_rd: #optional if read throughput limit in bytes per second is specified
> +#
> +# @bps_wr: #optional if write throughput limit in bytes per second is specified
> +#
> +# @iops: #optional if total I/O operations per second is specified
> +#
> +# @iops_rd: #optional if read I/O operations per second is specified
> +#
> +# @iops_wr: #optional if write I/O operations per second is specified
> +#
> # Since: 0.14.0
> #
> # Notes: This interface is only found in @BlockInfo.
> ##
> { 'type': 'BlockDeviceInfo',
> 'data': { 'file': 'str', 'ro': 'bool', 'drv': 'str',
> - '*backing_file': 'str', 'encrypted': 'bool' } }
> + '*backing_file': 'str', 'encrypted': 'bool',
> + 'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
> + 'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int'} }
>
> ##
> # @BlockDeviceIoStatus:
> diff --git a/qerror.c b/qerror.c
> index 4b48b39..807fb55 100644
> --- a/qerror.c
> +++ b/qerror.c
> @@ -238,6 +238,10 @@ static const QErrorStringTable qerror_table[] = {
> .error_fmt = QERR_QGA_COMMAND_FAILED,
> .desc = "Guest agent command failed, error was '%(message)'",
> },
> + {
> + .error_fmt = QERR_INVALID_PARAMETER_COMBINATION,
> + .desc = "Invalid paramter combination",
> + },
> {}
> };
>
> diff --git a/qerror.h b/qerror.h
> index d4bfcfd..777a36a 100644
> --- a/qerror.h
> +++ b/qerror.h
> @@ -198,4 +198,7 @@ QError *qobject_to_qerror(const QObject *obj);
> #define QERR_QGA_COMMAND_FAILED \
> "{ 'class': 'QgaCommandFailed', 'data': { 'message': %s } }"
>
> +#define QERR_INVALID_PARAMETER_COMBINATION \
> + "{ 'class': 'InvalidParameterCombination', 'data': {} }"
> +
> #endif /* QERROR_H */
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index 97975a5..cdc3c18 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -851,6 +851,44 @@ Example:
> EQMP
>
> {
> + .name = "block_set_io_throttle",
> + .args_type = "device:B,bps:i?,bps_rd:i?,bps_wr:i?,iops:i?,iops_rd:i?,iops_wr:i?",
> + .params = "device [bps] [bps_rd] [bps_wr] [iops] [iops_rd] [iops_wr]",
> + .help = "change I/O throttle limits for a block drive",
> + .user_print = monitor_user_noop,
> + .mhandler.cmd_new = do_block_set_io_throttle,
> + },
> +
> +SQMP
> +block_set_io_throttle
> +------------
> +
> +Change I/O throttle limits for a block drive.
> +
> +Arguments:
> +
> +- "device": device name (json-string)
> +- "bps": total throughput limit in bytes per second(json-int, optional)
> +- "bps_rd": read throughput limit in bytes per second(json-int, optional)
> +- "bps_wr": read throughput limit in bytes per second(json-int, optional)
> +- "iops": total I/O operations per second(json-int, optional)
> +- "iops_rd": read I/O operations per second(json-int, optional)
> +- "iops_wr": write I/O operations per second(json-int, optional)
...and here they are described as optional. One part is wrong, though I
don't know which one.
Kevin
next prev parent reply other threads:[~2011-11-07 15:23 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-03 8:57 [Qemu-devel] [PATCH v12 0/5] The intro to QEMU block I/O throttling Zhi Yong Wu
2011-11-03 8:57 ` [Qemu-devel] [PATCH v12 1/5] block: add the blockio limits command line support Zhi Yong Wu
2011-11-03 8:57 ` [Qemu-devel] [PATCH v12 2/5] CoQueue: introduce qemu_co_queue_wait_insert_head Zhi Yong Wu
2011-11-03 8:57 ` [Qemu-devel] [PATCH v12 3/5] block: add I/O throttling algorithm Zhi Yong Wu
2011-11-07 15:18 ` Kevin Wolf
2011-11-08 4:34 ` Zhi Yong Wu
2011-11-08 8:41 ` Kevin Wolf
2011-11-08 8:57 ` Zhi Yong Wu
2011-11-03 8:57 ` [Qemu-devel] [PATCH v12 4/5] hmp/qmp: add block_set_io_throttle Zhi Yong Wu
2011-11-07 15:26 ` Kevin Wolf [this message]
2011-11-08 2:21 ` Zhi Yong Wu
2011-11-03 8:57 ` [Qemu-devel] [PATCH v12 5/5] block: perf testing report based on block I/O throttling Zhi Yong Wu
2011-11-07 15:27 ` Kevin Wolf
2011-11-08 2:15 ` Zhi Yong Wu
-- strict thread matches above, loose matches on Subject: below --
2011-11-08 5:00 [Qemu-devel] [PATCH v12 4/5] hmp/qmp: add block_set_io_throttle Zhi Yong Wu
2011-11-08 10:12 ` Kevin Wolf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4EB7F89C.2020406@redhat.com \
--to=kwolf@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=ryanh@us.ibm.com \
--cc=stefanha@linux.vnet.ibm.com \
--cc=wuzhy@linux.vnet.ibm.com \
--cc=zwu.kernel@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.