From patchwork Fri Jun 7 09:05:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 166082 Delivered-To: patch@linaro.org Received: by 2002:a92:9e1a:0:0:0:0:0 with SMTP id q26csp383216ili; Fri, 7 Jun 2019 02:12:12 -0700 (PDT) X-Google-Smtp-Source: APXvYqwmhZvFupkzplBnVEleWXZDEHSFTjENobMkpmcd6z/e1M/zkyCDeprHWX12Vra9ew04x2p+ X-Received: by 2002:a0c:96aa:: with SMTP id a39mr43687567qvd.230.1559898732110; Fri, 07 Jun 2019 02:12:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559898732; cv=none; d=google.com; s=arc-20160816; b=xcy5sNtzsU4zEGieMyInWuqYj39OD2orDoKpNSw0fUlVHykhwhvxCQOTj+2NLax08v NOkaQ7G0N/4zvXbXH2tduBCKwsTuCg5IOgvYlZ0o49su2Jvc0YrY6b6251T45MU4n5mQ YsnEt+WNuV6tNYquX2FUZhMY0sUT4FVNJO/R3V6hm8wEPSSeK46Cu92DSZ7Gc2xqbML6 pZ4lqjeAMFAWEea3n8yEQjjN0sBlycFAwcGww5z9rLZY2M0lheF2THJVD28HocUC4EkY nR+JI3QenPwJmO9rir/O1HKbK4f2X97eKjb1pDPnVPXkpNsCYbRVqb2nlDmGJ/qTw4ML WCcA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=cQ0tfgve/Y4PUSaOnIOLkGNDESD+hZVEqLt68K3UEOk=; b=oWWpEnp5r+g/SzBbIJuMY40gjzS2pYiPvbtPBaxrKS/aVbNrNe/HDYc0AaMZDMR9ga 1RohkfD796dvvjiJOHXOsNXa3q6V4JFPuC+i5Wyn6UZ89tYZrEUDFF2CqEZ5T4QWpPDJ wPgpeSK0a0v1MtP1tYr7XZG0C+DPy9MRSBxNpFVcbpVU+GHU16ajERWxyZYa4xXo3rEu GLgC9O8++cPemTX69tJaEVd/H6FD1JwvGxqf4ipS4zLk1KXabJfNTX/aTtP3m8rw6hnW jQ377nkRJES/+vl2xEOhCAgtiUOS96vzU1yX6bCM4ybQnDL8+SNm/iM3e2prEzNT76ZS 3C/A== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=G81clC+6; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.47 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.47]) by mx.google.com with ESMTPS id i15si985426qte.365.2019.06.07.02.12.12 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 07 Jun 2019 02:12:12 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.47 as permitted sender) client-ip=209.51.188.47; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=G81clC+6; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.47 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:47192 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hZAux-0001T3-LI for patch@linaro.org; Fri, 07 Jun 2019 05:12:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39332) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hZAoz-00047M-RG for qemu-devel@nongnu.org; Fri, 07 Jun 2019 05:06:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hZAox-0004GA-9N for qemu-devel@nongnu.org; Fri, 07 Jun 2019 05:06:01 -0400 Received: from mail-wm1-x336.google.com ([2a00:1450:4864:20::336]:40205) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hZAot-0003x4-WA for qemu-devel@nongnu.org; Fri, 07 Jun 2019 05:05:58 -0400 Received: by mail-wm1-x336.google.com with SMTP id v19so1129291wmj.5 for ; Fri, 07 Jun 2019 02:05:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cQ0tfgve/Y4PUSaOnIOLkGNDESD+hZVEqLt68K3UEOk=; b=G81clC+6/P6GAgE93dcnmL4e5LVMKsjrJrY4MBsEWmB01u7eYsJW7EtsHx8fzhVbm6 /qUB7f3Ppwh6JuWvf1NXnEJgP8KhdFLymDEmQGH77I/NdjUf6jFgu+V293Eh9VYu5cLs djjxsFxqVOHZPD5OUC8RssqPsMSVpCXOlaJBQ3CecndxUQRf95F7Q8MoJ4AM3BRc9JPv Z7mLpwCcSXP4xfQFhjXDeHaSNdPMVlvPFRUAp76yxRz91S1dICDMYTUL2BTtFd5gQ4YI /lwBqTr8vZ9NNkli82z1uOwWsrnJrXkgBFgSD74Hn1zTO1EyQuf3w8zL1EjrgZxEBJft XvAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cQ0tfgve/Y4PUSaOnIOLkGNDESD+hZVEqLt68K3UEOk=; b=juUy2Zncm+pNe2WuLwhtoUYNwTmKjBcOyu7gyDEDcTSHkCwm6HwMFse5CKs1ocD6uF UzArbuxftmnx9PF/vKCN1XY3TkimnQnMIKqJiwkavjp2wkWjG8Bc7M5z5d3LaCJziXuH Eqx2xfWqbh2aIXcuvmbIgPp9pTptmn5Kk1MXoVeFcUL/wNcMXb0PGSxIId+oAz5PJR0Z CJ0n4WmWSSh5w+f4YhsjQ3VxXGU/Df8bZNHzzOwD9uabKH0GjANqvR89fcKF9cX7UjH2 1Fog0xTQqKo84Z6DBY9rSrnLKdGGJbbzZw08d99EpaBBOQn/igxS1ZuoKRU78htQ0CFF zc2w== X-Gm-Message-State: APjAAAWis6lTZ5rZlI2J2aYg5bYVwaULAkLu2sZVLyz84W9SuVpBS0kJ 3bfp6xYuQ6S4OkVJYZHfIN7JoQ== X-Received: by 2002:a1c:cb43:: with SMTP id b64mr2753473wmg.135.1559898354536; Fri, 07 Jun 2019 02:05:54 -0700 (PDT) Received: from zen.linaroharston ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id x16sm1209094wmj.4.2019.06.07.02.05.52 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Fri, 07 Jun 2019 02:05:53 -0700 (PDT) Received: from zen.linaroharston. (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 31A421FF8F; Fri, 7 Jun 2019 10:05:52 +0100 (BST) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Fri, 7 Jun 2019 10:05:01 +0100 Message-Id: <20190607090552.12434-3-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190607090552.12434-1-alex.bennee@linaro.org> References: <20190607090552.12434-1-alex.bennee@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::336 Subject: [Qemu-devel] [PULL 02/52] qemu-io-cmds: use clock_gettime for benchmarking X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?utf-8?q?Alex_Benn=C3=A9e?= , qemu-devel@nongnu.org, "open list:Block layer core" , Max Reitz Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" The previous use of gettimeofday() ran into undefined behaviour when we ended up doing a div 0 for a very short operation. This is because gettimeofday only works at the microsecond level as well as being prone to discontinuous jumps in system time. Using clock_gettime with CLOCK_MONOTONIC gives greater precision and alleviates some of the potential problems with time jumping around. We could use CLOCK_MONOTONIC_RAW to avoid being tripped up by NTP and adjtime but that is Linux specific so I decided it would do for now. Signed-off-by: Alex Bennée -- 2.20.1 diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index 30a7d9a13b..8904733961 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -248,20 +248,21 @@ static void cvtstr(double value, char *str, size_t size) -static struct timeval tsub(struct timeval t1, struct timeval t2) +static struct timespec tsub(struct timespec t1, struct timespec t2) { - t1.tv_usec -= t2.tv_usec; - if (t1.tv_usec < 0) { - t1.tv_usec += 1000000; + t1.tv_nsec -= t2.tv_nsec; + if (t1.tv_nsec < 0) { + t1.tv_nsec += NANOSECONDS_PER_SECOND; t1.tv_sec--; } t1.tv_sec -= t2.tv_sec; return t1; } -static double tdiv(double value, struct timeval tv) +static double tdiv(double value, struct timespec tv) { - return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0)); + double seconds = tv.tv_sec + (tv.tv_nsec / 1e9); + return value / seconds; } #define HOURS(sec) ((sec) / (60 * 60)) @@ -274,29 +275,27 @@ enum { VERBOSE_FIXED_TIME = 0x2, }; -static void timestr(struct timeval *tv, char *ts, size_t size, int format) +static void timestr(struct timespec *tv, char *ts, size_t size, int format) { - double usec = (double)tv->tv_usec / 1000000.0; + double frac_sec = tv->tv_nsec / 1e9; if (format & TERSE_FIXED_TIME) { if (!HOURS(tv->tv_sec)) { - snprintf(ts, size, "%u:%02u.%02u", - (unsigned int) MINUTES(tv->tv_sec), - (unsigned int) SECONDS(tv->tv_sec), - (unsigned int) (usec * 100)); + snprintf(ts, size, "%u:%05.2f", + (unsigned int) MINUTES(tv->tv_sec), + SECONDS(tv->tv_sec) + frac_sec); return; } format |= VERBOSE_FIXED_TIME; /* fallback if hours needed */ } if ((format & VERBOSE_FIXED_TIME) || tv->tv_sec) { - snprintf(ts, size, "%u:%02u:%02u.%02u", + snprintf(ts, size, "%u:%02u:%05.2f", (unsigned int) HOURS(tv->tv_sec), (unsigned int) MINUTES(tv->tv_sec), - (unsigned int) SECONDS(tv->tv_sec), - (unsigned int) (usec * 100)); + SECONDS(tv->tv_sec) + frac_sec); } else { - snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000)); + snprintf(ts, size, "%05.2f sec", frac_sec); } } @@ -376,7 +375,7 @@ static void dump_buffer(const void *buffer, int64_t offset, int64_t len) } } -static void print_report(const char *op, struct timeval *t, int64_t offset, +static void print_report(const char *op, struct timespec *t, int64_t offset, int64_t count, int64_t total, int cnt, bool Cflag) { char s1[64], s2[64], ts[64]; @@ -649,7 +648,7 @@ static const cmdinfo_t read_cmd = { static int read_f(BlockBackend *blk, int argc, char **argv) { - struct timeval t1, t2; + struct timespec t1, t2; bool Cflag = false, qflag = false, vflag = false; bool Pflag = false, sflag = false, lflag = false, bflag = false; int c, cnt, ret; @@ -758,13 +757,13 @@ static int read_f(BlockBackend *blk, int argc, char **argv) buf = qemu_io_alloc(blk, count, 0xab); - gettimeofday(&t1, NULL); + clock_gettime(CLOCK_MONOTONIC, &t1); if (bflag) { ret = do_load_vmstate(blk, buf, offset, count, &total); } else { ret = do_pread(blk, buf, offset, count, &total); } - gettimeofday(&t2, NULL); + clock_gettime(CLOCK_MONOTONIC, &t2); if (ret < 0) { printf("read failed: %s\n", strerror(-ret)); @@ -836,7 +835,7 @@ static const cmdinfo_t readv_cmd = { static int readv_f(BlockBackend *blk, int argc, char **argv) { - struct timeval t1, t2; + struct timespec t1, t2; bool Cflag = false, qflag = false, vflag = false; int c, cnt, ret; char *buf; @@ -891,9 +890,9 @@ static int readv_f(BlockBackend *blk, int argc, char **argv) return -EINVAL; } - gettimeofday(&t1, NULL); + clock_gettime(CLOCK_MONOTONIC, &t1); ret = do_aio_readv(blk, &qiov, offset, &total); - gettimeofday(&t2, NULL); + clock_gettime(CLOCK_MONOTONIC, &t2); if (ret < 0) { printf("readv failed: %s\n", strerror(-ret)); @@ -972,7 +971,7 @@ static const cmdinfo_t write_cmd = { static int write_f(BlockBackend *blk, int argc, char **argv) { - struct timeval t1, t2; + struct timespec t1, t2; bool Cflag = false, qflag = false, bflag = false; bool Pflag = false, zflag = false, cflag = false; int flags = 0; @@ -1091,7 +1090,7 @@ static int write_f(BlockBackend *blk, int argc, char **argv) buf = qemu_io_alloc(blk, count, pattern); } - gettimeofday(&t1, NULL); + clock_gettime(CLOCK_MONOTONIC, &t1); if (bflag) { ret = do_save_vmstate(blk, buf, offset, count, &total); } else if (zflag) { @@ -1101,7 +1100,7 @@ static int write_f(BlockBackend *blk, int argc, char **argv) } else { ret = do_pwrite(blk, buf, offset, count, flags, &total); } - gettimeofday(&t2, NULL); + clock_gettime(CLOCK_MONOTONIC, &t2); if (ret < 0) { printf("write failed: %s\n", strerror(-ret)); @@ -1160,7 +1159,7 @@ static const cmdinfo_t writev_cmd = { static int writev_f(BlockBackend *blk, int argc, char **argv) { - struct timeval t1, t2; + struct timespec t1, t2; bool Cflag = false, qflag = false; int flags = 0; int c, cnt, ret; @@ -1213,9 +1212,9 @@ static int writev_f(BlockBackend *blk, int argc, char **argv) return -EINVAL; } - gettimeofday(&t1, NULL); + clock_gettime(CLOCK_MONOTONIC, &t1); ret = do_aio_writev(blk, &qiov, offset, flags, &total); - gettimeofday(&t2, NULL); + clock_gettime(CLOCK_MONOTONIC, &t2); if (ret < 0) { printf("writev failed: %s\n", strerror(-ret)); @@ -1250,15 +1249,15 @@ struct aio_ctx { bool zflag; BlockAcctCookie acct; int pattern; - struct timeval t1; + struct timespec t1; }; static void aio_write_done(void *opaque, int ret) { struct aio_ctx *ctx = opaque; - struct timeval t2; + struct timespec t2; - gettimeofday(&t2, NULL); + clock_gettime(CLOCK_MONOTONIC, &t2); if (ret < 0) { @@ -1288,9 +1287,9 @@ out: static void aio_read_done(void *opaque, int ret) { struct aio_ctx *ctx = opaque; - struct timeval t2; + struct timespec t2; - gettimeofday(&t2, NULL); + clock_gettime(CLOCK_MONOTONIC, &t2); if (ret < 0) { printf("readv failed: %s\n", strerror(-ret)); @@ -1425,7 +1424,7 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv) return -EINVAL; } - gettimeofday(&ctx->t1, NULL); + clock_gettime(CLOCK_MONOTONIC, &ctx->t1); block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size, BLOCK_ACCT_READ); blk_aio_preadv(blk, ctx->offset, &ctx->qiov, 0, aio_read_done, ctx); @@ -1570,7 +1569,7 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv) return -EINVAL; } - gettimeofday(&ctx->t1, NULL); + clock_gettime(CLOCK_MONOTONIC, &ctx->t1); block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size, BLOCK_ACCT_WRITE); @@ -1746,7 +1745,7 @@ static const cmdinfo_t discard_cmd = { static int discard_f(BlockBackend *blk, int argc, char **argv) { - struct timeval t1, t2; + struct timespec t1, t2; bool Cflag = false, qflag = false; int c, ret; int64_t offset, bytes; @@ -1787,9 +1786,9 @@ static int discard_f(BlockBackend *blk, int argc, char **argv) return -EINVAL; } - gettimeofday(&t1, NULL); + clock_gettime(CLOCK_MONOTONIC, &t1); ret = blk_pdiscard(blk, offset, bytes); - gettimeofday(&t2, NULL); + clock_gettime(CLOCK_MONOTONIC, &t2); if (ret < 0) { printf("discard failed: %s\n", strerror(-ret));