All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Alberto Garcia <berto@igalia.com>,
	Stefan Hajnoczi <stefanha@redhat.com>
Subject: [Qemu-devel] [PULL 30/44] block: Allow configuring whether to account failed and invalid ops
Date: Tue, 10 Nov 2015 14:14:25 +0000	[thread overview]
Message-ID: <1447164879-6756-31-git-send-email-stefanha@redhat.com> (raw)
In-Reply-To: <1447164879-6756-1-git-send-email-stefanha@redhat.com>

From: Alberto Garcia <berto@igalia.com>

This patch adds two options, "stats-account-invalid" and
"stats-account-failed", that can be used to decide whether invalid and
failed I/O operations must be used when collecting statistics for
latency and last access time.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: ebc7e5966511a342cad428a392c5f5ad56b15213.1446044837.git.berto@igalia.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block/accounting.c         | 24 +++++++++++++++++++-----
 block/qapi.c               |  3 +++
 blockdev.c                 | 16 ++++++++++++++++
 include/block/accounting.h |  5 +++++
 qapi/block-core.json       | 17 ++++++++++++++++-
 qmp-commands.hx            | 25 ++++++++++++++++++++-----
 6 files changed, 79 insertions(+), 11 deletions(-)

diff --git a/block/accounting.c b/block/accounting.c
index 49a9444..923aeaf 100644
--- a/block/accounting.c
+++ b/block/accounting.c
@@ -28,6 +28,13 @@
 
 static QEMUClockType clock_type = QEMU_CLOCK_REALTIME;
 
+void block_acct_init(BlockAcctStats *stats, bool account_invalid,
+                     bool account_failed)
+{
+    stats->account_invalid = account_invalid;
+    stats->account_failed = account_failed;
+}
+
 void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
                       int64_t bytes, enum BlockAcctType type)
 {
@@ -53,13 +60,17 @@ void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie)
 
 void block_acct_failed(BlockAcctStats *stats, BlockAcctCookie *cookie)
 {
-    int64_t time_ns = qemu_clock_get_ns(clock_type);
-
     assert(cookie->type < BLOCK_MAX_IOTYPE);
 
     stats->failed_ops[cookie->type]++;
-    stats->total_time_ns[cookie->type] += time_ns - cookie->start_time_ns;
-    stats->last_access_time_ns = time_ns;
+
+    if (stats->account_failed) {
+        int64_t time_ns = qemu_clock_get_ns(clock_type);
+        int64_t latency_ns = time_ns - cookie->start_time_ns;
+
+        stats->total_time_ns[cookie->type] += latency_ns;
+        stats->last_access_time_ns = time_ns;
+    }
 }
 
 void block_acct_invalid(BlockAcctStats *stats, enum BlockAcctType type)
@@ -72,7 +83,10 @@ void block_acct_invalid(BlockAcctStats *stats, enum BlockAcctType type)
      * therefore there's no actual I/O involved. */
 
     stats->invalid_ops[type]++;
-    stats->last_access_time_ns = qemu_clock_get_ns(clock_type);
+
+    if (stats->account_invalid) {
+        stats->last_access_time_ns = qemu_clock_get_ns(clock_type);
+    }
 }
 
 void block_acct_merge_done(BlockAcctStats *stats, enum BlockAcctType type,
diff --git a/block/qapi.c b/block/qapi.c
index 84d8412..56c8139 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -372,6 +372,9 @@ static BlockStats *bdrv_query_stats(const BlockDriverState *bs,
         if (s->stats->has_idle_time_ns) {
             s->stats->idle_time_ns = block_acct_idle_time_ns(stats);
         }
+
+        s->stats->account_invalid = stats->account_invalid;
+        s->stats->account_failed = stats->account_failed;
     }
 
     s->stats->wr_highest_offset = bs->wr_highest_offset;
diff --git a/blockdev.c b/blockdev.c
index 9907822..5b7aac3 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -441,6 +441,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
     const char *buf;
     int bdrv_flags = 0;
     int on_read_error, on_write_error;
+    bool account_invalid, account_failed;
     BlockBackend *blk;
     BlockDriverState *bs;
     ThrottleConfig cfg;
@@ -477,6 +478,9 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
     /* extract parameters */
     snapshot = qemu_opt_get_bool(opts, "snapshot", 0);
 
+    account_invalid = qemu_opt_get_bool(opts, "stats-account-invalid", true);
+    account_failed = qemu_opt_get_bool(opts, "stats-account-failed", true);
+
     extract_common_blockdev_options(opts, &bdrv_flags, &throttling_group, &cfg,
                                     &detect_zeroes, &error);
     if (error) {
@@ -573,6 +577,8 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
         if (bdrv_key_required(bs)) {
             autostart = 0;
         }
+
+        block_acct_init(blk_get_stats(blk), account_invalid, account_failed);
     }
 
     blk_set_on_error(blk, on_read_error, on_write_error);
@@ -3639,6 +3645,16 @@ QemuOptsList qemu_common_drive_opts = {
             .name = "detect-zeroes",
             .type = QEMU_OPT_STRING,
             .help = "try to optimize zero writes (off, on, unmap)",
+        },{
+            .name = "stats-account-invalid",
+            .type = QEMU_OPT_BOOL,
+            .help = "whether to account for invalid I/O operations "
+                    "in the statistics",
+        },{
+            .name = "stats-account-failed",
+            .type = QEMU_OPT_BOOL,
+            .help = "whether to account for failed I/O operations "
+                    "in the statistics",
         },
         { /* end of list */ }
     },
