From nobody Sun Apr 28 06:22:57 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1559147187; cv=none; d=zoho.com; s=zohoarc; b=KuZhC10rhs6rBQL1q6oJticAeNWjdk7JGYqcncCK1nVLRM6Saw3hX6Y7jk6NF2Hw1sKr4f0ztFAkOMrQpfVu5EwAS5hLfGPT8CvaLZ29LkpWj0QsJwb9VJMIRbLwNcslLCkGzdeHaXxb8Kxh5Dwv3OrRxUpbrqk7P71zw66yqiQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559147187; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To:ARC-Authentication-Results; bh=W0SJ8X2eriH/6uj+RKzK10RqVpztQENWh4cWX7jYDAc=; b=MVi7ErKTzV71ysrXP4j09xVDYShXY3vo1EpJoFxykyc2Vs4LvXfttVM4g2Vo5i0k0rGmIljIUTR7A7iTqNY34uTcEtcb++TFkrKRUmZb+SC9Yo7hRxJIj7NVf4YU6ftefsYGzSK4VoRiytoP0c1FjoZD7Zdn3SjB/JljYxNvnaI= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1559147187243149.17043188976345; Wed, 29 May 2019 09:26:27 -0700 (PDT) Received: from localhost ([127.0.0.1]:57629 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hW1P4-0004aO-W7 for importer@patchew.org; Wed, 29 May 2019 12:26:15 -0400 Received: from eggs.gnu.org ([209.51.188.92]:36291) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hW1O0-000492-V3 for qemu-devel@nongnu.org; Wed, 29 May 2019 12:25:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hW1Nx-0003TI-Dg for qemu-devel@nongnu.org; Wed, 29 May 2019 12:25:08 -0400 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:36366) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hW1Nt-0003C9-0V for qemu-devel@nongnu.org; Wed, 29 May 2019 12:25:02 -0400 Received: by mail-wr1-x441.google.com with SMTP id s17so2245542wru.3 for ; Wed, 29 May 2019 09:24:55 -0700 (PDT) Received: from zen.linaroharston ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id d17sm24019029wrw.18.2019.05.29.09.24.48 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Wed, 29 May 2019 09:24:48 -0700 (PDT) Received: from zen.linaroharston. (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 215211FF87; Wed, 29 May 2019 17:24:48 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=W0SJ8X2eriH/6uj+RKzK10RqVpztQENWh4cWX7jYDAc=; b=OBMcVcOWTlFcfIZCbvsu422JxebiE/oN+Lf+leJmuWolRjayadeZiwRPe1BsH8vxqJ ZiWBqfacKGxiJtNwCXAcIymiQXfyByagnbAhu2VAD8YntD0OtrSrOmtvsUJstUGqcXQt VXa52Y1asLpzGk5JG4xTkDZF4IlLU9gmIqucDawzAkY0PuiJYPXp5LjpsI8yrYRw5y5Z hBBsLSZdtjf+lItxd4rhf9iGhIpqTk9rTZeLZAmnrJK2ll9ipQS6IDO3sNC1mRSLg8Ql W3/dV14klhYXMdtB/yogBnKN9zCr4/eD6LUd6jnpMFI0wg394gUba7sqBgKJRxrxnEsf 0OWg== 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:mime-version :content-transfer-encoding; bh=W0SJ8X2eriH/6uj+RKzK10RqVpztQENWh4cWX7jYDAc=; b=mfHGcSSDXjwv1d7zgT/Rf8yLVcwwECN64CtAaHYUQ6b0nOZ6hGaGJV2dM1ktugFUtA Fpg0CCXW7dcj0ctdhs3qgVTNVwijyvPnLsg8WYcX5j1EXC6CjouuVhrseWKj/mnuDV2l USgy7Ug+aN7GGt/38lc+yNs//1D5RYtZVyw6YYUuyZic5x6wzXIjnd96Rk2LZo4mXgaE KSLviByglZ/dHNTikcrP4FTX57v8je8af/tJamzYMhlpXYrj4owNIkG837vQ5oHBSDsJ 3cjnf+V9cL+nnvA4dBDaT3K922Y5tOEeYs6MpyOfda1mry/gjHuWRhEEdFgiXShffofb kTUA== X-Gm-Message-State: APjAAAX4tG04pJ1vjtFsBb1WXfuPYlwoO17F+2FaKD4RKgr65ttASdRE WFraHx3b6d5Fpmot1XjLClTEsQ== X-Google-Smtp-Source: APXvYqzo+3LwH9lTvP/CZg0ro/Mz3OsZFnbFjCM57o2PglRllOH0LF2TE5iYj2wWZmdbATMnEk3WCw== X-Received: by 2002:a5d:6745:: with SMTP id l5mr16004900wrw.160.1559147089687; Wed, 29 May 2019 09:24:49 -0700 (PDT) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: qemu-devel@nongnu.org Date: Wed, 29 May 2019 17:24:38 +0100 Message-Id: <20190529162438.22653-1-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 Subject: [Qemu-devel] [RFC PATCH] qemu-io-cmds: use clock_gettime for benchmarking X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?UTF-8?q?Alex=20Benn=C3=A9e?= , "open list:Block layer core" , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) 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=C3=A9e --- qemu-io-cmds.c | 69 +++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index 30a7d9a13bf..4ace2969a9e 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -248,20 +248,21 @@ static void cvtstr(double value, char *str, size_t si= ze) =20 =20 =20 -static struct timeval tsub(struct timeval t1, struct timeval t2) +static struct timespec tsub(struct timespec t1, struct timespec t2) { - t1.tv_usec -=3D t2.tv_usec; - if (t1.tv_usec < 0) { - t1.tv_usec +=3D 1000000; + t1.tv_nsec -=3D t2.tv_nsec; + if (t1.tv_nsec < 0) { + t1.tv_nsec +=3D 1000000000; t1.tv_sec--; } t1.tv_sec -=3D t2.tv_sec; return t1; } =20 -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 time =3D (double)tv.tv_sec + ((double)tv.tv_nsec / 1000000000.0= ); + return value / time; } =20 #define HOURS(sec) ((sec) / (60 * 60)) @@ -274,16 +275,16 @@ enum { VERBOSE_FIXED_TIME =3D 0x2, }; =20 -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 =3D (double)tv->tv_usec / 1000000.0; + double nsec =3D (double)tv->tv_nsec / 1000000000.0; =20 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)); + (unsigned int) (nsec * 100000)); return; } format |=3D VERBOSE_FIXED_TIME; /* fallback if hours needed */ @@ -294,9 +295,9 @@ static void timestr(struct timeval *tv, char *ts, size_= t size, int format) (unsigned int) HOURS(tv->tv_sec), (unsigned int) MINUTES(tv->tv_sec), (unsigned int) SECONDS(tv->tv_sec), - (unsigned int) (usec * 100)); + (unsigned int) (nsec * 100000)); } else { - snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000)); + snprintf(ts, size, "0.%04u sec", (unsigned int) (nsec * 10000000)); } } =20 @@ -376,7 +377,7 @@ static void dump_buffer(const void *buffer, int64_t off= set, int64_t len) } } =20 -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 offse= t, int64_t count, int64_t total, int cnt, bool Cflag) { char s1[64], s2[64], ts[64]; @@ -649,7 +650,7 @@ static const cmdinfo_t read_cmd =3D { =20 static int read_f(BlockBackend *blk, int argc, char **argv) { - struct timeval t1, t2; + struct timespec t1, t2; bool Cflag =3D false, qflag =3D false, vflag =3D false; bool Pflag =3D false, sflag =3D false, lflag =3D false, bflag =3D fals= e; int c, cnt, ret; @@ -758,13 +759,13 @@ static int read_f(BlockBackend *blk, int argc, char *= *argv) =20 buf =3D qemu_io_alloc(blk, count, 0xab); =20 - gettimeofday(&t1, NULL); + clock_gettime(CLOCK_MONOTONIC, &t1); if (bflag) { ret =3D do_load_vmstate(blk, buf, offset, count, &total); } else { ret =3D do_pread(blk, buf, offset, count, &total); } - gettimeofday(&t2, NULL); + clock_gettime(CLOCK_MONOTONIC, &t2); =20 if (ret < 0) { printf("read failed: %s\n", strerror(-ret)); @@ -836,7 +837,7 @@ static const cmdinfo_t readv_cmd =3D { =20 static int readv_f(BlockBackend *blk, int argc, char **argv) { - struct timeval t1, t2; + struct timespec t1, t2; bool Cflag =3D false, qflag =3D false, vflag =3D false; int c, cnt, ret; char *buf; @@ -891,9 +892,9 @@ static int readv_f(BlockBackend *blk, int argc, char **= argv) return -EINVAL; } =20 - gettimeofday(&t1, NULL); + clock_gettime(CLOCK_MONOTONIC,&t1); ret =3D do_aio_readv(blk, &qiov, offset, &total); - gettimeofday(&t2, NULL); + clock_gettime(CLOCK_MONOTONIC,&t2); =20 if (ret < 0) { printf("readv failed: %s\n", strerror(-ret)); @@ -972,7 +973,7 @@ static const cmdinfo_t write_cmd =3D { =20 static int write_f(BlockBackend *blk, int argc, char **argv) { - struct timeval t1, t2; + struct timespec t1, t2; bool Cflag =3D false, qflag =3D false, bflag =3D false; bool Pflag =3D false, zflag =3D false, cflag =3D false; int flags =3D 0; @@ -1091,7 +1092,7 @@ static int write_f(BlockBackend *blk, int argc, char = **argv) buf =3D qemu_io_alloc(blk, count, pattern); } =20 - gettimeofday(&t1, NULL); + clock_gettime(CLOCK_MONOTONIC,&t1); if (bflag) { ret =3D do_save_vmstate(blk, buf, offset, count, &total); } else if (zflag) { @@ -1101,7 +1102,7 @@ static int write_f(BlockBackend *blk, int argc, char = **argv) } else { ret =3D do_pwrite(blk, buf, offset, count, flags, &total); } - gettimeofday(&t2, NULL); + clock_gettime(CLOCK_MONOTONIC,&t2); =20 if (ret < 0) { printf("write failed: %s\n", strerror(-ret)); @@ -1160,7 +1161,7 @@ static const cmdinfo_t writev_cmd =3D { =20 static int writev_f(BlockBackend *blk, int argc, char **argv) { - struct timeval t1, t2; + struct timespec t1, t2; bool Cflag =3D false, qflag =3D false; int flags =3D 0; int c, cnt, ret; @@ -1213,9 +1214,9 @@ static int writev_f(BlockBackend *blk, int argc, char= **argv) return -EINVAL; } =20 - gettimeofday(&t1, NULL); + clock_gettime(CLOCK_MONOTONIC,&t1); ret =3D do_aio_writev(blk, &qiov, offset, flags, &total); - gettimeofday(&t2, NULL); + clock_gettime(CLOCK_MONOTONIC,&t2); =20 if (ret < 0) { printf("writev failed: %s\n", strerror(-ret)); @@ -1250,15 +1251,15 @@ struct aio_ctx { bool zflag; BlockAcctCookie acct; int pattern; - struct timeval t1; + struct timespec t1; }; =20 static void aio_write_done(void *opaque, int ret) { struct aio_ctx *ctx =3D opaque; - struct timeval t2; + struct timespec t2; =20 - gettimeofday(&t2, NULL); + clock_gettime(CLOCK_MONOTONIC,&t2); =20 =20 if (ret < 0) { @@ -1288,9 +1289,9 @@ out: static void aio_read_done(void *opaque, int ret) { struct aio_ctx *ctx =3D opaque; - struct timeval t2; + struct timespec t2; =20 - gettimeofday(&t2, NULL); + clock_gettime(CLOCK_MONOTONIC,&t2); =20 if (ret < 0) { printf("readv failed: %s\n", strerror(-ret)); @@ -1425,7 +1426,7 @@ static int aio_read_f(BlockBackend *blk, int argc, ch= ar **argv) return -EINVAL; } =20 - 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 +1571,7 @@ static int aio_write_f(BlockBackend *blk, int argc, c= har **argv) return -EINVAL; } =20 - 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); =20 @@ -1746,7 +1747,7 @@ static const cmdinfo_t discard_cmd =3D { =20 static int discard_f(BlockBackend *blk, int argc, char **argv) { - struct timeval t1, t2; + struct timespec t1, t2; bool Cflag =3D false, qflag =3D false; int c, ret; int64_t offset, bytes; @@ -1787,9 +1788,9 @@ static int discard_f(BlockBackend *blk, int argc, cha= r **argv) return -EINVAL; } =20 - gettimeofday(&t1, NULL); + clock_gettime(CLOCK_MONOTONIC,&t1); ret =3D blk_pdiscard(blk, offset, bytes); - gettimeofday(&t2, NULL); + clock_gettime(CLOCK_MONOTONIC,&t2); =20 if (ret < 0) { printf("discard failed: %s\n", strerror(-ret)); --=20 2.20.1