summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2016-05-25 07:09:54 +0000
committermav <mav@FreeBSD.org>2016-05-25 07:09:54 +0000
commitd748f0adede2aeb8cb93f4f727575df0987fec63 (patch)
treec3ddc45d3097fc4ebffb152e65e728afd2d6e73f /tools
parent9067c52647a790e0945bbadd59190a5e1be02e48 (diff)
downloadFreeBSD-src-d748f0adede2aeb8cb93f4f727575df0987fec63.zip
FreeBSD-src-d748f0adede2aeb8cb93f4f727575df0987fec63.tar.gz
MFC ioat(4) driver in its present state.
Diffstat (limited to 'tools')
-rw-r--r--tools/tools/ioat/Makefile9
-rw-r--r--tools/tools/ioat/ioatcontrol.8182
-rw-r--r--tools/tools/ioat/ioatcontrol.c258
3 files changed, 449 insertions, 0 deletions
diff --git a/tools/tools/ioat/Makefile b/tools/tools/ioat/Makefile
new file mode 100644
index 0000000..7ea3e6e
--- /dev/null
+++ b/tools/tools/ioat/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+PROG= ioatcontrol
+MAN= ioatcontrol.8
+CFLAGS+= -I${.CURDIR:H:H:H}/sys/dev/ioat
+WARNS?= 6
+LIBADD= util
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ioat/ioatcontrol.8 b/tools/tools/ioat/ioatcontrol.8
new file mode 100644
index 0000000..9e156fd
--- /dev/null
+++ b/tools/tools/ioat/ioatcontrol.8
@@ -0,0 +1,182 @@
+.\" Copyright (c) 2015 EMC / Isilon Storage Division
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd December 14, 2015
+.Dt IOATCONTROL 8
+.Os
+.Sh NAME
+.Nm ioatcontrol
+.Nd Userspace tool to test
+.Xr ioat 4
+.Sh SYNOPSIS
+.Nm
+.Op Fl c Ar period
+.Op Fl E
+.Op Fl f
+.Op Fl m
+.Op Fl V
+.Op Fl z
+.Ar channel_number
+.Ar num_txns
+.Ar [ bufsize
+.Ar [ chain-len
+.Ar [ duration ] ] ]
+.Nm
+.Fl r
+.Op Fl c Ar period
+.Op Fl v
+.Op Fl V
+.Op Fl w
+.Op Fl z
+.Ar channel_number
+.Ar address
+.Ar [ bufsize ]
+.Sh DESCRIPTION
+.Nm
+allows one to issue some number of test operations to the
+.Xr ioat 4
+driver on a specific hardware channel.
+The arguments are as follows:
+.Bl -tag -width Ds
+.It Fl c Ar period
+Configure the channel's interrupt coalescing period, in microseconds.
+.It Fl E
+Test non-contiguous 8k copy.
+.It Fl f
+Test block fill (by default,
+.Nm
+tests copy)
+.It Fl m
+Test memcpy instead of DMA.
+.It Fl V
+Verify copies/fills for accuracy
+.It Fl z
+Zero device statistics before running test.
+.El
+.Pp
+Alternatively one can use
+.Nm
+.Fl r
+to issue DMA to or from a specific
+.Ar address .
+The arguments in "raw" mode are:
+.Bl -tag -width Ds
+.It Fl c Ar period
+As above.
+.It Fl v
+.Ar address
+is a kernel virtual address (by default,
+.Ar address
+is assumed to be a physical address)
+.It Fl V
+Dump the resulting hex to syslog
+.It Fl w
+Write to the specified
+.Ar address
+(by default,
+.Nm
+.Fl r
+reads)
+.It Fl z
+As above.
+.El
+.Pp
+.Nm
+operates in one of two modes; if the
+.Ar duration
+argument is passed,
+.Nm
+tries to estimate the copy rate in bytes per second by running
+.Ar num_txns
+repeatedly in loop.
+If
+.Ar duration
+is not passed,
+.Nm
+only runs through
+.Ar num_txns
+once and prints the total bytes copied, as well as error information.
+.Pp
+The
+.Ar bufsize
+argument determines the size of buffers to use for each
+.Fn ioat_copy
+invocation.
+The default is 256 KB.
+In raw mode, the default is 4 KB.
+.Pp
+The
+.Ar chain-len
+argument determines the number of copies to chain together in a single DMA
+transaction.
+The default is 1, and the maximum is currently 4.
+.Pp
+The
+.Ar duration
+argument specifies an approximate time limit for the test, in milliseconds.
+.Pp
+The test will allocate two chunks of memory for each component of each
+transaction's chain.
+It will initialize them with specific data patterns.
+During the test, it submits DMA requests to copy between pairs of buffers.
+If the
+.Fl V
+flag was specified, it will compare the contents in the callback for a copy
+error.
+.Sh FILES
+.Pa /dev/ioat_test
+.Pp
+The interface between
+.Nm
+and
+.Xr ioat 4 .
+.Xr ioat 4
+exposes it with
+.Cd hw.ioat.enable_ioat_test=1 .
+.Sh DIAGNOSTICS
+The wait channel
+.Va test_submit
+indicates that the test code has enqueued all requested transactions and is
+waiting on the IOAT hardware to complete one before issuing another operation.
+.Sh SEE ALSO
+.Xr ioat 4
+.Sh HISTORY
+The
+.Xr ioat 4
+driver first appeared in
+.Fx 11.0 .
+.Sh AUTHORS
+The
+.Xr ioat 4
+driver and
+.Nm
+tool were developed by
+.An \&Jim Harris Aq Mt jimharris@FreeBSD.org ,
+.An \&Carl Delsey Aq Mt carl.r.delsey@intel.com ,
+and
+.An \&Conrad Meyer Aq Mt cem@FreeBSD.org .
+This manual page was written by
+.An \&Conrad Meyer Aq Mt cem@FreeBSD.org .
diff --git a/tools/tools/ioat/ioatcontrol.c b/tools/tools/ioat/ioatcontrol.c
new file mode 100644
index 0000000..32decc7
--- /dev/null
+++ b/tools/tools/ioat/ioatcontrol.c
@@ -0,0 +1,258 @@
+/*-
+ * Copyright (C) 2012 Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/ioctl.h>
+#include <sys/queue.h>
+
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+#include <libutil.h>
+
+#include "ioat_test.h"
+
+static int prettyprint(struct ioat_test *);
+
+static void
+usage(void)
+{
+
+ printf("Usage: %s [-E|-f|-m] OPTIONS <channel #> <txns> [<bufsize> "
+ "[<chain-len> [duration]]]\n", getprogname());
+ printf(" %s -r [-v] OPTIONS <channel #> <addr> [<bufsize>]\n\n",
+ getprogname());
+ printf(" OPTIONS:\n");
+ printf(" -c <period> - Enable interrupt coalescing (us)\n");
+ printf(" -V - Enable verification\n");
+ printf(" -z - Zero device stats before test\n");
+ exit(EX_USAGE);
+}
+
+static void
+main_raw(struct ioat_test *t, int argc, char **argv)
+{
+ int fd;
+
+ /* Raw DMA defaults */
+ t->testkind = IOAT_TEST_RAW_DMA;
+ t->transactions = 1;
+ t->chain_depth = 1;
+ t->buffer_size = 4 * 1024;
+
+ t->raw_target = strtoull(argv[1], NULL, 0);
+ if (t->raw_target == 0) {
+ printf("Target shoudln't be NULL\n");
+ exit(EX_USAGE);
+ }
+
+ if (argc >= 3) {
+ t->buffer_size = atoi(argv[2]);
+ if (t->buffer_size == 0) {
+ printf("Buffer size must be greater than zero\n");
+ exit(EX_USAGE);
+ }
+ }
+
+ fd = open("/dev/ioat_test", O_RDWR);
+ if (fd < 0) {
+ printf("Cannot open /dev/ioat_test\n");
+ exit(EX_UNAVAILABLE);
+ }
+
+ (void)ioctl(fd, IOAT_DMATEST, t);
+ close(fd);
+
+ exit(prettyprint(t));
+}
+
+int
+main(int argc, char **argv)
+{
+ struct ioat_test t;
+ int fd, ch;
+ bool fflag, rflag, Eflag, mflag;
+ unsigned modeflags;
+
+ fflag = rflag = Eflag = mflag = false;
+ modeflags = 0;
+
+ while ((ch = getopt(argc, argv, "c:EfmrvVwz")) != -1) {
+ switch (ch) {
+ case 'c':
+ t.coalesce_period = atoi(optarg);
+ break;
+ case 'E':
+ Eflag = true;
+ modeflags++;
+ break;
+ case 'f':
+ fflag = true;
+ modeflags++;
+ break;
+ case 'm':
+ mflag = true;
+ modeflags++;
+ break;
+ case 'r':
+ rflag = true;
+ modeflags++;
+ break;
+ case 'v':
+ t.raw_is_virtual = true;
+ break;
+ case 'V':
+ t.verify = true;
+ break;
+ case 'w':
+ t.raw_write = true;
+ break;
+ case 'z':
+ t.zero_stats = true;
+ break;
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 2)
+ usage();
+
+ if (modeflags > 1) {
+ printf("Invalid: Cannot use >1 mode flag (-E, -f, -m, or -r)\n");
+ usage();
+ }
+
+ /* Defaults for optional args */
+ t.buffer_size = 256 * 1024;
+ t.chain_depth = 2;
+ t.duration = 0;
+ t.testkind = IOAT_TEST_DMA;
+
+ if (fflag)
+ t.testkind = IOAT_TEST_FILL;
+ else if (Eflag) {
+ t.testkind = IOAT_TEST_DMA_8K;
+ t.buffer_size = 8 * 1024;
+ } else if (mflag)
+ t.testkind = IOAT_TEST_MEMCPY;
+
+ t.channel_index = atoi(argv[0]);
+ if (t.channel_index > 8) {
+ printf("Channel number must be between 0 and 7.\n");
+ return (EX_USAGE);
+ }
+
+ if (rflag) {
+ main_raw(&t, argc, argv);
+ return (EX_OK);
+ }
+
+ t.transactions = atoi(argv[1]);
+
+ if (argc >= 3) {
+ t.buffer_size = atoi(argv[2]);
+ if (t.buffer_size == 0) {
+ printf("Buffer size must be greater than zero\n");
+ return (EX_USAGE);
+ }
+ }
+
+ if (argc >= 4) {
+ t.chain_depth = atoi(argv[3]);
+ if (t.chain_depth < 1) {
+ printf("Chain length must be greater than zero\n");
+ return (EX_USAGE);
+ }
+ }
+
+ if (argc >= 5) {
+ t.duration = atoi(argv[4]);
+ if (t.duration < 1) {
+ printf("Duration must be greater than zero\n");
+ return (EX_USAGE);
+ }
+ }
+
+ fd = open("/dev/ioat_test", O_RDWR);
+ if (fd < 0) {
+ printf("Cannot open /dev/ioat_test\n");
+ return (EX_UNAVAILABLE);
+ }
+
+ (void)ioctl(fd, IOAT_DMATEST, &t);
+ close(fd);
+
+ return (prettyprint(&t));
+}
+
+static int
+prettyprint(struct ioat_test *t)
+{
+ char bps[10], bytesh[10];
+ uintmax_t bytes;
+
+ if (t->status[IOAT_TEST_NO_DMA_ENGINE] != 0 ||
+ t->status[IOAT_TEST_NO_MEMORY] != 0 ||
+ t->status[IOAT_TEST_MISCOMPARE] != 0) {
+ printf("Errors:\n");
+ if (t->status[IOAT_TEST_NO_DMA_ENGINE] != 0)
+ printf("\tNo DMA engine present: %u\n",
+ (unsigned)t->status[IOAT_TEST_NO_DMA_ENGINE]);
+ if (t->status[IOAT_TEST_NO_MEMORY] != 0)
+ printf("\tOut of memory: %u\n",
+ (unsigned)t->status[IOAT_TEST_NO_MEMORY]);
+ if (t->status[IOAT_TEST_MISCOMPARE] != 0)
+ printf("\tMiscompares: %u\n",
+ (unsigned)t->status[IOAT_TEST_MISCOMPARE]);
+ }
+
+ printf("Processed %u txns\n", (unsigned)t->status[IOAT_TEST_OK] /
+ t->chain_depth);
+ bytes = (uintmax_t)t->buffer_size * t->status[IOAT_TEST_OK];
+
+ humanize_number(bytesh, sizeof(bytesh), (int64_t)bytes, "B",
+ HN_AUTOSCALE, HN_DECIMAL);
+ if (t->duration) {
+ humanize_number(bps, sizeof(bps),
+ (int64_t)1000 * bytes / t->duration, "B/s", HN_AUTOSCALE,
+ HN_DECIMAL);
+ printf("%ju (%s) copied in %u ms (%s)\n", bytes, bytesh,
+ (unsigned)t->duration, bps);
+ } else
+ printf("%ju (%s) copied\n", bytes, bytesh);
+
+ return (EX_OK);
+}
OpenPOWER on IntegriCloud