xref: /dpdk/drivers/raw/ioat/ioat_rawdev_test.c (revision a70ed388)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Intel Corporation
3  */
4 
5 #include <unistd.h>
6 #include <inttypes.h>
7 #include <rte_mbuf.h>
8 #include "rte_rawdev.h"
9 #include "rte_ioat_rawdev.h"
10 
11 int ioat_rawdev_test(uint16_t dev_id); /* pre-define to keep compiler happy */
12 
13 static struct rte_mempool *pool;
14 
15 static int
16 test_enqueue_copies(int dev_id)
17 {
18 	const unsigned int length = 1024;
19 	unsigned int i;
20 
21 	do {
22 		struct rte_mbuf *src, *dst;
23 		char *src_data, *dst_data;
24 		struct rte_mbuf *completed[2] = {0};
25 
26 		/* test doing a single copy */
27 		src = rte_pktmbuf_alloc(pool);
28 		dst = rte_pktmbuf_alloc(pool);
29 		src->data_len = src->pkt_len = length;
30 		dst->data_len = dst->pkt_len = length;
31 		src_data = rte_pktmbuf_mtod(src, char *);
32 		dst_data = rte_pktmbuf_mtod(dst, char *);
33 
34 		for (i = 0; i < length; i++)
35 			src_data[i] = rand() & 0xFF;
36 
37 		if (rte_ioat_enqueue_copy(dev_id,
38 				src->buf_iova + src->data_off,
39 				dst->buf_iova + dst->data_off,
40 				length,
41 				(uintptr_t)src,
42 				(uintptr_t)dst,
43 				0 /* no fence */) != 1) {
44 			printf("Error with rte_ioat_enqueue_copy\n");
45 			return -1;
46 		}
47 		rte_ioat_do_copies(dev_id);
48 		usleep(10);
49 
50 		if (rte_ioat_completed_copies(dev_id, 1, (void *)&completed[0],
51 				(void *)&completed[1]) != 1) {
52 			printf("Error with rte_ioat_completed_copies\n");
53 			return -1;
54 		}
55 		if (completed[0] != src || completed[1] != dst) {
56 			printf("Error with completions: got (%p, %p), not (%p,%p)\n",
57 					completed[0], completed[1], src, dst);
58 			return -1;
59 		}
60 
61 		for (i = 0; i < length; i++)
62 			if (dst_data[i] != src_data[i]) {
63 				printf("Data mismatch at char %u\n", i);
64 				return -1;
65 			}
66 		rte_pktmbuf_free(src);
67 		rte_pktmbuf_free(dst);
68 	} while (0);
69 
70 	/* test doing multiple copies */
71 	do {
72 		struct rte_mbuf *srcs[32], *dsts[32];
73 		struct rte_mbuf *completed_src[64];
74 		struct rte_mbuf *completed_dst[64];
75 		unsigned int j;
76 
77 		for (i = 0; i < RTE_DIM(srcs); i++) {
78 			char *src_data;
79 
80 			srcs[i] = rte_pktmbuf_alloc(pool);
81 			dsts[i] = rte_pktmbuf_alloc(pool);
82 			srcs[i]->data_len = srcs[i]->pkt_len = length;
83 			dsts[i]->data_len = dsts[i]->pkt_len = length;
84 			src_data = rte_pktmbuf_mtod(srcs[i], char *);
85 
86 			for (j = 0; j < length; j++)
87 				src_data[j] = rand() & 0xFF;
88 
89 			if (rte_ioat_enqueue_copy(dev_id,
90 					srcs[i]->buf_iova + srcs[i]->data_off,
91 					dsts[i]->buf_iova + dsts[i]->data_off,
92 					length,
93 					(uintptr_t)srcs[i],
94 					(uintptr_t)dsts[i],
95 					0 /* nofence */) != 1) {
96 				printf("Error with rte_ioat_enqueue_copy for buffer %u\n",
97 						i);
98 				return -1;
99 			}
100 		}
101 		rte_ioat_do_copies(dev_id);
102 		usleep(100);
103 
104 		if (rte_ioat_completed_copies(dev_id, 64, (void *)completed_src,
105 				(void *)completed_dst) != RTE_DIM(srcs)) {
106 			printf("Error with rte_ioat_completed_copies\n");
107 			return -1;
108 		}
109 		for (i = 0; i < RTE_DIM(srcs); i++) {
110 			char *src_data, *dst_data;
111 
112 			if (completed_src[i] != srcs[i]) {
113 				printf("Error with source pointer %u\n", i);
114 				return -1;
115 			}
116 			if (completed_dst[i] != dsts[i]) {
117 				printf("Error with dest pointer %u\n", i);
118 				return -1;
119 			}
120 
121 			src_data = rte_pktmbuf_mtod(srcs[i], char *);
122 			dst_data = rte_pktmbuf_mtod(dsts[i], char *);
123 			for (j = 0; j < length; j++)
124 				if (src_data[j] != dst_data[j]) {
125 					printf("Error with copy of packet %u, byte %u\n",
126 							i, j);
127 					return -1;
128 				}
129 			rte_pktmbuf_free(srcs[i]);
130 			rte_pktmbuf_free(dsts[i]);
131 		}
132 
133 	} while (0);
134 
135 	return 0;
136 }
137 
138 int
139 ioat_rawdev_test(uint16_t dev_id)
140 {
141 #define IOAT_TEST_RINGSIZE 512
142 	struct rte_ioat_rawdev_config p = { .ring_size = -1 };
143 	struct rte_rawdev_info info = { .dev_private = &p };
144 	struct rte_rawdev_xstats_name *snames = NULL;
145 	uint64_t *stats = NULL;
146 	unsigned int *ids = NULL;
147 	unsigned int nb_xstats;
148 	unsigned int i;
149 
150 	rte_rawdev_info_get(dev_id, &info);
151 	if (p.ring_size != 0) {
152 		printf("Error, initial ring size is non-zero (%d)\n",
153 				(int)p.ring_size);
154 		return -1;
155 	}
156 
157 	p.ring_size = IOAT_TEST_RINGSIZE;
158 	if (rte_rawdev_configure(dev_id, &info) != 0) {
159 		printf("Error with rte_rawdev_configure()\n");
160 		return -1;
161 	}
162 	rte_rawdev_info_get(dev_id, &info);
163 	if (p.ring_size != IOAT_TEST_RINGSIZE) {
164 		printf("Error, ring size is not %d (%d)\n",
165 				IOAT_TEST_RINGSIZE, (int)p.ring_size);
166 		return -1;
167 	}
168 
169 	if (rte_rawdev_start(dev_id) != 0) {
170 		printf("Error with rte_rawdev_start()\n");
171 		return -1;
172 	}
173 
174 	pool = rte_pktmbuf_pool_create("TEST_IOAT_POOL",
175 			256, /* n == num elements */
176 			32,  /* cache size */
177 			0,   /* priv size */
178 			2048, /* data room size */
179 			info.socket_id);
180 	if (pool == NULL) {
181 		printf("Error with mempool creation\n");
182 		return -1;
183 	}
184 
185 	/* allocate memory for xstats names and values */
186 	nb_xstats = rte_rawdev_xstats_names_get(dev_id, NULL, 0);
187 
188 	snames = malloc(sizeof(*snames) * nb_xstats);
189 	if (snames == NULL) {
190 		printf("Error allocating xstat names memory\n");
191 		goto err;
192 	}
193 	rte_rawdev_xstats_names_get(dev_id, snames, nb_xstats);
194 
195 	ids = malloc(sizeof(*ids) * nb_xstats);
196 	if (ids == NULL) {
197 		printf("Error allocating xstat ids memory\n");
198 		goto err;
199 	}
200 	for (i = 0; i < nb_xstats; i++)
201 		ids[i] = i;
202 
203 	stats = malloc(sizeof(*stats) * nb_xstats);
204 	if (stats == NULL) {
205 		printf("Error allocating xstat memory\n");
206 		goto err;
207 	}
208 
209 	/* run the test cases */
210 	for (i = 0; i < 100; i++) {
211 		unsigned int j;
212 
213 		if (test_enqueue_copies(dev_id) != 0)
214 			goto err;
215 
216 		rte_rawdev_xstats_get(dev_id, ids, stats, nb_xstats);
217 		for (j = 0; j < nb_xstats; j++)
218 			printf("%s: %"PRIu64"   ", snames[j].name, stats[j]);
219 		printf("\r");
220 	}
221 	printf("\n");
222 
223 	rte_mempool_free(pool);
224 	free(snames);
225 	free(stats);
226 	free(ids);
227 	return 0;
228 
229 err:
230 	rte_mempool_free(pool);
231 	free(snames);
232 	free(stats);
233 	free(ids);
234 	return -1;
235 }
236