perftest.c revision 253109
1193326Sed/*- 2193326Sed * Copyright (C) 2012-2013 Intel Corporation 3193326Sed * All rights reserved. 4193326Sed * 5193326Sed * Redistribution and use in source and binary forms, with or without 6193326Sed * modification, are permitted provided that the following conditions 7193326Sed * are met: 8193326Sed * 1. Redistributions of source code must retain the above copyright 9193326Sed * notice, this list of conditions and the following disclaimer. 10193326Sed * 2. Redistributions in binary form must reproduce the above copyright 11193326Sed * notice, this list of conditions and the following disclaimer in the 12193326Sed * documentation and/or other materials provided with the distribution. 13193326Sed * 14193326Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15193326Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16193326Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17193326Sed * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18252723Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19226890Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20252723Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21201361Srdivacky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22193326Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23245431Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24218893Sdim * SUCH DAMAGE. 25193326Sed */ 26193326Sed 27193326Sed#include <sys/cdefs.h> 28226890Sdim__FBSDID("$FreeBSD: head/sbin/nvmecontrol/perftest.c 253109 2013-07-09 21:14:15Z jimharris $"); 29193326Sed 30193326Sed#include <sys/param.h> 31193326Sed#include <sys/ioccom.h> 32193326Sed 33218893Sdim#include <ctype.h> 34218893Sdim#include <err.h> 35198092Srdivacky#include <fcntl.h> 36193326Sed#include <stdbool.h> 37193326Sed#include <stddef.h> 38193326Sed#include <stdio.h> 39193326Sed#include <stdlib.h> 40193326Sed#include <string.h> 41198092Srdivacky#include <unistd.h> 42193326Sed 43193326Sed#include "nvmecontrol.h" 44193326Sed 45193326Sedstatic void 46198092Srdivackyprint_perftest(struct nvme_io_test *io_test, bool perthread) 47193326Sed{ 48198092Srdivacky uint32_t i, io_completed = 0, iops, mbps; 49235633Sdim 50198092Srdivacky for (i = 0; i < io_test->num_threads; i++) 51193326Sed io_completed += io_test->io_completed[i]; 52245431Sdim 53245431Sdim iops = io_completed/io_test->time; 54245431Sdim mbps = iops * io_test->size / (1024*1024); 55193326Sed 56193326Sed printf("Threads: %2d Size: %6d %5s Time: %3d IO/s: %7d MB/s: %4d\n", 57193326Sed io_test->num_threads, io_test->size, 58193326Sed io_test->opc == NVME_OPC_READ ? "READ" : "WRITE", 59193326Sed io_test->time, iops, mbps); 60193326Sed 61198092Srdivacky if (perthread) 62198092Srdivacky for (i = 0; i < io_test->num_threads; i++) 63198092Srdivacky printf("\t%3d: %8d IO/s\n", i, 64193326Sed io_test->io_completed[i]/io_test->time); 65193326Sed 66193326Sed exit(1); 67193326Sed} 68193326Sed 69235633Sdimstatic void 70235633Sdimperftest_usage(void) 71235633Sdim{ 72193326Sed fprintf(stderr, "usage:\n"); 73235633Sdim fprintf(stderr, PERFTEST_USAGE); 74235633Sdim exit(1); 75235633Sdim} 76235633Sdim 77235633Sdimvoid 78235633Sdimperftest(int argc, char *argv[]) 79235633Sdim{ 80235633Sdim struct nvme_io_test io_test; 81198092Srdivacky int fd; 82263509Sdim char ch; 83263509Sdim char *p; 84193326Sed u_long ioctl_cmd = NVME_IO_TEST; 85198092Srdivacky bool nflag, oflag, sflag, tflag; 86193326Sed int perthread = 0; 87193326Sed 88193326Sed nflag = oflag = sflag = tflag = false; 89193326Sed 90193326Sed memset(&io_test, 0, sizeof(io_test)); 91198092Srdivacky 92193326Sed while ((ch = getopt(argc, argv, "f:i:n:o:ps:t:")) != -1) { 93193326Sed switch (ch) { 94193326Sed case 'f': 95193326Sed if (!strcmp(optarg, "refthread")) 96193326Sed io_test.flags |= NVME_TEST_FLAG_REFTHREAD; 97201361Srdivacky break; 98193326Sed case 'i': 99198092Srdivacky if (!strcmp(optarg, "bio") || 100198092Srdivacky !strcmp(optarg, "wait")) 101193326Sed ioctl_cmd = NVME_BIO_TEST; 102198092Srdivacky else if (!strcmp(optarg, "io") || 103263509Sdim !strcmp(optarg, "intr")) 104263509Sdim ioctl_cmd = NVME_IO_TEST; 105263509Sdim break; 106263509Sdim case 'n': 107263509Sdim nflag = true; 108263509Sdim io_test.num_threads = strtoul(optarg, &p, 0); 109263509Sdim if (p != NULL && *p != '\0') { 110263509Sdim fprintf(stderr, 111193326Sed "\"%s\" not valid number of threads.\n", 112193326Sed optarg); 113193326Sed perftest_usage(); 114263509Sdim } else if (io_test.num_threads == 0 || 115193326Sed io_test.num_threads > 128) { 116193326Sed fprintf(stderr, 117193326Sed "\"%s\" not valid number of threads.\n", 118198092Srdivacky optarg); 119193326Sed perftest_usage(); 120193326Sed } 121193326Sed break; 122263509Sdim case 'o': 123263509Sdim oflag = true; 124193326Sed if (!strcmp(optarg, "read") || !strcmp(optarg, "READ")) 125193326Sed io_test.opc = NVME_OPC_READ; 126193326Sed else if (!strcmp(optarg, "write") || 127198092Srdivacky !strcmp(optarg, "WRITE")) 128193326Sed io_test.opc = NVME_OPC_WRITE; 129193326Sed else { 130193326Sed fprintf(stderr, "\"%s\" not valid opcode.\n", 131263509Sdim optarg); 132193326Sed perftest_usage(); 133193326Sed } 134193326Sed break; 135198092Srdivacky case 'p': 136193326Sed perthread = 1; 137193326Sed break; 138193326Sed case 's': 139263509Sdim sflag = true; 140263509Sdim io_test.size = strtoul(optarg, &p, 0); 141193326Sed if (p == NULL || *p == '\0' || toupper(*p) == 'B') { 142193326Sed // do nothing 143193326Sed } else if (toupper(*p) == 'K') { 144198092Srdivacky io_test.size *= 1024; 145193326Sed } else if (toupper(*p) == 'M') { 146193326Sed io_test.size *= 1024 * 1024; 147193326Sed } else { 148193326Sed fprintf(stderr, "\"%s\" not valid size.\n", 149193326Sed optarg); 150193326Sed perftest_usage(); 151226890Sdim } 152193326Sed break; 153193326Sed case 't': 154235633Sdim tflag = true; 155235633Sdim io_test.time = strtoul(optarg, &p, 0); 156193326Sed if (p != NULL && *p != '\0') { 157193326Sed fprintf(stderr, 158226890Sdim "\"%s\" not valid time duration.\n", 159226890Sdim optarg); 160193326Sed perftest_usage(); 161193326Sed } 162226890Sdim break; 163226890Sdim } 164226890Sdim } 165226890Sdim 166193326Sed if (!nflag || !oflag || !sflag || !tflag || optind >= argc) 167193326Sed perftest_usage(); 168235633Sdim 169235633Sdim open_dev(argv[optind], &fd, 1, 1); 170235633Sdim if (ioctl(fd, ioctl_cmd, &io_test) < 0) 171235633Sdim err(1, "ioctl NVME_IO_TEST failed"); 172235633Sdim 173193326Sed close(fd); 174193326Sed print_perftest(&io_test, perthread); 175193326Sed exit(0); 176193326Sed} 177193326Sed