From patchwork Tue Nov 10 14:14:25 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 542402 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 0AD1B140213 for ; Wed, 11 Nov 2015 01:46:30 +1100 (AEDT) Received: from localhost ([::1]:60591 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZwABo-0005oL-2B for incoming@patchwork.ozlabs.org; Tue, 10 Nov 2015 09:46:28 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58635) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zw9iE-0002al-Mk for qemu-devel@nongnu.org; Tue, 10 Nov 2015 09:15:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zw9iC-0005yC-Rs for qemu-devel@nongnu.org; Tue, 10 Nov 2015 09:15:54 -0500 Received: from mx1.redhat.com ([209.132.183.28]:60368) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zw9iC-0005xu-BM for qemu-devel@nongnu.org; Tue, 10 Nov 2015 09:15:52 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id E24DEC0A849D; Tue, 10 Nov 2015 14:15:51 +0000 (UTC) Received: from localhost (ovpn-112-78.ams2.redhat.com [10.36.112.78]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAAEFo7H013640; Tue, 10 Nov 2015 09:15:51 -0500 From: Stefan Hajnoczi To: Date: Tue, 10 Nov 2015 14:14:25 +0000 Message-Id: <1447164879-6756-31-git-send-email-stefanha@redhat.com> In-Reply-To: <1447164879-6756-1-git-send-email-stefanha@redhat.com> References: <1447164879-6756-1-git-send-email-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Peter Maydell , Alberto Garcia , Stefan Hajnoczi Subject: [Qemu-devel] [PULL 30/44] block: Allow configuring whether to account failed and invalid ops X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Alberto Garcia 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 Reviewed-by: Stefan Hajnoczi Message-id: ebc7e5966511a342cad428a392c5f5ad56b15213.1446044837.git.berto@igalia.com Signed-off-by: Stefan Hajnoczi --- 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 +#include #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 } } ]