6aad79486e10cdf19a1c6d00743a007e786a6d5a
[dpdk.git] / drivers / raw / ioat / ioat_rawdev_test.c
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_rawdev_stop(dev_id);
224         rte_mempool_free(pool);
225         free(snames);
226         free(stats);
227         free(ids);
228         return 0;
229
230 err:
231         rte_rawdev_stop(dev_id);
232         rte_mempool_free(pool);
233         free(snames);
234         free(stats);
235         free(ids);
236         return -1;
237 }