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