diff --git a/include/block/accounting.h b/include/block/accounting.h
index b50e3cc..0d9b076 100644
--- a/include/block/accounting.h
+++ b/include/block/accounting.h
@@ -25,6 +25,7 @@
 #define BLOCK_ACCOUNTING_H
 
 #include <stdint.h>
+#include <stdbool.h>
 
 #include "qemu/typedefs.h"
 
@@ -43,6 +44,8 @@ typedef struct BlockAcctStats {
     uint64_t total_time_ns[BLOCK_MAX_IOTYPE];
     uint64_t merged[BLOCK_MAX_IOTYPE];
     int64_t last_access_time_ns;
+    bool account_invalid;
+    bool account_failed;
 } BlockAcctStats;
 
 typedef struct BlockAcctCookie {
@@ -51,6 +54,8 @@ typedef struct BlockAcctCookie {
     enum BlockAcctType type;
 } BlockAcctCookie;
 
+void block_acct_init(BlockAcctStats *stats, bool account_invalid,
+                     bool account_failed);
 void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
                       int64_t bytes, enum BlockAcctType type);
 void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie);
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 0718243..b33663b 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -470,6 +470,12 @@
 # @invalid_flush_operations: The number of invalid flush operations
 #                            performed by the device (Since 2.5)
 #
+# @account_invalid: Whether invalid operations are included in the
+#                   last access statistics (Since 2.5)
+#
+# @account_failed: Whether failed operations are included in the
+#                  latency and last access statistics (Since 2.5)
+#
 # Since: 0.14.0
 ##
 { 'struct': 'BlockDeviceStats',
@@ -480,7 +486,8 @@
            'rd_merged': 'int', 'wr_merged': 'int', '*idle_time_ns': 'int',
            'failed_rd_operations': 'int', 'failed_wr_operations': 'int',
            'failed_flush_operations': 'int', 'invalid_rd_operations': 'int',
-           'invalid_wr_operations': 'int', 'invalid_flush_operations': 'int'  } }
+           'invalid_wr_operations': 'int', 'invalid_flush_operations': 'int',
+           'account_invalid': 'bool', 'account_failed': 'bool' } }
 
 ##
 # @BlockStats:
@@ -1433,6 +1440,12 @@
 #                 (default: enospc)
 # @read-only:     #optional whether the block device should be read-only
 #                 (default: false)
+# @stats-account-invalid: #optional whether to include invalid
+#                         operations when computing last access statistics
+#                         (default: true) (Since 2.5)
+# @stats-account-failed: #optional whether to include failed
+#                         operations when computing latency and last
+#                         access statistics (default: true) (Since 2.5)
 # @detect-zeroes: #optional detect and optimize zero writes (Since 2.1)
 #                 (default: off)
 #
@@ -1448,6 +1461,8 @@
             '*rerror': 'BlockdevOnError',
             '*werror': 'BlockdevOnError',
             '*read-only': 'bool',
+            '*stats-account-invalid': 'bool',
+            '*stats-account-failed': 'bool',
             '*detect-zeroes': 'BlockdevDetectZeroesOptions' } }
 
 ##
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 970a282..70cfea5 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2542,6 +2542,11 @@ Each json-object contain the following:
                                (json-int)
     - "invalid_flush_operations": number of invalid flush operations
                                   (json-int)
+    - "account_invalid": whether invalid operations are included in
+                         the last access statistics (json-bool)
+    - "account_failed": whether failed operations are included in the
+                         latency and last access statistics
+                         (json-bool)
 - "parent": Contains recursively the statistics of the underlying
             protocol (e.g. the host file for a qcow2 image). If there is
             no underlying protocol, this field is omitted
@@ -2567,7 +2572,9 @@ Example:
                   "flush_operations":61,
                   "rd_merged":0,
                   "wr_merged":0,
