summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcem <cem@FreeBSD.org>2015-12-10 02:05:35 +0000
committercem <cem@FreeBSD.org>2015-12-10 02:05:35 +0000
commit0a85f054bd5a318ab31fd192648b716a85572349 (patch)
treec863c582e8c0f35db4d5e469cc3e0b074a220f17
parent7d03b5290e120264ab7a32f6b787241e05841c65 (diff)
downloadFreeBSD-src-0a85f054bd5a318ab31fd192648b716a85572349.zip
FreeBSD-src-0a85f054bd5a318ab31fd192648b716a85572349.tar.gz
ioat(4): Add ioatcontrol(8) testing for copy_8k
Add -E ("Eight k") and -m ("Memcpy") modes to the ioatcontrol(8) tool. Prompted by: rpokala Sponsored by: EMC / Isilon Storage Division
-rw-r--r--sys/dev/ioat/ioat_test.c53
-rw-r--r--sys/dev/ioat/ioat_test.h2
-rw-r--r--tools/tools/ioat/ioatcontrol.88
-rw-r--r--tools/tools/ioat/ioatcontrol.c29
4 files changed, 77 insertions, 15 deletions
diff --git a/sys/dev/ioat/ioat_test.c b/sys/dev/ioat/ioat_test.c
index a8311ab..f39786e 100644
--- a/sys/dev/ioat/ioat_test.c
+++ b/sys/dev/ioat/ioat_test.c
@@ -84,11 +84,17 @@ static inline void _ioat_test_log(int verbosity, const char *fmt, ...);
static void
ioat_test_transaction_destroy(struct test_transaction *tx)
{
+ struct ioat_test *test;
int i;
+ test = tx->test;
+
for (i = 0; i < IOAT_MAX_BUFS; i++) {
if (tx->buf[i] != NULL) {
- contigfree(tx->buf[i], tx->length, M_IOAT_TEST);
+ if (test->testkind == IOAT_TEST_DMA_8K)
+ free(tx->buf[i], M_IOAT_TEST);
+ else
+ contigfree(tx->buf[i], tx->length, M_IOAT_TEST);
tx->buf[i] = NULL;
}
}
@@ -97,8 +103,8 @@ ioat_test_transaction_destroy(struct test_transaction *tx)
}
static struct
-test_transaction *ioat_test_transaction_create(unsigned num_buffers,
- uint32_t buffer_size)
+test_transaction *ioat_test_transaction_create(struct ioat_test *test,
+ unsigned num_buffers)
{
struct test_transaction *tx;
unsigned i;
@@ -107,11 +113,16 @@ test_transaction *ioat_test_transaction_create(unsigned num_buffers,
if (tx == NULL)
return (NULL);
- tx->length = buffer_size;
+ tx->length = test->buffer_size;
for (i = 0; i < num_buffers; i++) {
- tx->buf[i] = contigmalloc(buffer_size, M_IOAT_TEST, M_NOWAIT,
- 0, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
+ if (test->testkind == IOAT_TEST_DMA_8K)
+ tx->buf[i] = malloc(test->buffer_size, M_IOAT_TEST,
+ M_NOWAIT);
+ else
+ tx->buf[i] = contigmalloc(test->buffer_size,
+ M_IOAT_TEST, M_NOWAIT, 0, BUS_SPACE_MAXADDR,
+ PAGE_SIZE, 0);
if (tx->buf[i] == NULL) {
ioat_test_transaction_destroy(tx);
@@ -197,8 +208,7 @@ ioat_test_prealloc_memory(struct ioat_test *test, int index)
struct test_transaction *tx;
for (i = 0; i < test->transactions; i++) {
- tx = ioat_test_transaction_create(test->chain_depth * 2,
- test->buffer_size);
+ tx = ioat_test_transaction_create(test, test->chain_depth * 2);
if (tx == NULL) {
ioat_test_log(0, "tx == NULL - memory exhausted\n");
test->status[IOAT_TEST_NO_MEMORY]++;
@@ -258,8 +268,16 @@ ioat_test_submit_1_tx(struct ioat_test *test, bus_dmaengine_t dma)
TAILQ_INSERT_HEAD(&test->pend_q, tx, entry);
IT_UNLOCK();
- ioat_acquire(dma);
+ if (test->testkind != IOAT_TEST_MEMCPY)
+ ioat_acquire(dma);
for (i = 0; i < tx->depth; i++) {
+ if (test->testkind == IOAT_TEST_MEMCPY) {
+ memcpy(tx->buf[2 * i + 1], tx->buf[2 * i], tx->length);
+ if (i == tx->depth - 1)
+ ioat_dma_test_callback(tx, 0);
+ continue;
+ }
+
src = vtophys((vm_offset_t)tx->buf[2*i]);
dest = vtophys((vm_offset_t)tx->buf[2*i+1]);
@@ -286,10 +304,20 @@ ioat_test_submit_1_tx(struct ioat_test *test, bus_dmaengine_t dma)
fillpattern = *(uint64_t *)tx->buf[2*i];
desc = ioat_blockfill(dma, dest, fillpattern,
tx->length, cb, tx, flags);
+ } else if (test->testkind == IOAT_TEST_DMA_8K) {
+ bus_addr_t src2, dst2;
+
+ src2 = vtophys((vm_offset_t)tx->buf[2*i] + PAGE_SIZE);
+ dst2 = vtophys((vm_offset_t)tx->buf[2*i+1] + PAGE_SIZE);
+
+ desc = ioat_copy_8k_aligned(dma, dest, dst2, src, src2,
+ cb, tx, flags);
}
if (desc == NULL)
break;
}
+ if (test->testkind == IOAT_TEST_MEMCPY)
+ return;
ioat_release(dma);
/*
@@ -317,6 +345,13 @@ ioat_dma_test(void *arg)
test = arg;
memset(__DEVOLATILE(void *, test->status), 0, sizeof(test->status));
+ if (test->testkind == IOAT_TEST_DMA_8K &&
+ test->buffer_size != 2 * PAGE_SIZE) {
+ ioat_test_log(0, "Asked for 8k test and buffer size isn't 8k\n");
+ test->status[IOAT_TEST_INVALID_INPUT]++;
+ return;
+ }
+
if (test->buffer_size > 1024 * 1024) {
ioat_test_log(0, "Buffer size too large >1MB\n");
test->status[IOAT_TEST_NO_MEMORY]++;
diff --git a/sys/dev/ioat/ioat_test.h b/sys/dev/ioat/ioat_test.h
index b6e6a15..4306b3b 100644
--- a/sys/dev/ioat/ioat_test.h
+++ b/sys/dev/ioat/ioat_test.h
@@ -42,6 +42,8 @@ enum ioat_test_kind {
IOAT_TEST_FILL = 0,
IOAT_TEST_DMA,
IOAT_TEST_RAW_DMA,
+ IOAT_TEST_DMA_8K,
+ IOAT_TEST_MEMCPY,
IOAT_NUM_TESTKINDS
};
diff --git a/tools/tools/ioat/ioatcontrol.8 b/tools/tools/ioat/ioatcontrol.8
index 2306d38..002759f 100644
--- a/tools/tools/ioat/ioatcontrol.8
+++ b/tools/tools/ioat/ioatcontrol.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 28, 2015
+.Dd December 9, 2015
.Dt IOATCONTROL 8
.Os
.Sh NAME
@@ -33,7 +33,9 @@
.Xr ioat 4
.Sh SYNOPSIS
.Nm
+.Op Fl E
.Op Fl f
+.Op Fl m
.Op Fl V
.Ar channel_number
.Ar num_txns
@@ -55,10 +57,14 @@ allows one to issue some number of test operations to the
driver on a specific hardware channel.
The arguments are as follows:
.Bl -tag -width Ds
+.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
.El
diff --git a/tools/tools/ioat/ioatcontrol.c b/tools/tools/ioat/ioatcontrol.c
index 90255e7..d40ae15 100644
--- a/tools/tools/ioat/ioatcontrol.c
+++ b/tools/tools/ioat/ioatcontrol.c
@@ -48,7 +48,7 @@ static void
usage(void)
{
- printf("Usage: %s [-fV] <channel #> <txns> [<bufsize> "
+ printf("Usage: %s [-E|-f|-m] [-V] <channel #> <txns> [<bufsize> "
"[<chain-len> [duration]]]\n", getprogname());
printf(" %s -r [-vV] <channel #> <addr> [<bufsize>]\n",
getprogname());
@@ -97,15 +97,29 @@ main(int argc, char **argv)
{
struct ioat_test t;
int fd, ch;
- bool fflag, rflag;
+ bool fflag, rflag, Eflag, mflag;
+ unsigned modeflags;
- while ((ch = getopt(argc, argv, "rfvVw")) != -1) {
+ fflag = rflag = Eflag = mflag = false;
+ modeflags = 0;
+
+ while ((ch = getopt(argc, argv, "EfmrvVw")) != -1) {
switch (ch) {
+ 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;
@@ -126,8 +140,8 @@ main(int argc, char **argv)
if (argc < 2)
usage();
- if (rflag && fflag) {
- printf("Invalid: -r and -f\n");
+ if (modeflags > 1) {
+ printf("Invalid: Cannot use >1 mode flag (-E, -f, -m, or -r)\n");
usage();
}
@@ -139,6 +153,11 @@ main(int argc, char **argv)
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) {
OpenPOWER on IntegriCloud