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
This commit is contained in:
parent
eef0660a7f
commit
6a301ac85a
@ -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]++;
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user