-                  "idle_time_ns":2953431879
+                  "idle_time_ns":2953431879,
+                  "account_invalid":true,
+                  "account_failed":false
                }
             },
             "stats":{
@@ -2582,7 +2589,9 @@ Example:
                "flush_total_times_ns":49653,
                "rd_merged":0,
                "wr_merged":0,
-               "idle_time_ns":2953431879
+               "idle_time_ns":2953431879,
+               "account_invalid":true,
+               "account_failed":false
             }
          },
          {
@@ -2598,7 +2607,9 @@ Example:
                "rd_total_times_ns":0
                "flush_total_times_ns":0,
                "rd_merged":0,
-               "wr_merged":0
+               "wr_merged":0,
+               "account_invalid":false,
+               "account_failed":false
             }
          },
          {
@@ -2614,7 +2625,9 @@ Example:
                "rd_total_times_ns":0
                "flush_total_times_ns":0,
                "rd_merged":0,
-               "wr_merged":0
+               "wr_merged":0,
+               "account_invalid":false,
+               "account_failed":false
             }
          },
          {
@@ -2630,7 +2643,9 @@ Example:
                "rd_total_times_ns":0
                "flush_total_times_ns":0,
                "rd_merged":0,
-               "wr_merged":0
+               "wr_merged":0,
+               "account_invalid":false,
+               "account_failed":false
             }
          }
       ]
-- 
2.5.0

  parent reply	other threads:[~2015-11-10 14:15 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-10 14:13 [Qemu-devel] [PULL 00/44] Block patches Stefan Hajnoczi
2015-11-10 14:13 ` [Qemu-devel] [PULL 01/44] block: Add more types for tracked request Stefan Hajnoczi
2015-11-10 14:13 ` [Qemu-devel] [PULL 02/44] block: Track flush requests Stefan Hajnoczi
2015-11-10 14:13 ` [Qemu-devel] [PULL 03/44] block: Track discard requests Stefan Hajnoczi
2015-11-10 14:13 ` [Qemu-devel] [PULL 04/44] iscsi: Emulate commands in iscsi_aio_ioctl as iscsi_ioctl Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 05/44] block: Add ioctl parameter fields to BlockRequest Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 06/44] block: Emulate bdrv_ioctl with bdrv_aio_ioctl and track both Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 07/44] block: Drop BlockDriver.bdrv_ioctl Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 08/44] block: Introduce BlockDriver.bdrv_drain callback Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 09/44] qed: Implement .bdrv_drain Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 10/44] qapi: Add transaction support to block-dirty-bitmap operations Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 11/44] iotests: add transactional incremental backup test Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 12/44] block: rename BlkTransactionState and BdrvActionOps Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 13/44] backup: Extract dirty bitmap handling as a separate function Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 14/44] blockjob: Introduce reference count and fix reference to job->bs Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 15/44] blockjob: Add .commit and .abort block job actions Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 16/44] blockjob: Add "completed" and "ret" in BlockJob Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 17/44] blockjob: Simplify block_job_finish_sync Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 18/44] block: Add block job transactions Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 19/44] block/backup: Rely on commit/abort for cleanup Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 20/44] block: Add BlockJobTxn support to backup_run Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 21/44] block: add transactional properties Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 22/44] iotests: 124 - transactional failure test Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 23/44] tests: add BlockJobTxn unit test Stefan Hajnoczi
2015-11-12 18:26   ` Eric Blake
2015-11-10 14:14 ` [Qemu-devel] [PULL 24/44] xen_disk: Account for flush operations Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 25/44] ide: Account for write operations correctly Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 26/44] block: define 'clock_type' for the accounting code Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 27/44] util: Infrastructure for computing recent averages Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 28/44] block: Add idle_time_ns to BlockDeviceStats Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 29/44] block: Add statistics for failed and invalid I/O operations Stefan Hajnoczi
2015-11-10 14:14 ` Stefan Hajnoczi [this message]
2015-11-10 14:14 ` [Qemu-devel] [PULL 31/44] block: Compute minimum, maximum and average I/O latencies Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 32/44] block: Add average I/O queue depth to BlockDeviceTimedStats Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 33/44] block: New option to define the intervals for collecting I/O statistics Stefan Hajnoczi
2015-11-10 17:23   ` Eric Blake
2015-11-10 18:49     ` Markus Armbruster
2015-11-11 11:10     ` Alberto Garcia
2015-11-10 14:14 ` [Qemu-devel] [PULL 34/44] qemu-io: Account for failed, invalid and flush operations Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 35/44] block: Use QEMU_CLOCK_VIRTUAL for the accounting code in qtest mode Stefan Hajnoczi
2015-11-10 15:08   ` Paolo Bonzini
2015-11-10 14:14 ` [Qemu-devel] [PULL 36/44] iotests: Add test for the block device statistics Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 37/44] nvme: Account for failed and invalid operations Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 38/44] virtio-blk: " Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 39/44] xen_disk: " Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 40/44] atapi: " Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 41/44] ide: " Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 42/44] macio: Account for failed operations Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 43/44] scsi-disk: " Stefan Hajnoczi
2015-11-10 14:14 ` [Qemu-devel] [PULL 44/44] block: Update copyright of the accounting code Stefan Hajnoczi

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=1447164879-6756-31-git-send-email-stefanha@redhat.com \
    --to=stefanha@redhat.com \
    --cc=berto@igalia.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /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.