qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: zhenwei pi <pizhenwei@bytedance.com>
To: kwolf@redhat.com, mreitz@redhat.com
Cc: fam@euphon.net, qemu-block@nongnu.org, vsementsov@virtuozzo.com,
	qemu-devel@nongnu.org, pizhenwei@bytedance.com
Subject: [Qemu-devel] [PATCH 3/3] qapi: add block size histogram interface
Date: Thu, 20 Jun 2019 16:54:32 +0800	[thread overview]
Message-ID: <1561020872-6214-4-git-send-email-pizhenwei@bytedance.com> (raw)
In-Reply-To: <1561020872-6214-1-git-send-email-pizhenwei@bytedance.com>

Set/Clear block size histograms through new command
x-block-size-histogram-set and show new statistics in
query-blockstats results.

Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
---
 block/qapi.c         |  24 ++++++++++++
 blockdev.c           |  56 +++++++++++++++++++++++++++
 qapi/block-core.json | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 184 insertions(+), 1 deletion(-)

diff --git a/block/qapi.c b/block/qapi.c
index f3a84f776e..04edbd5243 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -428,6 +428,20 @@ static void bdrv_latency_histogram_stats(BlockHistogram *hist,
     }
 }
 
+static void bdrv_size_histogram_stats(BlockHistogram *hist,
+                                         bool *not_null,
+                                         BlockSizeHistogramInfo **info)
+{
+    *not_null = hist->bins != NULL;
+    if (*not_null) {
+        *info = g_new0(BlockSizeHistogramInfo, 1);
+
+        (*info)->boundaries = uint64_list(hist->boundaries, hist->nbins - 1);
+        (*info)->bins = uint64_list(hist->bins, hist->nbins);
+    }
+}
+
+
 static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
 {
     BlockAcctStats *stats = blk_get_stats(blk);
@@ -503,6 +517,16 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
     bdrv_latency_histogram_stats(&stats->latency_histogram[BLOCK_ACCT_FLUSH],
                                  &ds->has_flush_latency_histogram,
                                  &ds->flush_latency_histogram);
+
+    bdrv_size_histogram_stats(&stats->size_histogram[BLOCK_ACCT_READ],
+                                 &ds->has_x_rd_size_histogram,
+                                 &ds->x_rd_size_histogram);
+    bdrv_size_histogram_stats(&stats->size_histogram[BLOCK_ACCT_WRITE],
+                                 &ds->has_x_wr_size_histogram,
+                                 &ds->x_wr_size_histogram);
+    bdrv_size_histogram_stats(&stats->size_histogram[BLOCK_ACCT_FLUSH],
+                                 &ds->has_x_flush_size_histogram,
+                                 &ds->x_flush_size_histogram);
 }
 
 static BlockStats *bdrv_query_bds_stats(BlockDriverState *bs,
diff --git a/blockdev.c b/blockdev.c
index 5d6a13dea9..c3f893891d 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -4563,6 +4563,62 @@ void qmp_block_latency_histogram_set(
     }
 }
 
+void qmp_x_block_size_histogram_set(
+    const char *id,
+    bool has_boundaries, uint64List *boundaries,
+    bool has_boundaries_read, uint64List *boundaries_read,
+    bool has_boundaries_write, uint64List *boundaries_write,
+    bool has_boundaries_flush, uint64List *boundaries_flush,
+    Error **errp)
+{
+    BlockBackend *blk = qmp_get_blk(NULL, id, errp);
+    BlockAcctStats *stats;
+    int ret;
+
+    if (!blk) {
+        return;
+    }
+
+    stats = blk_get_stats(blk);
+
+    if (!has_boundaries && !has_boundaries_read && !has_boundaries_write &&
+        !has_boundaries_flush)
+    {
+        block_size_histograms_clear(stats);
+        return;
+    }
+
+    if (has_boundaries || has_boundaries_read) {
+        ret = block_size_histogram_set(
+            stats, BLOCK_ACCT_READ,
+            has_boundaries_read ? boundaries_read : boundaries);
+        if (ret) {
+            error_setg(errp, "Device '%s' set read boundaries fail", id);
+            return;
+        }
+    }
+
+    if (has_boundaries || has_boundaries_write) {
+        ret = block_size_histogram_set(
+            stats, BLOCK_ACCT_WRITE,
+            has_boundaries_write ? boundaries_write : boundaries);
+        if (ret) {
+            error_setg(errp, "Device '%s' set write boundaries fail", id);
+            return;
+        }
+    }
+
+    if (has_boundaries || has_boundaries_flush) {
+        ret = block_size_histogram_set(
+            stats, BLOCK_ACCT_FLUSH,
+            has_boundaries_flush ? boundaries_flush : boundaries);
+        if (ret) {
+            error_setg(errp, "Device '%s' set flush boundaries fail", id);
+            return;
+        }
+    }
+}
+
 QemuOptsList qemu_common_drive_opts = {
     .name = "drive",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_common_drive_opts.head),
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 0d43d4f37c..cae45c9db5 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -633,6 +633,100 @@
            '*boundaries-flush': ['uint64'] } }
 
 ##
