Date: Thu, 22 Sep 2016 07:33:43 +0000 (UTC) From: Edward Tomasz Napierala <trasz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r306160 - head/usr.sbin/diskinfo Message-ID: <201609220733.u8M7XhcM081660@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: trasz Date: Thu Sep 22 07:33:43 2016 New Revision: 306160 URL: https://svnweb.freebsd.org/changeset/base/306160 Log: Add "diskinfo -i", a simple aio-based IOPS benchmark. MFC after: 1 month Modified: head/usr.sbin/diskinfo/diskinfo.8 head/usr.sbin/diskinfo/diskinfo.c Modified: head/usr.sbin/diskinfo/diskinfo.8 ============================================================================== --- head/usr.sbin/diskinfo/diskinfo.8 Thu Sep 22 06:24:40 2016 (r306159) +++ head/usr.sbin/diskinfo/diskinfo.8 Thu Sep 22 07:33:43 2016 (r306160) @@ -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: head/usr.sbin/diskinfo/diskinfo.c ============================================================================== --- head/usr.sbin/diskinfo/diskinfo.c Thu Sep 22 06:24:40 2016 (r306159) +++ head/usr.sbin/diskinfo/diskinfo.c Thu Sep 22 07:33:43 2016 (r306160) @@ -40,22 +40,26 @@ #include <libutil.h> #include <paths.h> #include <err.h> +#include <sys/aio.h> #include <sys/disk.h> #include <sys/param.h> #include <sys/stat.h> #include <sys/time.h> +#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; @@ -188,6 +196,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; @@ -418,6 +438,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) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609220733.u8M7XhcM081660>