From owner-svn-src-all@freebsd.org Sat Mar 18 18:01:32 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 768A3D1249D; Sat, 18 Mar 2017 18:01:32 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2D99D1E23; Sat, 18 Mar 2017 18:01:32 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v2II1VEt061353; Sat, 18 Mar 2017 18:01:31 GMT (envelope-from trasz@FreeBSD.org) Received: (from trasz@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v2II1VHO061351; Sat, 18 Mar 2017 18:01:31 GMT (envelope-from trasz@FreeBSD.org) Message-Id: <201703181801.v2II1VHO061351@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: trasz set sender to trasz@FreeBSD.org using -f From: Edward Tomasz Napierala Date: Sat, 18 Mar 2017 18:01:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r315494 - stable/11/usr.sbin/diskinfo X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 18 Mar 2017 18:01:32 -0000 Author: trasz Date: Sat Mar 18 18:01:30 2017 New Revision: 315494 URL: https://svnweb.freebsd.org/changeset/base/315494 Log: MFC r306160: Add "diskinfo -i", a simple aio-based IOPS benchmark. Modified: stable/11/usr.sbin/diskinfo/diskinfo.8 stable/11/usr.sbin/diskinfo/diskinfo.c Modified: stable/11/usr.sbin/diskinfo/diskinfo.8 ============================================================================== --- stable/11/usr.sbin/diskinfo/diskinfo.8 Sat Mar 18 17:59:43 2017 (r315493) +++ stable/11/usr.sbin/diskinfo/diskinfo.8 Sat Mar 18 18:01:30 2017 (r315494) @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 9, 2004 +.Dd September 22, 2016 .Dt DISKINFO 8 .Os .Sh NAME @@ -36,7 +36,7 @@ .Nd get information about disk device .Sh SYNOPSIS .Nm -.Op Fl ctv +.Op Fl citv .Ar disk ... .Sh DESCRIPTION The @@ -59,6 +59,10 @@ The option triggers a simple measurement of the I/O read command overhead. .Pp The +.Fl i +option triggers a simple IOPS benchmark. +.Pp +The .Fl t option triggers a simple and rather naive benchmark of the disks seek and transfer performance. Modified: stable/11/usr.sbin/diskinfo/diskinfo.c ============================================================================== --- stable/11/usr.sbin/diskinfo/diskinfo.c Sat Mar 18 17:59:43 2017 (r315493) +++ stable/11/usr.sbin/diskinfo/diskinfo.c Sat Mar 18 18:01:30 2017 (r315494) @@ -40,22 +40,26 @@ #include #include #include +#include #include #include #include #include +#define NAIO 128 + static void usage(void) { - fprintf(stderr, "usage: diskinfo [-ctv] disk ...\n"); + fprintf(stderr, "usage: diskinfo [-citv] disk ...\n"); exit (1); } -static int opt_c, opt_t, opt_v; +static int opt_c, opt_i, opt_t, opt_v; static void speeddisk(int fd, off_t mediasize, u_int sectorsize); static void commandtime(int fd, off_t mediasize, u_int sectorsize); +static void iopsbench(int fd, off_t mediasize, u_int sectorsize); static int zonecheck(int fd, uint32_t *zone_mode, char *zone_str, size_t zone_str_len); @@ -70,12 +74,16 @@ main(int argc, char **argv) u_int sectorsize, fwsectors, fwheads, zoned = 0; uint32_t zone_mode; - while ((ch = getopt(argc, argv, "ctv")) != -1) { + while ((ch = getopt(argc, argv, "citv")) != -1) { switch (ch) { case 'c': opt_c = 1; opt_v = 1; break; + case 'i': + opt_i = 1; + opt_v = 1; + break; case 't': opt_t = 1; opt_v = 1; @@ -187,6 +195,8 @@ main(int argc, char **argv) commandtime(fd, mediasize, sectorsize); if (opt_t) speeddisk(fd, mediasize, sectorsize); + if (opt_i) + iopsbench(fd, mediasize, sectorsize); out: close(fd); } @@ -270,6 +280,16 @@ TR(double count) } static void +TI(double count) +{ + double dt; + + dt = delta_t(); + printf("%8.0f ops in %10.6f sec = %8.0f IOPS\n", + count, dt, count / dt); +} + +static void speeddisk(int fd, off_t mediasize, u_int sectorsize) { int bulk, i; @@ -421,6 +441,91 @@ commandtime(int fd, off_t mediasize, u_i return; } +static void +iops(int fd, off_t mediasize, u_int sectorsize) +{ + struct aiocb aios[NAIO], *aiop; + ssize_t ret; + off_t sectorcount; + int error, i, queued, completed; + + sectorcount = mediasize / sectorsize; + + for (i = 0; i < NAIO; i++) { + aiop = &(aios[i]); + bzero(aiop, sizeof(*aiop)); + aiop->aio_buf = malloc(sectorsize); + if (aiop->aio_buf == NULL) + err(1, "malloc"); + } + + T0(); + for (i = 0; i < NAIO; i++) { + aiop = &(aios[i]); + + aiop->aio_fildes = fd; + aiop->aio_offset = (random() % (sectorcount)) * sectorsize; + aiop->aio_nbytes = sectorsize; + + error = aio_read(aiop); + if (error != 0) + err(1, "aio_read"); + } + + queued = i; + completed = 0; + + for (;;) { + ret = aio_waitcomplete(&aiop, NULL); + if (ret < 0) + err(1, "aio_waitcomplete"); + if (ret != (ssize_t)sectorsize) + errx(1, "short read"); + + completed++; + + if (delta_t() < 3.0) { + aiop->aio_fildes = fd; + aiop->aio_offset = (random() % (sectorcount)) * sectorsize; + aiop->aio_nbytes = sectorsize; + + error = aio_read(aiop); + if (error != 0) + err(1, "aio_read"); + + queued++; + } else if (completed == queued) { + break; + } + } + + TI(completed); + + return; +} + +static void +iopsbench(int fd, off_t mediasize, u_int sectorsize) +{ + printf("Asynchronous random reads:\n"); + + printf("\tsectorsize: "); + iops(fd, mediasize, sectorsize); + + if (sectorsize != 4096) { + printf("\t4 kbytes: "); + iops(fd, mediasize, 4096); + } + + printf("\t32 kbytes: "); + iops(fd, mediasize, 32 * 1024); + + printf("\t128 kbytes: "); + iops(fd, mediasize, 128 * 1024); + + printf("\n"); +} + static int zonecheck(int fd, uint32_t *zone_mode, char *zone_str, size_t zone_str_len) {