aboutsummaryrefslogtreecommitdiff
path: root/tools/tools
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2015-10-29 04:16:16 +0000
committerConrad Meyer <cem@FreeBSD.org>2015-10-29 04:16:16 +0000
commite9497f9bbd2ac5e16b9d913c89ff2d2a08f52cd7 (patch)
tree63b6a27f2cd8595b1327c9198eead709529ef4bc /tools/tools
parent52eab858c03174e617ed86357ec600af94d49615 (diff)
downloadsrc-e9497f9bbd2ac5e16b9d913c89ff2d2a08f52cd7.tar.gz
src-e9497f9bbd2ac5e16b9d913c89ff2d2a08f52cd7.zip
ioatcontrol(8): Add and document "raw" testing mode
Allows DMA from/to arbitrary KVA or physical address. /dev/ioat_test must be enabled by root and is only R/W root, so this is approximately as dangerous as /dev/mem and /dev/kmem. Sponsored by: EMC / Isilon Storage Division
Notes
Notes: svn path=/head/; revision=290129
Diffstat (limited to 'tools/tools')
-rw-r--r--tools/tools/ioat/ioatcontrol.834
-rw-r--r--tools/tools/ioat/ioatcontrol.c62
2 files changed, 93 insertions, 3 deletions
diff --git a/tools/tools/ioat/ioatcontrol.8 b/tools/tools/ioat/ioatcontrol.8
index 7e3234825eda..2306d3876a36 100644
--- a/tools/tools/ioat/ioatcontrol.8
+++ b/tools/tools/ioat/ioatcontrol.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 26, 2015
+.Dd October 28, 2015
.Dt IOATCONTROL 8
.Os
.Sh NAME
@@ -40,6 +40,14 @@
.Ar [ bufsize
.Ar [ chain-len
.Ar [ duration ] ] ]
+.Nm
+.Fl r
+.Op Fl v
+.Op Fl V
+.Op Fl w
+.Ar channel_number
+.Ar address
+.Ar [ bufsize ]
.Sh DESCRIPTION
.Nm
allows one to issue some number of test operations to the
@@ -55,6 +63,29 @@ tests copy)
Verify copies/fills for accuracy
.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 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)
+.El
+.Pp
.Nm
operates in one of two modes; if the
.Ar duration
@@ -77,6 +108,7 @@ 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
diff --git a/tools/tools/ioat/ioatcontrol.c b/tools/tools/ioat/ioatcontrol.c
index e55ce4f605d3..90255e7c7d25 100644
--- a/tools/tools/ioat/ioatcontrol.c
+++ b/tools/tools/ioat/ioatcontrol.c
@@ -50,24 +50,72 @@ usage(void)
printf("Usage: %s [-fV] <channel #> <txns> [<bufsize> "
"[<chain-len> [duration]]]\n", getprogname());
+ printf(" %s -r [-vV] <channel #> <addr> [<bufsize>]\n",
+ getprogname());
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;
+ bool fflag, rflag;
- while ((ch = getopt(argc, argv, "fV")) != -1) {
+ while ((ch = getopt(argc, argv, "rfvVw")) != -1) {
switch (ch) {
case 'f':
fflag = true;
break;
+ case 'r':
+ rflag = true;
+ break;
+ case 'v':
+ t.raw_is_virtual = true;
+ break;
case 'V':
t.verify = true;
break;
+ case 'w':
+ t.raw_write = true;
+ break;
default:
usage();
}
@@ -78,6 +126,11 @@ main(int argc, char **argv)
if (argc < 2)
usage();
+ if (rflag && fflag) {
+ printf("Invalid: -r and -f\n");
+ usage();
+ }
+
/* Defaults for optional args */
t.buffer_size = 256 * 1024;
t.chain_depth = 2;
@@ -93,6 +146,11 @@ main(int argc, char **argv)
return (EX_USAGE);
}
+ if (rflag) {
+ main_raw(&t, argc, argv);
+ return (EX_OK);
+ }
+
t.transactions = atoi(argv[1]);
if (argc >= 3) {