From nobody Mon Feb 9 23:03:13 2026 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=1559211537; cv=none; d=zoho.com; s=zohoarc; b=kJFj3U9a1ZhiKai0Zb2WeVSsWOwxC0Fx+bVBrc6H44y+B5hsMlKhzruoGHDizN0UfAKAk4BlUwZLfj8QbIX3goVEn8+sFkHB2BOWYUvP77MCvn9BBUOg4DUme1OOAl1HBoSAQ/aum+jkUjFWenNO6Lh5Xg3w1adxthtZPrf849I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559211537; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=BFjisebq0hiOO8nTLU3fa+Dkmd/UUHwPkWgZnwgthE0=; b=fXyVuN/Z1NZdwFGfJmCKcHZUFZ2kTwGmzATp7bbX5a41M5CctOJJrPA2cw9VXK+IYrkrWZ8OsLokmw3LErzLB3wS+XJR3P+0ZDVx9mX2kpdMB6xmP8xkGCTYPS7SGGSrnsKrSi8AoPt1v+YVx88Nqy9I3QThkvMgay3HSjea/9Y= 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 1559211537806855.7615656104955; Thu, 30 May 2019 03:18:57 -0700 (PDT) Received: from localhost ([127.0.0.1]:50555 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hWI8z-0003sk-Nz for importer@patchew.org; Thu, 30 May 2019 06:18:45 -0400 Received: from eggs.gnu.org ([209.51.188.92]:54254) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hWI6U-0002ZH-7F for qemu-devel@nongnu.org; Thu, 30 May 2019 06:16:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hWI6S-0006Rx-Ml for qemu-devel@nongnu.org; Thu, 30 May 2019 06:16:10 -0400 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]:54260) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hWI6S-0006R7-FR for qemu-devel@nongnu.org; Thu, 30 May 2019 06:16:08 -0400 Received: by mail-wm1-x342.google.com with SMTP id d17so3593610wmb.3 for ; Thu, 30 May 2019 03:16:08 -0700 (PDT) Received: from zen.linaroharston ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id h12sm1917464wre.14.2019.05.30.03.16.04 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Thu, 30 May 2019 03:16:04 -0700 (PDT) Received: from zen.linaroharston. (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 31D7F1FF8F; Thu, 30 May 2019 11:16:04 +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:in-reply-to:references :mime-version:content-transfer-encoding; bh=BFjisebq0hiOO8nTLU3fa+Dkmd/UUHwPkWgZnwgthE0=; b=oWYG3OsZHSvMDtOSOcqGd358S7FY6Qy7aFfdfAXFGpkWzeTJyPHN5EcqeLWu/2995E eYL9nAaDcAfdl3Zp50yUa4ArvHxS8zek5XoB6fS7RyeXmByX8HBwBGbWhVyttf5+ks99 jueFlGH8XasYjgJN3WSMP5oWG0IxHzBGZWgHFXTjbjGzOnjiWkTqfGKDPZMj8A5kBNz0 k/RwgaL8UiU77pkiM7lW3TDHYVq9s50x22sn+DGwV2GUEZgBFOlDm93nIWrp8Sj919Ou N+gTklJvg7OTyiqni61wauYxGklPccK1AU9Q2xYbgGa8FY8ourmuZv9l4NnUQU7W/GPt Bbrw== 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=BFjisebq0hiOO8nTLU3fa+Dkmd/UUHwPkWgZnwgthE0=; b=BT1KFrD5qkHPhInFCF+Y6bsJBpTN0/gTlhByyRIE3h2Cd80IBNNE+GQ5C6TPnD5Ckp Kgt3sqY5swSr/8sPXOqACZkn5J0l2rtWTR2IBGzIc8BDvnOXUFWFzQvO4S8KONwHofiz WzqW/BT67zgE5Y2b2dfaiq8+tWM2FNgxNZ1nFskSe4PVFaa+VYe0xl9zBPu9ogoWXMpl yNv6tD8tUdCzbvn++v4XP/gLIWN7XZQgyw3qm1/PJb9IS+SsuT/5BrhQ1AxeYlVtzp87 yJY0Gjvt4ePXMgV3mvRhQy7cCau1BxxfLGdLNV776urOsgYm5tasQQF4dnmZSEt0Virp 0ZXg== X-Gm-Message-State: APjAAAUAV869yoWjBa6LCc5V0TMliL+pVhgXNrP3R0EQSeQafuzaOC5r wVy464BRpKuMdJn6zQM0akw0rQ== X-Google-Smtp-Source: APXvYqyZBlYGdwJiueywb0PiVnPzW7eEvT6GTvBWQ1WqZcrEV3v2U2ebgxIjc4FUyROC89NTiKQLrw== X-Received: by 2002:a1c:407:: with SMTP id 7mr1852691wme.113.1559211367301; Thu, 30 May 2019 03:16:07 -0700 (PDT) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: qemu-devel@nongnu.org Date: Thu, 30 May 2019 11:15:39 +0100 Message-Id: <20190530101603.22254-3-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190530101603.22254-1-alex.bennee@linaro.org> References: <20190530101603.22254-1-alex.bennee@linaro.org> 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::342 Subject: [Qemu-devel] [PATCH v1 02/26] 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..f6701e3b8a8 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