[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 29/44] block: Add statistics for failed and invalid I
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [PULL 29/44] block: Add statistics for failed and invalid I/O operations |
Date: |
Tue, 10 Nov 2015 14:14:24 +0000 |
From: Alberto Garcia <address@hidden>
This patch adds the block_acct_failed() and block_acct_invalid()
functions to allow keeping track of failed and invalid I/O operations.
The number of failed and invalid operations is exposed in
BlockDeviceStats.
We don't keep track of the time spent on invalid operations because
they are cancelled immediately when they are started.
Signed-off-by: Alberto Garcia <address@hidden>
Message-id: address@hidden
Signed-off-by: Stefan Hajnoczi <address@hidden>
---
block/accounting.c | 23 +++++++++++++++++++++++
block/qapi.c | 10 ++++++++++
include/block/accounting.h | 4 ++++
qapi/block-core.json | 23 ++++++++++++++++++++++-
qmp-commands.hx | 12 ++++++++++++
5 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/block/accounting.c b/block/accounting.c
index d427fa8..49a9444 100644
--- a/block/accounting.c
+++ b/block/accounting.c
@@ -51,6 +51,29 @@ void block_acct_done(BlockAcctStats *stats, BlockAcctCookie
*cookie)
stats->last_access_time_ns = time_ns;
}
+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;
+}
+
+void block_acct_invalid(BlockAcctStats *stats, enum BlockAcctType type)
+{
+ assert(type < BLOCK_MAX_IOTYPE);
+
+ /* block_acct_done() and block_acct_failed() update
+ * total_time_ns[], but this one does not. The reason is that
+ * invalid requests are accounted during their submission,
+ * therefore there's no actual I/O involved. */
+
+ stats->invalid_ops[type]++;
+ stats->last_access_time_ns = qemu_clock_get_ns(clock_type);
+}
void block_acct_merge_done(BlockAcctStats *stats, enum BlockAcctType type,
int num_requests)
diff --git a/block/qapi.c b/block/qapi.c
index 539c2e3..84d8412 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -351,6 +351,16 @@ static BlockStats *bdrv_query_stats(const BlockDriverState
*bs,
s->stats->wr_bytes = stats->nr_bytes[BLOCK_ACCT_WRITE];
s->stats->rd_operations = stats->nr_ops[BLOCK_ACCT_READ];
s->stats->wr_operations = stats->nr_ops[BLOCK_ACCT_WRITE];
+
+ s->stats->failed_rd_operations = stats->failed_ops[BLOCK_ACCT_READ];
+ s->stats->failed_wr_operations = stats->failed_ops[BLOCK_ACCT_WRITE];
+ s->stats->failed_flush_operations =
stats->failed_ops[BLOCK_ACCT_FLUSH];
+
+ s->stats->invalid_rd_operations = stats->invalid_ops[BLOCK_ACCT_READ];
+ s->stats->invalid_wr_operations = stats->invalid_ops[BLOCK_ACCT_WRITE];
+ s->stats->invalid_flush_operations =
+ stats->invalid_ops[BLOCK_ACCT_FLUSH];
+
s->stats->rd_merged = stats->merged[BLOCK_ACCT_READ];
s->stats->wr_merged = stats->merged[BLOCK_ACCT_WRITE];
s->stats->flush_operations = stats->nr_ops[BLOCK_ACCT_FLUSH];
diff --git a/include/block/accounting.h b/include/block/accounting.h
index 4b2b999..b50e3cc 100644
--- a/include/block/accounting.h
+++ b/include/block/accounting.h
@@ -38,6 +38,8 @@ enum BlockAcctType {
typedef struct BlockAcctStats {
uint64_t nr_bytes[BLOCK_MAX_IOTYPE];
uint64_t nr_ops[BLOCK_MAX_IOTYPE];
+ uint64_t invalid_ops[BLOCK_MAX_IOTYPE];
+ uint64_t failed_ops[BLOCK_MAX_IOTYPE];
uint64_t total_time_ns[BLOCK_MAX_IOTYPE];
uint64_t merged[BLOCK_MAX_IOTYPE];
int64_t last_access_time_ns;
@@ -52,6 +54,8 @@ typedef struct BlockAcctCookie {
void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
int64_t bytes, enum BlockAcctType type);
void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie);
+void block_acct_failed(BlockAcctStats *stats, BlockAcctCookie *cookie);
+void block_acct_invalid(BlockAcctStats *stats, enum BlockAcctType type);
void block_acct_merge_done(BlockAcctStats *stats, enum BlockAcctType type,
int num_requests);
int64_t block_acct_idle_time_ns(BlockAcctStats *stats);
diff --git a/qapi/block-core.json b/qapi/block-core.json
index b00be46..0718243 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -452,6 +452,24 @@
# nanoseconds. If the field is absent it means that
# there haven't been any operations yet (Since 2.5).
#
+# @failed_rd_operations: The number of failed read operations
+# performed by the device (Since 2.5)
+#
+# @failed_wr_operations: The number of failed write operations
+# performed by the device (Since 2.5)
+#
+# @failed_flush_operations: The number of failed flush operations
+# performed by the device (Since 2.5)
+#
+# @invalid_rd_operations: The number of invalid read operations
+# performed by the device (Since 2.5)
+#
+# @invalid_wr_operations: The number of invalid write operations
+# performed by the device (Since 2.5)
+#
+# @invalid_flush_operations: The number of invalid flush operations
+# performed by the device (Since 2.5)
+#
# Since: 0.14.0
##
{ 'struct': 'BlockDeviceStats',
@@ -459,7 +477,10 @@
'wr_operations': 'int', 'flush_operations': 'int',
'flush_total_time_ns': 'int', 'wr_total_time_ns': 'int',
'rd_total_time_ns': 'int', 'wr_highest_offset': 'int',
- 'rd_merged': 'int', 'wr_merged': 'int', '*idle_time_ns': 'int' } }
+ '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'
} }
##
# @BlockStats:
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ff3e2c0..970a282 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2530,6 +2530,18 @@ Each json-object contain the following:
nanoseconds. If the field is absent it means
that there haven't been any operations yet
(json-int, optional)
+ - "failed_rd_operations": number of failed read operations
+ (json-int)
+ - "failed_wr_operations": number of failed write operations
+ (json-int)
+ - "failed_flush_operations": number of failed flush operations
+ (json-int)
+ - "invalid_rd_operations": number of invalid read operations
+ (json-int)
+ - "invalid_wr_operations": number of invalid write operations
+ (json-int)
+ - "invalid_flush_operations": number of invalid flush operations
+ (json-int)
- "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
--
2.5.0
- [Qemu-devel] [PULL 22/44] iotests: 124 - transactional failure test, (continued)
- [Qemu-devel] [PULL 22/44] iotests: 124 - transactional failure test, Stefan Hajnoczi, 2015/11/10
- [Qemu-devel] [PULL 21/44] block: add transactional properties, Stefan Hajnoczi, 2015/11/10
- [Qemu-devel] [PULL 23/44] tests: add BlockJobTxn unit test, Stefan Hajnoczi, 2015/11/10
- [Qemu-devel] [PULL 25/44] ide: Account for write operations correctly, Stefan Hajnoczi, 2015/11/10
- [Qemu-devel] [PULL 24/44] xen_disk: Account for flush operations, Stefan Hajnoczi, 2015/11/10
- [Qemu-devel] [PULL 26/44] block: define 'clock_type' for the accounting code, Stefan Hajnoczi, 2015/11/10
- [Qemu-devel] [PULL 27/44] util: Infrastructure for computing recent averages, Stefan Hajnoczi, 2015/11/10
- [Qemu-devel] [PULL 28/44] block: Add idle_time_ns to BlockDeviceStats, Stefan Hajnoczi, 2015/11/10
- [Qemu-devel] [PULL 30/44] block: Allow configuring whether to account failed and invalid ops, Stefan Hajnoczi, 2015/11/10
- [Qemu-devel] [PULL 29/44] block: Add statistics for failed and invalid I/O operations,
Stefan Hajnoczi <=
- [Qemu-devel] [PULL 32/44] block: Add average I/O queue depth to BlockDeviceTimedStats, Stefan Hajnoczi, 2015/11/10
- [Qemu-devel] [PULL 34/44] qemu-io: Account for failed, invalid and flush operations, Stefan Hajnoczi, 2015/11/10
- [Qemu-devel] [PULL 31/44] block: Compute minimum, maximum and average I/O latencies, Stefan Hajnoczi, 2015/11/10
- [Qemu-devel] [PULL 33/44] block: New option to define the intervals for collecting I/O statistics, Stefan Hajnoczi, 2015/11/10
- [Qemu-devel] [PULL 35/44] block: Use QEMU_CLOCK_VIRTUAL for the accounting code in qtest mode, Stefan Hajnoczi, 2015/11/10
- [Qemu-devel] [PULL 37/44] nvme: Account for failed and invalid operations, Stefan Hajnoczi, 2015/11/10