From patchwork Fri Oct 2 14:26:20 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 525607 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 AC8261402B6 for ; Sat, 3 Oct 2015 02:00:37 +1000 (AEST) Received: from localhost ([::1]:60975 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zi2l9-0007Fg-Md for incoming@patchwork.ozlabs.org; Fri, 02 Oct 2015 12:00:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39724) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zi1JC-0001fv-AR for qemu-devel@nongnu.org; Fri, 02 Oct 2015 10:27:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zi1J8-0005Lx-SA for qemu-devel@nongnu.org; Fri, 02 Oct 2015 10:27:38 -0400 Received: from smtp3.mundo-r.com ([212.51.32.191]:19591 helo=smtp4.mundo-r.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zi1J8-0004y4-MW; Fri, 02 Oct 2015 10:27:34 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2BCBgCRkw5W/5tjdVteHAEBgwmBQqkqAQEBAQEBBQGBDQGPHIQvh3QCgTQ6EgEBAQEBAQGBCoQlAQEEJ1IQPxI8GxmIMgHLdwErgk+DXYltZQeELAWNd4gFjReBVodbkjIoAjmBSkcdgVduiC+BSQEBAQ X-IPAS-Result: A2BCBgCRkw5W/5tjdVteHAEBgwmBQqkqAQEBAQEBBQGBDQGPHIQvh3QCgTQ6EgEBAQEBAQGBCoQlAQEEJ1IQPxI8GxmIMgHLdwErgk+DXYltZQeELAWNd4gFjReBVodbkjIoAjmBSkcdgVduiC+BSQEBAQ X-IronPort-AV: E=Sophos;i="5.17,623,1437429600"; d="scan'208";a="29069584" Received: from fanzine.igalia.com ([91.117.99.155]) by smtp4.mundo-r.com with ESMTP; 02 Oct 2015 16:26:55 +0200 Received: from dsl-hkibrasgw4-50df50-201.dhcp.inet.fi ([80.223.80.201] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim) id 1Zi1IT-0006yr-N8; Fri, 02 Oct 2015 16:26:54 +0200 Received: from berto by perseus.local with local (Exim 4.86) (envelope-from ) id 1Zi1IG-00070c-J6; Fri, 02 Oct 2015 17:26:40 +0300 From: Alberto Garcia To: qemu-devel@nongnu.org Date: Fri, 2 Oct 2015 17:26:20 +0300 Message-Id: <481052055ac4d462ba51562c78d837ffdbbee78b.1443793122.git.berto@igalia.com> X-Mailer: git-send-email 2.5.3 In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 212.51.32.191 Cc: Kevin Wolf , Alberto Garcia , qemu-block@nongnu.org, Markus Armbruster , Max Reitz , Stefan Hajnoczi Subject: [Qemu-devel] [PATCH v2 10/22] block: Add average I/O queue depth to BlockDeviceTimedStats 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 This patch adds two new fields to BlockDeviceTimedStats that track the average number of pending read and write requests for a block device. The values are calculated for the period of time defined for that interval. Signed-off-by: Alberto Garcia --- block/accounting.c | 12 ++++++++++++ block/qapi.c | 5 +++++ include/block/accounting.h | 2 ++ include/qemu/timed-average.h | 1 + qapi/block-core.json | 9 ++++++++- qmp-commands.hx | 6 ++++++ util/timed-average.c | 17 +++++++++++++++++ 7 files changed, 51 insertions(+), 1 deletion(-) diff --git a/block/accounting.c b/block/accounting.c index c74a473..d94ebed 100644 --- a/block/accounting.c +++ b/block/accounting.c @@ -138,3 +138,15 @@ int64_t block_acct_idle_time_ns(BlockAcctStats *stats) { return qemu_clock_get_ns(clock_type) - stats->last_access_time_ns; } + +double block_acct_queue_depth(BlockAcctTimedStats *stats, + enum BlockAcctType type) +{ + uint64_t sum, elapsed; + + assert(type < BLOCK_MAX_IOTYPE); + + sum = timed_average_sum(&stats->latency[type], &elapsed); + + return (double) sum / elapsed; +} diff --git a/block/qapi.c b/block/qapi.c index fdddb45..2fec5e1 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -404,6 +404,11 @@ static BlockStats *bdrv_query_stats(const BlockDriverState *bs, dev_stats->min_flush_latency_ns = timed_average_min(fl); dev_stats->max_flush_latency_ns = timed_average_max(fl); dev_stats->avg_flush_latency_ns = timed_average_avg(fl); + + dev_stats->avg_rd_queue_depth = + block_acct_queue_depth(ts, BLOCK_ACCT_READ); + dev_stats->avg_wr_queue_depth = + block_acct_queue_depth(ts, BLOCK_ACCT_WRITE); } } diff --git a/include/block/accounting.h b/include/block/accounting.h index 09605bb..f41ddde 100644 --- a/include/block/accounting.h +++ b/include/block/accounting.h @@ -78,5 +78,7 @@ 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); +double block_acct_queue_depth(BlockAcctTimedStats *stats, + enum BlockAcctType type); #endif diff --git a/include/qemu/timed-average.h b/include/qemu/timed-average.h index f1cdddc..364bf88 100644 --- a/include/qemu/timed-average.h +++ b/include/qemu/timed-average.h @@ -59,5 +59,6 @@ void timed_average_account(TimedAverage *ta, uint64_t value); uint64_t timed_average_min(TimedAverage *ta); uint64_t timed_average_avg(TimedAverage *ta); uint64_t timed_average_max(TimedAverage *ta); +uint64_t timed_average_sum(TimedAverage *ta, uint64_t *elapsed); #endif diff --git a/qapi/block-core.json b/qapi/block-core.json index 45f913b..c6db03b 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -450,6 +450,12 @@ # @avg_flush_latency_ns: Average latency of flush operations in the # defined interval, in nanoseconds. # +# @avg_rd_queue_depth: Average number of pending read operations +# in the defined interval. +# +# @avg_wr_queue_depth: Average number of pending write operations +# in the defined interval. +# # Since: 2.5 ## @@ -458,7 +464,8 @@ 'max_rd_latency_ns': 'int', 'avg_rd_latency_ns': 'int', 'min_wr_latency_ns': 'int', 'max_wr_latency_ns': 'int', 'avg_wr_latency_ns': 'int', 'min_flush_latency_ns': 'int', - 'max_flush_latency_ns': 'int', 'avg_flush_latency_ns': 'int' } } + 'max_flush_latency_ns': 'int', 'avg_flush_latency_ns': 'int', + 'avg_rd_queue_depth': 'number', 'avg_wr_queue_depth': 'number' } } ## # @BlockDeviceStats: diff --git a/qmp-commands.hx b/qmp-commands.hx index 33f2897..533edf5 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -2564,6 +2564,12 @@ Each json-object contain the following: - "avg_flush_latency_ns": average latency of flush operations in the defined interval, in nanoseconds (json-int) + - "avg_rd_queue_depth": average number of pending read + operations in the defined interval + (json-number) + - "avg_wr_queue_depth": average number of pending write + operations in the defined interval + (json-number). - "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 diff --git a/util/timed-average.c b/util/timed-average.c index 1f4689e..4263b29 100644 --- a/util/timed-average.c +++ b/util/timed-average.c @@ -208,3 +208,20 @@ uint64_t timed_average_max(TimedAverage *ta) check_expirations(ta); return current_window(ta)->max; } + +/* Get the sum of all accounted values + * @ta: the TimedAverage structure + * @elapsed: if non-NULL, the elapsed time (in ns) will be stored here + * @ret: the sum of all accounted values + */ +uint64_t timed_average_sum(TimedAverage *ta, uint64_t *elapsed) +{ + TimedAverageWindow *w; + check_expirations(ta); + w = current_window(ta); + if (elapsed != NULL) { + int64_t remaining = w->expiration - qemu_clock_get_ns(ta->clock_type); + *elapsed = ta->period - remaining; + } + return w->sum; +}