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