diff --git a/sys/dev/ioat/ioat_test.c b/sys/dev/ioat/ioat_test.c index f39786e07c4b..ee014c096271 100644 --- a/sys/dev/ioat/ioat_test.c +++ b/sys/dev/ioat/ioat_test.c @@ -337,10 +337,11 @@ ioat_test_submit_1_tx(struct ioat_test *test, bus_dmaengine_t dma) static void ioat_dma_test(void *arg) { + struct ioat_softc *ioat; struct ioat_test *test; bus_dmaengine_t dmaengine; uint32_t loops; - int index, rc, start, end; + int index, rc, start, end, error; test = arg; memset(__DEVOLATILE(void *, test->status), 0, sizeof(test->status)); @@ -393,9 +394,10 @@ ioat_dma_test(void *arg) test->status[IOAT_TEST_NO_DMA_ENGINE]++; return; } + ioat = to_ioat_softc(dmaengine); if (test->testkind == IOAT_TEST_FILL && - (to_ioat_softc(dmaengine)->capabilities & IOAT_DMACAP_BFILL) == 0) + (ioat->capabilities & IOAT_DMACAP_BFILL) == 0) { ioat_test_log(0, "Hardware doesn't support block fill, aborting test\n"); @@ -403,6 +405,25 @@ ioat_dma_test(void *arg) goto out; } + if (test->coalesce_period > ioat->intrdelay_max) { + ioat_test_log(0, + "Hardware doesn't support intrdelay of %u us.\n", + (unsigned)test->coalesce_period); + test->status[IOAT_TEST_INVALID_INPUT]++; + goto out; + } + error = ioat_set_interrupt_coalesce(dmaengine, test->coalesce_period); + if (error == ENODEV && test->coalesce_period == 0) + error = 0; + if (error != 0) { + ioat_test_log(0, "ioat_set_interrupt_coalesce: %d\n", error); + test->status[IOAT_TEST_INVALID_INPUT]++; + goto out; + } + + if (test->zero_stats) + memset(&ioat->stats, 0, sizeof(ioat->stats)); + if (test->testkind == IOAT_TEST_RAW_DMA) { if (test->raw_is_virtual) { test->raw_vtarget = (void *)test->raw_target; diff --git a/sys/dev/ioat/ioat_test.h b/sys/dev/ioat/ioat_test.h index 4306b3bffff1..8ef521c57361 100644 --- a/sys/dev/ioat/ioat_test.h +++ b/sys/dev/ioat/ioat_test.h @@ -75,6 +75,10 @@ struct ioat_test { bool raw_write; bool raw_is_virtual; + bool zero_stats; + /* Configure coalesce period */ + uint16_t coalesce_period; + /* Internal usage -- not test inputs */ TAILQ_HEAD(, test_transaction) free_q; TAILQ_HEAD(, test_transaction) pend_q; diff --git a/tools/tools/ioat/ioatcontrol.8 b/tools/tools/ioat/ioatcontrol.8 index 002759fb5be8..9e156fd89892 100644 --- a/tools/tools/ioat/ioatcontrol.8 +++ b/tools/tools/ioat/ioatcontrol.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 9, 2015 +.Dd December 14, 2015 .Dt IOATCONTROL 8 .Os .Sh NAME @@ -33,10 +33,12 @@ .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 @@ -44,9 +46,11 @@ .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 ] @@ -57,6 +61,8 @@ 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 c Ar period +Configure the channel's interrupt coalescing period, in microseconds. .It Fl E Test non-contiguous 8k copy. .It Fl f @@ -67,6 +73,8 @@ tests copy) 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 @@ -76,6 +84,8 @@ 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, @@ -90,6 +100,8 @@ Write to the specified .Nm .Fl r reads) +.It Fl z +As above. .El .Pp .Nm diff --git a/tools/tools/ioat/ioatcontrol.c b/tools/tools/ioat/ioatcontrol.c index d40ae1506882..32decc77a2f7 100644 --- a/tools/tools/ioat/ioatcontrol.c +++ b/tools/tools/ioat/ioatcontrol.c @@ -48,10 +48,14 @@ static void usage(void) { - printf("Usage: %s [-E|-f|-m] [-V] [ " + printf("Usage: %s [-E|-f|-m] OPTIONS [ " "[ [duration]]]\n", getprogname()); - printf(" %s -r [-vV] []\n", + printf(" %s -r [-v] OPTIONS []\n\n", getprogname()); + printf(" OPTIONS:\n"); + printf(" -c - Enable interrupt coalescing (us)\n"); + printf(" -V - Enable verification\n"); + printf(" -z - Zero device stats before test\n"); exit(EX_USAGE); } @@ -103,8 +107,11 @@ main(int argc, char **argv) fflag = rflag = Eflag = mflag = false; modeflags = 0; - while ((ch = getopt(argc, argv, "EfmrvVw")) != -1) { + while ((ch = getopt(argc, argv, "c:EfmrvVwz")) != -1) { switch (ch) { + case 'c': + t.coalesce_period = atoi(optarg); + break; case 'E': Eflag = true; modeflags++; @@ -130,6 +137,9 @@ main(int argc, char **argv) case 'w': t.raw_write = true; break; + case 'z': + t.zero_stats = true; + break; default: usage(); }