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