+# @BlockSizeHistogramInfo:
+#
+# Block size histogram.
+#
+# @boundaries: list of interval boundary values in nanoseconds, all greater
+#              than zero and in ascending order.
+#              For example, the list [8193, 32769, 131073] produces the
+#              following histogram intervals:
+#              [0, 8193), [8193, 32769), [32769, 131073), [131073, +inf).
+#
+# @bins: list of io request counts corresponding to histogram intervals.
+#        len(@bins) = len(@boundaries) + 1
+#        For the example above, @bins may be something like [6, 3, 7, 9],
+#        and corresponding histogram looks like:
+#
+# Since: 4.0
+##
+{ 'struct': 'BlockSizeHistogramInfo',
+  'data': {'boundaries': ['uint64'], 'bins': ['uint64'] } }
+
+##
+# @x-block-size-histogram-set:
+#
+# Manage read, write and flush size histograms for the device.
+#
+# If only @id parameter is specified, remove all present size histograms
+# for the device. Otherwise, add/reset some of (or all) size histograms.
+#
+# @id: The name or QOM path of the guest device.
+#
+# @boundaries: list of interval boundary values (see description in
+#              BlockSizeHistogramInfo definition). If specified, all
+#              size histograms are removed, and empty ones created for all
+#              io types with intervals corresponding to @boundaries (except for
+#              io types, for which specific boundaries are set through the
+#              following parameters).
+#
+# @boundaries-read: list of interval boundary values for read size
+#                   histogram. If specified, old read size histogram is
+#                   removed, and empty one created with intervals
+#                   corresponding to @boundaries-read. The parameter has higher
+#                   priority then @boundaries.
+#
+# @boundaries-write: list of interval boundary values for write size
+#                    histogram.
+#
+# @boundaries-flush: list of interval boundary values for flush size
+#                    histogram.
+#
+# Returns: error if device is not found or any boundary arrays are invalid.
+#
+# Since: 4.0
+#
+# Example: set new histograms for all io types with intervals
+# [0, 8193), [8193, 32769), [32769, 131073), [131073, +inf):
+#
+# -> { "execute": "x-block-size-histogram-set",
+#      "arguments": { "id": "drive0",
+#                     "boundaries": [8193, 32769, 131073] } }
+# <- { "return": {} }
+#
+# Example: set new histogram only for write, other histograms will remain
+# not changed (or not created):
+#
+# -> { "execute": "x-block-size-histogram-set",
+#      "arguments": { "id": "drive0",
+#                     "boundaries-write": [8193, 32769, 131073] } }
+# <- { "return": {} }
+#
+# Example: set new histograms with the following intervals:
+#   read, flush: [0, 8193), [8193, 32769), [32769, 131073), [131073, +inf)
+#   write: [0, 4097), [4097, 8193), [8193, 32769), [32769, +inf)
+#
+# -> { "execute": "x-block-size-histogram-set",
+#      "arguments": { "id": "drive0",
+#                     "boundaries": [8193, 32769, 131073],
+#                     "boundaries-write": [4097, 8193, 32769] } }
+# <- { "return": {} }
+#
+# Example: remove all size histograms:
+#
+# -> { "execute": "x-block-size-histogram-set",
+#      "arguments": { "id": "drive0" } }
+# <- { "return": {} }
+##
+{ 'command': 'x-block-size-histogram-set',
+  'data': {'id': 'str',
+           '*boundaries': ['uint64'],
+           '*boundaries-read': ['uint64'],
+           '*boundaries-write': ['uint64'],
+           '*boundaries-flush': ['uint64'] } }
+
+
+##
 # @BlockInfo:
 #
 # Block device information.  This structure describes a virtual device and
@@ -918,6 +1012,12 @@
 #
 # @flush_latency_histogram: @BlockLatencyHistogramInfo. (Since 4.0)
 #
+# @x_rd_size_histogram: @BlockSizeHistogramInfo. (Since 4.0)
+#
+# @x_wr_size_histogram: @BlockSizeHistogramInfo. (Since 4.0)
+#
+# @x_flush_size_histogram: @BlockSizeHistogramInfo. (Since 4.0)
+#
 # Since: 0.14.0
 ##
 { 'struct': 'BlockDeviceStats',
@@ -933,7 +1033,10 @@
            'timed_stats': ['BlockDeviceTimedStats'],
            '*rd_latency_histogram': 'BlockLatencyHistogramInfo',
            '*wr_latency_histogram': 'BlockLatencyHistogramInfo',
-           '*flush_latency_histogram': 'BlockLatencyHistogramInfo' } }
+           '*flush_latency_histogram': 'BlockLatencyHistogramInfo',
+           '*x_rd_size_histogram': 'BlockSizeHistogramInfo',
+           '*x_wr_size_histogram': 'BlockSizeHistogramInfo',
+           '*x_flush_size_histogram': 'BlockSizeHistogramInfo' } }
 
 ##
 # @BlockStats:
-- 
2.11.0



  parent reply	other threads:[~2019-06-20  9:11 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-20  8:54 [Qemu-devel] [PATCH 0/3] Add block size histogram qapi interface zhenwei pi
2019-06-20  8:54 ` [Qemu-devel] [PATCH 1/3] block/accounting: rename struct BlockLatencyHistogram zhenwei pi
2019-06-21  9:45   ` Vladimir Sementsov-Ogievskiy
2019-06-20  8:54 ` [Qemu-devel] [PATCH 2/3] block/accounting: introduce block size histogram zhenwei pi
2019-06-21  9:48   ` Vladimir Sementsov-Ogievskiy
2019-06-20  8:54 ` zhenwei pi [this message]
2019-06-20 14:03   ` [Qemu-devel] [PATCH 3/3] qapi: add block size histogram interface Eric Blake
2019-06-21  1:52     ` [Qemu-devel] [External Email] " zhenwei pi
2019-06-21  9:26       ` Vladimir Sementsov-Ogievskiy

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=1561020872-6214-4-git-send-email-pizhenwei@bytedance.com \
    --to=pizhenwei@bytedance.com \
    --cc=fam@euphon.net \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=vsementsov@virtuozzo.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).