1 // SPDX-License-Identifier: GPL-2.0 2 #include <bpf/bpf.h> 3 #include <errno.h> 4 #include <linux/bitmap.h> 5 #include <linux/if_link.h> 6 #include <linux/mman.h> 7 #include <linux/netdev.h> 8 #include <poll.h> 9 #include <pthread.h> 10 #include <string.h> 11 #include <sys/mman.h> 12 #include <sys/socket.h> 13 #include <sys/time.h> 14 #include <unistd.h> 15 16 #include "network_helpers.h" 17 #include "test_xsk.h" 18 #include "xsk_xdp_common.h" 19 #include "xsk_xdp_progs.skel.h" 20 21 #define DEFAULT_BATCH_SIZE 64 22 #define MIN_PKT_SIZE 64 23 #define MAX_ETH_JUMBO_SIZE 9000 24 #define MAX_INTERFACES 2 25 #define MAX_TEARDOWN_ITER 10 26 #define MAX_TX_BUDGET_DEFAULT 32 27 #define PKT_DUMP_NB_TO_PRINT 16 28 /* Just to align the data in the packet */ 29 #define PKT_HDR_SIZE (sizeof(struct ethhdr) + 2) 30 #define POLL_TMOUT 1000 31 #define THREAD_TMOUT 3 32 #define UMEM_HEADROOM_TEST_SIZE 128 33 #define XSK_DESC__INVALID_OPTION (0xffff) 34 #define XSK_UMEM__INVALID_FRAME_SIZE (MAX_ETH_JUMBO_SIZE + 1) 35 #define XSK_UMEM__LARGE_FRAME_SIZE (3 * 1024) 36 #define XSK_UMEM__MAX_FRAME_SIZE (4 * 1024) 37 38 static const u8 g_mac[ETH_ALEN] = {0x55, 0x44, 0x33, 0x22, 0x11, 0x00}; 39 40 bool opt_verbose; 41 pthread_barrier_t barr; 42 pthread_mutex_t pacing_mutex = PTHREAD_MUTEX_INITIALIZER; 43 44 int pkts_in_flight; 45 46 /* The payload is a word consisting of a packet sequence number in the upper 47 * 16-bits and a intra packet data sequence number in the lower 16 bits. So the 3rd packet's 48 * 5th word of data will contain the number (2<<16) | 4 as they are numbered from 0. 49 */ 50 static void write_payload(void *dest, u32 pkt_nb, u32 start, u32 size) 51 { 52 u32 *ptr = (u32 *)dest, i; 53 54 start /= sizeof(*ptr); 55 size /= sizeof(*ptr); 56 for (i = 0; i < size; i++) 57 ptr[i] = htonl(pkt_nb << 16 | (i + start)); 58 } 59 60 static void gen_eth_hdr(struct xsk_socket_info *xsk, struct ethhdr *eth_hdr) 61 { 62 memcpy(eth_hdr->h_dest, xsk->dst_mac, ETH_ALEN); 63 memcpy(eth_hdr->h_source, xsk->src_mac, ETH_ALEN); 64 eth_hdr->h_proto = htons(ETH_P_LOOPBACK); 65 } 66 67 static u32 mode_to_xdp_flags(enum test_mode mode) 68 { 69 return (mode == TEST_MODE_SKB) ? XDP_FLAGS_SKB_MODE : XDP_FLAGS_DRV_MODE; 70 } 71 72 static u64 umem_size(struct xsk_umem_info *umem) 73 { 74 return umem->num_frames * umem->frame_size; 75 } 76 77 int xsk_configure_umem(struct ifobject *ifobj, struct xsk_umem_info *umem, void *buffer, 78 u64 size) 79 { 80 struct xsk_umem_config cfg = { 81 .fill_size = XSK_RING_PROD__DEFAULT_NUM_DESCS, 82 .comp_size = XSK_RING_CONS__DEFAULT_NUM_DESCS, 83 .frame_size = umem->frame_size, 84 .frame_headroom = umem->frame_headroom, 85 .flags = XSK_UMEM__DEFAULT_FLAGS 86 }; 87 int ret; 88 89 if (umem->fill_size) 90 cfg.fill_size = umem->fill_size; 91 92 if (umem->comp_size) 93 cfg.comp_size = umem->comp_size; 94 95 if (umem->unaligned_mode) 96 cfg.flags |= XDP_UMEM_UNALIGNED_CHUNK_FLAG; 97 98 ret = xsk_umem__create(&umem->umem, buffer, size, 99 &umem->fq, &umem->cq, &cfg); 100 if (ret) 101 return ret; 102 103 umem->buffer = buffer; 104 if (ifobj->shared_umem && ifobj->rx_on) { 105 umem->base_addr = umem_size(umem); 106 umem->next_buffer = umem_size(umem); 107 } 108 109 return 0; 110 } 111 112 static u64 umem_alloc_buffer(struct xsk_umem_info *umem) 113 { 114 u64 addr; 115 116 addr = umem->next_buffer; 117 umem->next_buffer += umem->frame_size; 118 if (umem->next_buffer >= umem->base_addr + umem_size(umem)) 119 umem->next_buffer = umem->base_addr; 120 121 return addr; 122 } 123 124 static void umem_reset_alloc(struct xsk_umem_info *umem) 125 { 126 umem->next_buffer = 0; 127 } 128 129 static int enable_busy_poll(struct xsk_socket_info *xsk) 130 { 131 int sock_opt; 132 133 sock_opt = 1; 134 if (setsockopt(xsk_socket__fd(xsk->xsk), SOL_SOCKET, SO_PREFER_BUSY_POLL, 135 (void *)&sock_opt, sizeof(sock_opt)) < 0) 136 return -errno; 137 138 sock_opt = 20; 139 if (setsockopt(xsk_socket__fd(xsk->xsk), SOL_SOCKET, SO_BUSY_POLL, 140 (void *)&sock_opt, sizeof(sock_opt)) < 0) 141 return -errno; 142 143 sock_opt = xsk->batch_size; 144 if (setsockopt(xsk_socket__fd(xsk->xsk), SOL_SOCKET, SO_BUSY_POLL_BUDGET, 145 (void *)&sock_opt, sizeof(sock_opt)) < 0) 146 return -errno; 147 148 return 0; 149 } 150 151 int xsk_configure_socket(struct xsk_socket_info *xsk, struct xsk_umem_info *umem, 152 struct ifobject *ifobject, bool shared) 153 { 154 struct xsk_socket_config cfg = {}; 155 struct xsk_ring_cons *rxr; 156 struct xsk_ring_prod *txr; 157 158 xsk->umem = umem; 159 cfg.rx_size = xsk->rxqsize; 160 cfg.tx_size = XSK_RING_PROD__DEFAULT_NUM_DESCS; 161 cfg.bind_flags = ifobject->bind_flags; 162 if (shared) 163 cfg.bind_flags |= XDP_SHARED_UMEM; 164 if (ifobject->mtu > MAX_ETH_PKT_SIZE) 165 cfg.bind_flags |= XDP_USE_SG; 166 if (umem->comp_size) 167 cfg.tx_size = umem->comp_size; 168 if (umem->fill_size) 169 cfg.rx_size = umem->fill_size; 170 171 txr = ifobject->tx_on ? &xsk->tx : NULL; 172 rxr = ifobject->rx_on ? &xsk->rx : NULL; 173 return xsk_socket__create(&xsk->xsk, ifobject->ifindex, 0, umem->umem, rxr, txr, &cfg); 174 } 175 176 static int set_ring_size(struct ifobject *ifobj) 177 { 178 int ret; 179 u32 ctr = 0; 180 181 while (ctr++ < SOCK_RECONF_CTR) { 182 ret = set_hw_ring_size(ifobj->ifname, &ifobj->ring); 183 if (!ret) 184 break; 185 186 /* Retry if it fails */ 187 if (ctr >= SOCK_RECONF_CTR || errno != EBUSY) 188 return -errno; 189 190 usleep(USLEEP_MAX); 191 } 192 193 return ret; 194 } 195 196 int hw_ring_size_reset(struct ifobject *ifobj) 197 { 198 ifobj->ring.tx_pending = ifobj->set_ring.default_tx; 199 ifobj->ring.rx_pending = ifobj->set_ring.default_rx; 200 return set_ring_size(ifobj); 201 } 202 203 static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx, 204 struct ifobject *ifobj_rx) 205 { 206 u32 i, j; 207 208 for (i = 0; i < MAX_INTERFACES; i++) { 209 struct ifobject *ifobj = i ? ifobj_rx : ifobj_tx; 210 struct xsk_umem_info *umem_real; 211 212 ifobj->xsk = &ifobj->xsk_arr[0]; 213 ifobj->use_poll = false; 214 ifobj->use_fill_ring = true; 215 ifobj->release_rx = true; 216 ifobj->validation_func = NULL; 217 ifobj->use_metadata = false; 218 219 if (i == 0) { 220 ifobj->rx_on = false; 221 ifobj->tx_on = true; 222 } else { 223 ifobj->rx_on = true; 224 ifobj->tx_on = false; 225 } 226 227 umem_real = ifobj->xsk_arr[0].umem_real; 228 memset(umem_real, 0, sizeof(*umem_real)); 229 for (j = 0; j < MAX_SOCKETS; j++) { 230 struct xsk_socket_info *xsk = &ifobj->xsk_arr[j]; 231 232 memset(xsk, 0, sizeof(*xsk)); 233 xsk->rxqsize = XSK_RING_CONS__DEFAULT_NUM_DESCS; 234 if (j == 0) 235 xsk->umem_real = umem_real; 236 xsk->umem = umem_real; 237 xsk->batch_size = DEFAULT_BATCH_SIZE; 238 if (i == 0) 239 xsk->pkt_stream = test->tx_pkt_stream_default; 240 else 241 xsk->pkt_stream = test->rx_pkt_stream_default; 242 243 memcpy(xsk->src_mac, g_mac, ETH_ALEN); 244 memcpy(xsk->dst_mac, g_mac, ETH_ALEN); 245 xsk->src_mac[5] += ((j * 2) + 0); 246 xsk->dst_mac[5] += ((j * 2) + 1); 247 } 248 249 ifobj->xsk->umem->num_frames = DEFAULT_UMEM_BUFFERS; 250 ifobj->xsk->umem->frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE; 251 } 252 253 if (ifobj_tx->hw_ring_size_supp) 254 hw_ring_size_reset(ifobj_tx); 255 256 test->ifobj_tx = ifobj_tx; 257 test->ifobj_rx = ifobj_rx; 258 test->current_step = 0; 259 test->total_steps = 1; 260 test->nb_sockets = 1; 261 test->fail = false; 262 test->set_ring = false; 263 test->adjust_tail = false; 264 test->adjust_tail_support = false; 265 test->mtu = MAX_ETH_PKT_SIZE; 266 test->xdp_prog_rx = ifobj_rx->xdp_progs->progs.xsk_def_prog; 267 test->xskmap_rx = ifobj_rx->xdp_progs->maps.xsk; 268 test->xdp_prog_tx = ifobj_tx->xdp_progs->progs.xsk_def_prog; 269 test->xskmap_tx = ifobj_tx->xdp_progs->maps.xsk; 270 } 271 272 void test_init(struct test_spec *test, struct ifobject *ifobj_tx, 273 struct ifobject *ifobj_rx, enum test_mode mode, 274 const struct test_spec *test_to_run) 275 { 276 struct pkt_stream *tx_pkt_stream; 277 struct pkt_stream *rx_pkt_stream; 278 u32 i; 279 280 tx_pkt_stream = test->tx_pkt_stream_default; 281 rx_pkt_stream = test->rx_pkt_stream_default; 282 memset(test, 0, sizeof(*test)); 283 test->tx_pkt_stream_default = tx_pkt_stream; 284 test->rx_pkt_stream_default = rx_pkt_stream; 285 286 for (i = 0; i < MAX_INTERFACES; i++) { 287 struct ifobject *ifobj = i ? ifobj_rx : ifobj_tx; 288 289 ifobj->bind_flags = XDP_USE_NEED_WAKEUP; 290 if (mode == TEST_MODE_ZC) 291 ifobj->bind_flags |= XDP_ZEROCOPY; 292 else 293 ifobj->bind_flags |= XDP_COPY; 294 } 295 296 memcpy(test->name, test_to_run->name, MAX_TEST_NAME_SIZE); 297 test->test_func = test_to_run->test_func; 298 test->mode = mode; 299 __test_spec_init(test, ifobj_tx, ifobj_rx); 300 } 301 302 static void test_spec_reset(struct test_spec *test) 303 { 304 __test_spec_init(test, test->ifobj_tx, test->ifobj_rx); 305 } 306 307 static void test_spec_set_unaligned(struct test_spec *test) 308 { 309 test->ifobj_tx->xsk->umem->unaligned_mode = true; 310 test->ifobj_rx->xsk->umem->unaligned_mode = true; 311 } 312 313 static void test_spec_set_frame_size(struct test_spec *test, u32 size) 314 { 315 test->ifobj_tx->xsk->umem->frame_size = size; 316 test->ifobj_rx->xsk->umem->frame_size = size; 317 } 318 319 static void test_spec_set_xdp_prog(struct test_spec *test, struct bpf_program *xdp_prog_rx, 320 struct bpf_program *xdp_prog_tx, struct bpf_map *xskmap_rx, 321 struct bpf_map *xskmap_tx) 322 { 323 test->xdp_prog_rx = xdp_prog_rx; 324 test->xdp_prog_tx = xdp_prog_tx; 325 test->xskmap_rx = xskmap_rx; 326 test->xskmap_tx = xskmap_tx; 327 } 328 329 static int test_spec_set_mtu(struct test_spec *test, int mtu) 330 { 331 int err; 332 333 if (test->ifobj_rx->mtu != mtu) { 334 err = xsk_set_mtu(test->ifobj_rx->ifindex, mtu); 335 if (err) 336 return err; 337 test->ifobj_rx->mtu = mtu; 338 } 339 if (test->ifobj_tx->mtu != mtu) { 340 err = xsk_set_mtu(test->ifobj_tx->ifindex, mtu); 341 if (err) 342 return err; 343 test->ifobj_tx->mtu = mtu; 344 } 345 346 return 0; 347 } 348 349 void pkt_stream_reset(struct pkt_stream *pkt_stream) 350 { 351 if (pkt_stream) { 352 pkt_stream->current_pkt_nb = 0; 353 pkt_stream->nb_rx_pkts = 0; 354 } 355 } 356 357 static struct pkt *pkt_stream_get_next_tx_pkt(struct pkt_stream *pkt_stream) 358 { 359 if (pkt_stream->current_pkt_nb >= pkt_stream->nb_pkts) 360 return NULL; 361 362 return &pkt_stream->pkts[pkt_stream->current_pkt_nb++]; 363 } 364 365 static struct pkt *pkt_stream_get_next_rx_pkt(struct pkt_stream *pkt_stream, u32 *pkts_sent) 366 { 367 while (pkt_stream->current_pkt_nb < pkt_stream->nb_pkts) { 368 (*pkts_sent)++; 369 if (pkt_stream->pkts[pkt_stream->current_pkt_nb].valid) 370 return &pkt_stream->pkts[pkt_stream->current_pkt_nb++]; 371 pkt_stream->current_pkt_nb++; 372 } 373 return NULL; 374 } 375 376 void pkt_stream_delete(struct pkt_stream *pkt_stream) 377 { 378 free(pkt_stream->pkts); 379 free(pkt_stream); 380 } 381 382 void pkt_stream_restore_default(struct test_spec *test) 383 { 384 struct pkt_stream *tx_pkt_stream = test->ifobj_tx->xsk->pkt_stream; 385 struct pkt_stream *rx_pkt_stream = test->ifobj_rx->xsk->pkt_stream; 386 387 if (tx_pkt_stream != test->tx_pkt_stream_default) { 388 pkt_stream_delete(test->ifobj_tx->xsk->pkt_stream); 389 test->ifobj_tx->xsk->pkt_stream = test->tx_pkt_stream_default; 390 } 391 392 if (rx_pkt_stream != test->rx_pkt_stream_default) { 393 pkt_stream_delete(test->ifobj_rx->xsk->pkt_stream); 394 test->ifobj_rx->xsk->pkt_stream = test->rx_pkt_stream_default; 395 } 396 } 397 398 static struct pkt_stream *__pkt_stream_alloc(u32 nb_pkts) 399 { 400 struct pkt_stream *pkt_stream; 401 402 pkt_stream = calloc(1, sizeof(*pkt_stream)); 403 if (!pkt_stream) 404 return NULL; 405 406 pkt_stream->pkts = calloc(nb_pkts, sizeof(*pkt_stream->pkts)); 407 if (!pkt_stream->pkts) { 408 free(pkt_stream); 409 return NULL; 410 } 411 412 pkt_stream->nb_pkts = nb_pkts; 413 return pkt_stream; 414 } 415 416 static u32 pkt_nb_frags(u32 frame_size, struct pkt_stream *pkt_stream, struct pkt *pkt) 417 { 418 u32 nb_frags = 1, next_frag; 419 420 if (!pkt) 421 return 1; 422 423 if (!pkt_stream->verbatim) { 424 if (!pkt->valid || !pkt->len) 425 return 1; 426 return ceil_u32(pkt->len, frame_size); 427 } 428 429 /* Search for the end of the packet in verbatim mode */ 430 if (!pkt_continues(pkt->options)) 431 return nb_frags; 432 433 next_frag = pkt_stream->current_pkt_nb; 434 pkt++; 435 while (next_frag++ < pkt_stream->nb_pkts) { 436 nb_frags++; 437 if (!pkt_continues(pkt->options)) 438 break; 439 pkt++; 440 } 441 return nb_frags; 442 } 443 444 static bool set_pkt_valid(int offset, u32 len) 445 { 446 return len <= MAX_ETH_JUMBO_SIZE; 447 } 448 449 static void pkt_set(struct pkt_stream *pkt_stream, struct pkt *pkt, int offset, u32 len) 450 { 451 pkt->offset = offset; 452 pkt->len = len; 453 pkt->valid = set_pkt_valid(offset, len); 454 } 455 456 static void pkt_stream_pkt_set(struct pkt_stream *pkt_stream, struct pkt *pkt, int offset, u32 len) 457 { 458 bool prev_pkt_valid = pkt->valid; 459 460 pkt_set(pkt_stream, pkt, offset, len); 461 pkt_stream->nb_valid_entries += pkt->valid - prev_pkt_valid; 462 } 463 464 static u32 pkt_get_buffer_len(struct xsk_umem_info *umem, u32 len) 465 { 466 return ceil_u32(len, umem->frame_size) * umem->frame_size; 467 } 468 469 static struct pkt_stream *__pkt_stream_generate(u32 nb_pkts, u32 pkt_len, u32 nb_start, u32 nb_off) 470 { 471 struct pkt_stream *pkt_stream; 472 u32 i; 473 474 pkt_stream = __pkt_stream_alloc(nb_pkts); 475 if (!pkt_stream) 476 return NULL; 477 478 pkt_stream->nb_pkts = nb_pkts; 479 pkt_stream->max_pkt_len = pkt_len; 480 for (i = 0; i < nb_pkts; i++) { 481 struct pkt *pkt = &pkt_stream->pkts[i]; 482 483 pkt_stream_pkt_set(pkt_stream, pkt, 0, pkt_len); 484 pkt->pkt_nb = nb_start + i * nb_off; 485 } 486 487 return pkt_stream; 488 } 489 490 struct pkt_stream *pkt_stream_generate(u32 nb_pkts, u32 pkt_len) 491 { 492 return __pkt_stream_generate(nb_pkts, pkt_len, 0, 1); 493 } 494 495 static struct pkt_stream *pkt_stream_clone(struct pkt_stream *pkt_stream) 496 { 497 return pkt_stream_generate(pkt_stream->nb_pkts, pkt_stream->pkts[0].len); 498 } 499 500 static int pkt_stream_replace_ifobject(struct ifobject *ifobj, u32 nb_pkts, u32 pkt_len) 501 { 502 ifobj->xsk->pkt_stream = pkt_stream_generate(nb_pkts, pkt_len); 503 504 if (!ifobj->xsk->pkt_stream) 505 return -ENOMEM; 506 507 return 0; 508 } 509 510 static int pkt_stream_replace(struct test_spec *test, u32 nb_pkts, u32 pkt_len) 511 { 512 int ret; 513 514 ret = pkt_stream_replace_ifobject(test->ifobj_tx, nb_pkts, pkt_len); 515 if (ret) 516 return ret; 517 518 return pkt_stream_replace_ifobject(test->ifobj_rx, nb_pkts, pkt_len); 519 } 520 521 static int __pkt_stream_replace_half(struct ifobject *ifobj, u32 pkt_len, 522 int offset) 523 { 524 struct pkt_stream *pkt_stream; 525 u32 i; 526 527 pkt_stream = pkt_stream_clone(ifobj->xsk->pkt_stream); 528 if (!pkt_stream) 529 return -ENOMEM; 530 531 for (i = 1; i < ifobj->xsk->pkt_stream->nb_pkts; i += 2) 532 pkt_stream_pkt_set(pkt_stream, &pkt_stream->pkts[i], offset, pkt_len); 533 534 ifobj->xsk->pkt_stream = pkt_stream; 535 536 return 0; 537 } 538 539 static int pkt_stream_replace_half(struct test_spec *test, u32 pkt_len, int offset) 540 { 541 int ret = __pkt_stream_replace_half(test->ifobj_tx, pkt_len, offset); 542 543 if (ret) 544 return ret; 545 546 return __pkt_stream_replace_half(test->ifobj_rx, pkt_len, offset); 547 } 548 549 static int pkt_stream_receive_half(struct test_spec *test) 550 { 551 struct pkt_stream *pkt_stream = test->ifobj_tx->xsk->pkt_stream; 552 u32 i; 553 554 if (test->ifobj_rx->xsk->pkt_stream != test->rx_pkt_stream_default) 555 /* Packet stream has already been replaced so we have to release this one. 556 * The newly created one will be freed by the restore_default() at the 557 * end of the test 558 */ 559 pkt_stream_delete(test->ifobj_rx->xsk->pkt_stream); 560 561 test->ifobj_rx->xsk->pkt_stream = pkt_stream_generate(pkt_stream->nb_pkts, 562 pkt_stream->pkts[0].len); 563 if (!test->ifobj_rx->xsk->pkt_stream) 564 return -ENOMEM; 565 566 pkt_stream = test->ifobj_rx->xsk->pkt_stream; 567 for (i = 1; i < pkt_stream->nb_pkts; i += 2) 568 pkt_stream->pkts[i].valid = false; 569 570 pkt_stream->nb_valid_entries /= 2; 571 572 return 0; 573 } 574 575 static int pkt_stream_even_odd_sequence(struct test_spec *test) 576 { 577 struct pkt_stream *pkt_stream; 578 u32 i; 579 580 for (i = 0; i < test->nb_sockets; i++) { 581 pkt_stream = test->ifobj_tx->xsk_arr[i].pkt_stream; 582 pkt_stream = __pkt_stream_generate(pkt_stream->nb_pkts / 2, 583 pkt_stream->pkts[0].len, i, 2); 584 if (!pkt_stream) 585 return -ENOMEM; 586 test->ifobj_tx->xsk_arr[i].pkt_stream = pkt_stream; 587 588 pkt_stream = test->ifobj_rx->xsk_arr[i].pkt_stream; 589 pkt_stream = __pkt_stream_generate(pkt_stream->nb_pkts / 2, 590 pkt_stream->pkts[0].len, i, 2); 591 if (!pkt_stream) 592 return -ENOMEM; 593 test->ifobj_rx->xsk_arr[i].pkt_stream = pkt_stream; 594 } 595 596 return 0; 597 } 598 599 static void release_even_odd_sequence(struct test_spec *test) 600 { 601 struct pkt_stream *later_free_tx = test->ifobj_tx->xsk->pkt_stream; 602 struct pkt_stream *later_free_rx = test->ifobj_rx->xsk->pkt_stream; 603 int i; 604 605 for (i = 0; i < test->nb_sockets; i++) { 606 /* later_free_{rx/tx} will be freed by restore_default() */ 607 if (test->ifobj_tx->xsk_arr[i].pkt_stream != later_free_tx) 608 pkt_stream_delete(test->ifobj_tx->xsk_arr[i].pkt_stream); 609 if (test->ifobj_rx->xsk_arr[i].pkt_stream != later_free_rx) 610 pkt_stream_delete(test->ifobj_rx->xsk_arr[i].pkt_stream); 611 } 612 613 } 614 615 static u64 pkt_get_addr(struct pkt *pkt, struct xsk_umem_info *umem) 616 { 617 if (!pkt->valid) 618 return pkt->offset; 619 return pkt->offset + umem_alloc_buffer(umem); 620 } 621 622 static void pkt_stream_cancel(struct pkt_stream *pkt_stream) 623 { 624 pkt_stream->current_pkt_nb--; 625 } 626 627 static void pkt_generate(struct xsk_socket_info *xsk, struct xsk_umem_info *umem, u64 addr, u32 len, 628 u32 pkt_nb, u32 bytes_written) 629 { 630 void *data = xsk_umem__get_data(umem->buffer, addr); 631 632 if (len < MIN_PKT_SIZE) 633 return; 634 635 if (!bytes_written) { 636 gen_eth_hdr(xsk, data); 637 638 len -= PKT_HDR_SIZE; 639 data += PKT_HDR_SIZE; 640 } else { 641 bytes_written -= PKT_HDR_SIZE; 642 } 643 644 write_payload(data, pkt_nb, bytes_written, len); 645 } 646 647 static struct pkt_stream *__pkt_stream_generate_custom(struct ifobject *ifobj, struct pkt *frames, 648 u32 nb_frames, bool verbatim) 649 { 650 u32 i, len = 0, pkt_nb = 0, payload = 0; 651 struct pkt_stream *pkt_stream; 652 653 pkt_stream = __pkt_stream_alloc(nb_frames); 654 if (!pkt_stream) 655 return NULL; 656 657 for (i = 0; i < nb_frames; i++) { 658 struct pkt *pkt = &pkt_stream->pkts[pkt_nb]; 659 struct pkt *frame = &frames[i]; 660 661 pkt->offset = frame->offset; 662 if (verbatim) { 663 *pkt = *frame; 664 pkt->pkt_nb = payload; 665 if (!frame->valid || !pkt_continues(frame->options)) 666 payload++; 667 } else { 668 if (frame->valid) { 669 len += frame->len; 670 if (pkt_continues(frame->options)) 671 continue; 672 } 673 pkt->pkt_nb = pkt_nb; 674 pkt->len = len; 675 pkt->valid = frame->valid; 676 pkt->options = 0; 677 678 len = 0; 679 } 680 681 print_verbose("offset: %d len: %u valid: %u options: %u pkt_nb: %u\n", 682 pkt->offset, pkt->len, pkt->valid, pkt->options, pkt->pkt_nb); 683 684 if (pkt->valid && pkt->len > pkt_stream->max_pkt_len) 685 pkt_stream->max_pkt_len = pkt->len; 686 687 if (pkt->valid) 688 pkt_stream->nb_valid_entries++; 689 690 pkt_nb++; 691 } 692 693 pkt_stream->nb_pkts = pkt_nb; 694 pkt_stream->verbatim = verbatim; 695 return pkt_stream; 696 } 697 698 static int pkt_stream_generate_custom(struct test_spec *test, struct pkt *pkts, u32 nb_pkts) 699 { 700 struct pkt_stream *pkt_stream; 701 702 pkt_stream = __pkt_stream_generate_custom(test->ifobj_tx, pkts, nb_pkts, true); 703 if (!pkt_stream) 704 return -ENOMEM; 705 test->ifobj_tx->xsk->pkt_stream = pkt_stream; 706 707 pkt_stream = __pkt_stream_generate_custom(test->ifobj_rx, pkts, nb_pkts, false); 708 if (!pkt_stream) 709 return -ENOMEM; 710 test->ifobj_rx->xsk->pkt_stream = pkt_stream; 711 712 return 0; 713 } 714 715 static void pkt_print_data(u32 *data, u32 cnt) 716 { 717 u32 i; 718 719 for (i = 0; i < cnt; i++) { 720 u32 seqnum, pkt_nb; 721 722 seqnum = ntohl(*data) & 0xffff; 723 pkt_nb = ntohl(*data) >> 16; 724 ksft_print_msg("%u:%u ", pkt_nb, seqnum); 725 data++; 726 } 727 } 728 729 static void pkt_dump(void *pkt, u32 len, bool eth_header) 730 { 731 struct ethhdr *ethhdr = pkt; 732 u32 i, *data; 733 734 if (eth_header) { 735 /*extract L2 frame */ 736 ksft_print_msg("DEBUG>> L2: dst mac: "); 737 for (i = 0; i < ETH_ALEN; i++) 738 ksft_print_msg("%02X", ethhdr->h_dest[i]); 739 740 ksft_print_msg("\nDEBUG>> L2: src mac: "); 741 for (i = 0; i < ETH_ALEN; i++) 742 ksft_print_msg("%02X", ethhdr->h_source[i]); 743 744 data = pkt + PKT_HDR_SIZE; 745 } else { 746 data = pkt; 747 } 748 749 /*extract L5 frame */ 750 ksft_print_msg("\nDEBUG>> L5: seqnum: "); 751 pkt_print_data(data, PKT_DUMP_NB_TO_PRINT); 752 ksft_print_msg("...."); 753 if (len > PKT_DUMP_NB_TO_PRINT * sizeof(u32)) { 754 ksft_print_msg("\n.... "); 755 pkt_print_data(data + len / sizeof(u32) - PKT_DUMP_NB_TO_PRINT, 756 PKT_DUMP_NB_TO_PRINT); 757 } 758 ksft_print_msg("\n---------------------------------------\n"); 759 } 760 761 static bool is_offset_correct(struct xsk_umem_info *umem, struct pkt *pkt, u64 addr) 762 { 763 u32 headroom = umem->unaligned_mode ? 0 : umem->frame_headroom; 764 u32 offset = addr % umem->frame_size, expected_offset; 765 int pkt_offset = pkt->valid ? pkt->offset : 0; 766 767 if (!umem->unaligned_mode) 768 pkt_offset = 0; 769 770 expected_offset = (pkt_offset + headroom + XDP_PACKET_HEADROOM) % umem->frame_size; 771 772 if (offset == expected_offset) 773 return true; 774 775 ksft_print_msg("[%s] expected [%u], got [%u]\n", __func__, expected_offset, offset); 776 return false; 777 } 778 779 static bool is_metadata_correct(struct pkt *pkt, void *buffer, u64 addr) 780 { 781 void *data = xsk_umem__get_data(buffer, addr); 782 struct xdp_info *meta = data - sizeof(struct xdp_info); 783 784 if (meta->count != pkt->pkt_nb) { 785 ksft_print_msg("[%s] expected meta_count [%d], got meta_count [%llu]\n", 786 __func__, pkt->pkt_nb, 787 (unsigned long long)meta->count); 788 return false; 789 } 790 791 return true; 792 } 793 794 static int is_adjust_tail_supported(struct xsk_xdp_progs *skel_rx, bool *supported) 795 { 796 struct bpf_map *data_map; 797 int adjust_value = 0; 798 int key = 0; 799 int ret; 800 801 data_map = bpf_object__find_map_by_name(skel_rx->obj, "xsk_xdp_.bss"); 802 if (!data_map || !bpf_map__is_internal(data_map)) { 803 ksft_print_msg("Error: could not find bss section of XDP program\n"); 804 return -EINVAL; 805 } 806 807 ret = bpf_map_lookup_elem(bpf_map__fd(data_map), &key, &adjust_value); 808 if (ret) { 809 ksft_print_msg("Error: bpf_map_lookup_elem failed with error %d\n", ret); 810 return ret; 811 } 812 813 /* Set the 'adjust_value' variable to -EOPNOTSUPP in the XDP program if the adjust_tail 814 * helper is not supported. Skip the adjust_tail test case in this scenario. 815 */ 816 *supported = adjust_value != -EOPNOTSUPP; 817 818 return 0; 819 } 820 821 static bool is_frag_valid(struct xsk_umem_info *umem, u64 addr, u32 len, u32 expected_pkt_nb, 822 u32 bytes_processed) 823 { 824 u32 seqnum, pkt_nb, *pkt_data, words_to_end, expected_seqnum; 825 void *data = xsk_umem__get_data(umem->buffer, addr); 826 u64 umem_sz = umem_size(umem); 827 828 addr -= umem->base_addr; 829 830 if (addr >= umem_sz || addr + len > umem_sz) { 831 ksft_print_msg("Frag invalid addr: %llx len: %u\n", 832 (unsigned long long)addr, len); 833 return false; 834 } 835 if (!umem->unaligned_mode && addr % umem->frame_size + len > umem->frame_size) { 836 ksft_print_msg("Frag crosses frame boundary addr: %llx len: %u\n", 837 (unsigned long long)addr, len); 838 return false; 839 } 840 841 pkt_data = data; 842 if (!bytes_processed) { 843 pkt_data += PKT_HDR_SIZE / sizeof(*pkt_data); 844 len -= PKT_HDR_SIZE; 845 } else { 846 bytes_processed -= PKT_HDR_SIZE; 847 } 848 849 expected_seqnum = bytes_processed / sizeof(*pkt_data); 850 seqnum = ntohl(*pkt_data) & 0xffff; 851 pkt_nb = ntohl(*pkt_data) >> 16; 852 853 if (expected_pkt_nb != pkt_nb) { 854 ksft_print_msg("[%s] expected pkt_nb [%u], got pkt_nb [%u]\n", 855 __func__, expected_pkt_nb, pkt_nb); 856 goto error; 857 } 858 if (expected_seqnum != seqnum) { 859 ksft_print_msg("[%s] expected seqnum at start [%u], got seqnum [%u]\n", 860 __func__, expected_seqnum, seqnum); 861 goto error; 862 } 863 864 words_to_end = len / sizeof(*pkt_data) - 1; 865 pkt_data += words_to_end; 866 seqnum = ntohl(*pkt_data) & 0xffff; 867 expected_seqnum += words_to_end; 868 if (expected_seqnum != seqnum) { 869 ksft_print_msg("[%s] expected seqnum at end [%u], got seqnum [%u]\n", 870 __func__, expected_seqnum, seqnum); 871 goto error; 872 } 873 874 return true; 875 876 error: 877 pkt_dump(data, len, !bytes_processed); 878 return false; 879 } 880 881 static bool is_pkt_valid(struct pkt *pkt, void *buffer, u64 addr, u32 len) 882 { 883 if (pkt->len != len) { 884 ksft_print_msg("[%s] expected packet length [%d], got length [%d]\n", 885 __func__, pkt->len, len); 886 pkt_dump(xsk_umem__get_data(buffer, addr), len, true); 887 return false; 888 } 889 890 return true; 891 } 892 893 static u32 load_value(u32 *counter) 894 { 895 return __atomic_load_n(counter, __ATOMIC_ACQUIRE); 896 } 897 898 static bool kick_tx_with_check(struct xsk_socket_info *xsk, int *ret) 899 { 900 u32 max_budget = MAX_TX_BUDGET_DEFAULT; 901 u32 cons, ready_to_send; 902 int delta; 903 904 cons = load_value(xsk->tx.consumer); 905 ready_to_send = load_value(xsk->tx.producer) - cons; 906 *ret = sendto(xsk_socket__fd(xsk->xsk), NULL, 0, MSG_DONTWAIT, NULL, 0); 907 908 delta = load_value(xsk->tx.consumer) - cons; 909 /* By default, xsk should consume exact @max_budget descs at one 910 * send in this case where hitting the max budget limit in while 911 * loop is triggered in __xsk_generic_xmit(). Please make sure that 912 * the number of descs to be sent is larger than @max_budget, or 913 * else the tx.consumer will be updated in xskq_cons_peek_desc() 914 * in time which hides the issue we try to verify. 915 */ 916 if (ready_to_send > max_budget && delta != max_budget) 917 return false; 918 919 return true; 920 } 921 922 int kick_tx(struct xsk_socket_info *xsk) 923 { 924 int ret; 925 926 if (xsk->check_consumer) { 927 if (!kick_tx_with_check(xsk, &ret)) 928 return TEST_FAILURE; 929 } else { 930 ret = sendto(xsk_socket__fd(xsk->xsk), NULL, 0, MSG_DONTWAIT, NULL, 0); 931 } 932 if (ret >= 0) 933 return TEST_PASS; 934 if (errno == ENOBUFS || errno == EAGAIN || errno == EBUSY || errno == ENETDOWN) { 935 usleep(100); 936 return TEST_PASS; 937 } 938 return TEST_FAILURE; 939 } 940 941 int kick_rx(struct xsk_socket_info *xsk) 942 { 943 int ret; 944 945 ret = recvfrom(xsk_socket__fd(xsk->xsk), NULL, 0, MSG_DONTWAIT, NULL, NULL); 946 if (ret < 0) 947 return TEST_FAILURE; 948 949 return TEST_PASS; 950 } 951 952 static int complete_pkts(struct xsk_socket_info *xsk, int batch_size) 953 { 954 unsigned int rcvd; 955 u32 idx; 956 int ret; 957 958 if (xsk_ring_prod__needs_wakeup(&xsk->tx)) { 959 ret = kick_tx(xsk); 960 if (ret) 961 return TEST_FAILURE; 962 } 963 964 rcvd = xsk_ring_cons__peek(&xsk->umem->cq, batch_size, &idx); 965 if (rcvd) { 966 if (rcvd > xsk->outstanding_tx) { 967 u64 addr = *xsk_ring_cons__comp_addr(&xsk->umem->cq, idx + rcvd - 1); 968 969 ksft_print_msg("[%s] Too many packets completed\n", __func__); 970 ksft_print_msg("Last completion address: %llx\n", 971 (unsigned long long)addr); 972 return TEST_FAILURE; 973 } 974 975 xsk_ring_cons__release(&xsk->umem->cq, rcvd); 976 xsk->outstanding_tx -= rcvd; 977 } 978 979 return TEST_PASS; 980 } 981 982 static int __receive_pkts(struct test_spec *test, struct xsk_socket_info *xsk) 983 { 984 u32 frags_processed = 0, nb_frags = 0, pkt_len = 0; 985 u32 idx_rx = 0, idx_fq = 0, rcvd, pkts_sent = 0; 986 struct pkt_stream *pkt_stream = xsk->pkt_stream; 987 struct ifobject *ifobj = test->ifobj_rx; 988 struct xsk_umem_info *umem = xsk->umem; 989 struct pollfd fds = { }; 990 struct pkt *pkt; 991 u64 first_addr = 0; 992 int ret; 993 994 fds.fd = xsk_socket__fd(xsk->xsk); 995 fds.events = POLLIN; 996 997 ret = kick_rx(xsk); 998 if (ret) 999 return TEST_FAILURE; 1000 1001 if (ifobj->use_poll) { 1002 ret = poll(&fds, 1, POLL_TMOUT); 1003 if (ret < 0) 1004 return TEST_FAILURE; 1005 1006 if (!ret) { 1007 if (test->poll_tmout) 1008 return TEST_PASS; 1009 1010 ksft_print_msg("ERROR: [%s] Poll timed out\n", __func__); 1011 return TEST_CONTINUE; 1012 } 1013 1014 if (!(fds.revents & POLLIN)) 1015 return TEST_CONTINUE; 1016 } 1017 1018 rcvd = xsk_ring_cons__peek(&xsk->rx, xsk->batch_size, &idx_rx); 1019 if (!rcvd) 1020 return TEST_CONTINUE; 1021 1022 if (ifobj->use_fill_ring) { 1023 ret = xsk_ring_prod__reserve(&umem->fq, rcvd, &idx_fq); 1024 while (ret != rcvd) { 1025 if (xsk_ring_prod__needs_wakeup(&umem->fq)) { 1026 ret = poll(&fds, 1, POLL_TMOUT); 1027 if (ret < 0) 1028 return TEST_FAILURE; 1029 } 1030 ret = xsk_ring_prod__reserve(&umem->fq, rcvd, &idx_fq); 1031 } 1032 } 1033 1034 while (frags_processed < rcvd) { 1035 const struct xdp_desc *desc = xsk_ring_cons__rx_desc(&xsk->rx, idx_rx++); 1036 u64 addr = desc->addr, orig; 1037 1038 orig = xsk_umem__extract_addr(addr); 1039 addr = xsk_umem__add_offset_to_addr(addr); 1040 1041 if (!nb_frags) { 1042 pkt = pkt_stream_get_next_rx_pkt(pkt_stream, &pkts_sent); 1043 if (!pkt) { 1044 ksft_print_msg("[%s] received too many packets addr: %lx len %u\n", 1045 __func__, addr, desc->len); 1046 return TEST_FAILURE; 1047 } 1048 } 1049 1050 print_verbose("Rx: addr: %lx len: %u options: %u pkt_nb: %u valid: %u\n", 1051 addr, desc->len, desc->options, pkt->pkt_nb, pkt->valid); 1052 1053 if (!is_frag_valid(umem, addr, desc->len, pkt->pkt_nb, pkt_len) || 1054 !is_offset_correct(umem, pkt, addr) || (ifobj->use_metadata && 1055 !is_metadata_correct(pkt, umem->buffer, addr))) 1056 return TEST_FAILURE; 1057 1058 if (!nb_frags++) 1059 first_addr = addr; 1060 frags_processed++; 1061 pkt_len += desc->len; 1062 if (ifobj->use_fill_ring) 1063 *xsk_ring_prod__fill_addr(&umem->fq, idx_fq++) = orig; 1064 1065 if (pkt_continues(desc->options)) 1066 continue; 1067 1068 /* The complete packet has been received */ 1069 if (!is_pkt_valid(pkt, umem->buffer, first_addr, pkt_len) || 1070 !is_offset_correct(umem, pkt, addr)) 1071 return TEST_FAILURE; 1072 1073 pkt_stream->nb_rx_pkts++; 1074 nb_frags = 0; 1075 pkt_len = 0; 1076 } 1077 1078 if (nb_frags) { 1079 /* In the middle of a packet. Start over from beginning of packet. */ 1080 idx_rx -= nb_frags; 1081 xsk_ring_cons__cancel(&xsk->rx, nb_frags); 1082 if (ifobj->use_fill_ring) { 1083 idx_fq -= nb_frags; 1084 xsk_ring_prod__cancel(&umem->fq, nb_frags); 1085 } 1086 frags_processed -= nb_frags; 1087 pkt_stream_cancel(pkt_stream); 1088 pkts_sent--; 1089 } 1090 1091 if (ifobj->use_fill_ring) 1092 xsk_ring_prod__submit(&umem->fq, frags_processed); 1093 if (ifobj->release_rx) 1094 xsk_ring_cons__release(&xsk->rx, frags_processed); 1095 1096 pthread_mutex_lock(&pacing_mutex); 1097 pkts_in_flight -= pkts_sent; 1098 pthread_mutex_unlock(&pacing_mutex); 1099 pkts_sent = 0; 1100 1101 return TEST_CONTINUE; 1102 } 1103 1104 bool all_packets_received(struct test_spec *test, struct xsk_socket_info *xsk, u32 sock_num, 1105 unsigned long *bitmap) 1106 { 1107 struct pkt_stream *pkt_stream = xsk->pkt_stream; 1108 1109 if (!pkt_stream) { 1110 __set_bit(sock_num, bitmap); 1111 return false; 1112 } 1113 1114 if (pkt_stream->nb_rx_pkts == pkt_stream->nb_valid_entries) { 1115 __set_bit(sock_num, bitmap); 1116 if (bitmap_full(bitmap, test->nb_sockets)) 1117 return true; 1118 } 1119 1120 return false; 1121 } 1122 1123 static int receive_pkts(struct test_spec *test) 1124 { 1125 struct timeval tv_end, tv_now, tv_timeout = {THREAD_TMOUT, 0}; 1126 DECLARE_BITMAP(bitmap, test->nb_sockets); 1127 struct xsk_socket_info *xsk; 1128 u32 sock_num = 0; 1129 int res, ret; 1130 1131 bitmap_zero(bitmap, test->nb_sockets); 1132 1133 ret = gettimeofday(&tv_now, NULL); 1134 if (ret) 1135 return TEST_FAILURE; 1136 1137 timeradd(&tv_now, &tv_timeout, &tv_end); 1138 1139 while (1) { 1140 xsk = &test->ifobj_rx->xsk_arr[sock_num]; 1141 1142 if ((all_packets_received(test, xsk, sock_num, bitmap))) 1143 break; 1144 1145 res = __receive_pkts(test, xsk); 1146 if (res != TEST_CONTINUE) 1147 return res; 1148 1149 ret = gettimeofday(&tv_now, NULL); 1150 if (ret) 1151 return TEST_FAILURE; 1152 1153 if (timercmp(&tv_now, &tv_end, >)) { 1154 ksft_print_msg("ERROR: [%s] Receive loop timed out\n", __func__); 1155 return TEST_FAILURE; 1156 } 1157 sock_num = (sock_num + 1) % test->nb_sockets; 1158 } 1159 1160 return TEST_PASS; 1161 } 1162 1163 static int __send_pkts(struct ifobject *ifobject, struct xsk_socket_info *xsk, 1164 bool test_timeout) 1165 { 1166 u32 i, idx = 0, valid_pkts = 0, valid_frags = 0, buffer_len; 1167 struct xsk_umem_info *umem = ifobject->xsk_arr[0].umem_real; 1168 struct pkt_stream *pkt_stream = xsk->pkt_stream; 1169 bool use_poll = ifobject->use_poll; 1170 struct pollfd fds = { }; 1171 int ret; 1172 1173 buffer_len = pkt_get_buffer_len(umem, pkt_stream->max_pkt_len); 1174 /* pkts_in_flight might be negative if many invalid packets are sent */ 1175 if (pkts_in_flight >= (int)((umem_size(umem) - xsk->batch_size * buffer_len) / 1176 buffer_len) && !test_timeout) { 1177 ret = kick_tx(xsk); 1178 if (ret) 1179 return TEST_FAILURE; 1180 return TEST_CONTINUE; 1181 } 1182 1183 fds.fd = xsk_socket__fd(xsk->xsk); 1184 fds.events = POLLOUT; 1185 1186 while (xsk_ring_prod__reserve(&xsk->tx, xsk->batch_size, &idx) < xsk->batch_size) { 1187 if (use_poll) { 1188 ret = poll(&fds, 1, POLL_TMOUT); 1189 if (test_timeout) { 1190 if (ret < 0) { 1191 ksft_print_msg("ERROR: [%s] Poll error %d\n", 1192 __func__, errno); 1193 return TEST_FAILURE; 1194 } 1195 if (ret == 0) 1196 return TEST_PASS; 1197 break; 1198 } 1199 if (ret <= 0) { 1200 ksft_print_msg("ERROR: [%s] Poll error %d\n", 1201 __func__, errno); 1202 return TEST_FAILURE; 1203 } 1204 } 1205 1206 complete_pkts(xsk, xsk->batch_size); 1207 } 1208 1209 for (i = 0; i < xsk->batch_size; i++) { 1210 struct pkt *pkt = pkt_stream_get_next_tx_pkt(pkt_stream); 1211 u32 nb_frags_left, nb_frags, bytes_written = 0; 1212 1213 if (!pkt) 1214 break; 1215 1216 nb_frags = pkt_nb_frags(umem->frame_size, pkt_stream, pkt); 1217 if (nb_frags > xsk->batch_size - i) { 1218 pkt_stream_cancel(pkt_stream); 1219 xsk_ring_prod__cancel(&xsk->tx, xsk->batch_size - i); 1220 break; 1221 } 1222 nb_frags_left = nb_frags; 1223 1224 while (nb_frags_left--) { 1225 struct xdp_desc *tx_desc = xsk_ring_prod__tx_desc(&xsk->tx, idx + i); 1226 1227 tx_desc->addr = pkt_get_addr(pkt, umem); 1228 if (pkt_stream->verbatim) { 1229 tx_desc->len = pkt->len; 1230 tx_desc->options = pkt->options; 1231 } else if (nb_frags_left) { 1232 tx_desc->len = umem->frame_size; 1233 tx_desc->options = XDP_PKT_CONTD; 1234 } else { 1235 tx_desc->len = pkt->len - bytes_written; 1236 tx_desc->options = 0; 1237 } 1238 if (pkt->valid) 1239 pkt_generate(xsk, umem, tx_desc->addr, tx_desc->len, pkt->pkt_nb, 1240 bytes_written); 1241 bytes_written += tx_desc->len; 1242 1243 print_verbose("Tx addr: %llx len: %u options: %u pkt_nb: %u\n", 1244 tx_desc->addr, tx_desc->len, tx_desc->options, pkt->pkt_nb); 1245 1246 if (nb_frags_left) { 1247 i++; 1248 if (pkt_stream->verbatim) 1249 pkt = pkt_stream_get_next_tx_pkt(pkt_stream); 1250 } 1251 } 1252 1253 if (pkt && pkt->valid) 1254 valid_pkts++; 1255 valid_frags += nb_frags; 1256 } 1257 1258 pthread_mutex_lock(&pacing_mutex); 1259 pkts_in_flight += valid_pkts; 1260 pthread_mutex_unlock(&pacing_mutex); 1261 1262 xsk_ring_prod__submit(&xsk->tx, i); 1263 xsk->outstanding_tx += valid_frags; 1264 1265 if (use_poll) { 1266 ret = poll(&fds, 1, POLL_TMOUT); 1267 if (ret <= 0) { 1268 if (ret == 0 && test_timeout) 1269 return TEST_PASS; 1270 1271 ksft_print_msg("ERROR: [%s] Poll error %d\n", __func__, ret); 1272 return TEST_FAILURE; 1273 } 1274 } 1275 1276 if (!test_timeout) { 1277 if (complete_pkts(xsk, i)) 1278 return TEST_FAILURE; 1279 1280 usleep(10); 1281 } 1282 1283 /* Loop completion is driven by send_pkts() stream progress checks. */ 1284 return TEST_CONTINUE; 1285 } 1286 1287 static int wait_for_tx_completion(struct xsk_socket_info *xsk) 1288 { 1289 struct timeval tv_end, tv_now, tv_timeout = {THREAD_TMOUT, 0}; 1290 int ret; 1291 1292 ret = gettimeofday(&tv_now, NULL); 1293 if (ret) 1294 return TEST_FAILURE; 1295 timeradd(&tv_now, &tv_timeout, &tv_end); 1296 1297 while (xsk->outstanding_tx) { 1298 ret = gettimeofday(&tv_now, NULL); 1299 if (ret) 1300 return TEST_FAILURE; 1301 if (timercmp(&tv_now, &tv_end, >)) { 1302 ksft_print_msg("ERROR: [%s] Transmission loop timed out\n", __func__); 1303 return TEST_FAILURE; 1304 } 1305 1306 complete_pkts(xsk, xsk->batch_size); 1307 } 1308 1309 return TEST_PASS; 1310 } 1311 1312 bool all_packets_sent(struct test_spec *test, unsigned long *bitmap) 1313 { 1314 return bitmap_full(bitmap, test->nb_sockets); 1315 } 1316 1317 static int send_pkts(struct test_spec *test, struct ifobject *ifobject) 1318 { 1319 DECLARE_BITMAP(bitmap, test->nb_sockets); 1320 u32 i, ret; 1321 1322 bitmap_zero(bitmap, test->nb_sockets); 1323 1324 while (!(all_packets_sent(test, bitmap))) { 1325 for (i = 0; i < test->nb_sockets; i++) { 1326 struct pkt_stream *pkt_stream; 1327 1328 pkt_stream = ifobject->xsk_arr[i].pkt_stream; 1329 if (!pkt_stream || pkt_stream->current_pkt_nb >= pkt_stream->nb_pkts) { 1330 __set_bit(i, bitmap); 1331 continue; 1332 } 1333 ret = __send_pkts(ifobject, &ifobject->xsk_arr[i], test->poll_tmout); 1334 if (ret != TEST_CONTINUE) 1335 return ret; 1336 1337 if (test->fail) 1338 return TEST_FAILURE; 1339 1340 if (!test->poll_tmout) { 1341 ret = wait_for_tx_completion(&ifobject->xsk_arr[i]); 1342 if (ret) 1343 return TEST_FAILURE; 1344 } 1345 } 1346 } 1347 1348 return TEST_PASS; 1349 } 1350 1351 static int get_xsk_stats(struct xsk_socket *xsk, struct xdp_statistics *stats) 1352 { 1353 int fd = xsk_socket__fd(xsk), err; 1354 socklen_t optlen, expected_len; 1355 1356 optlen = sizeof(*stats); 1357 err = getsockopt(fd, SOL_XDP, XDP_STATISTICS, stats, &optlen); 1358 if (err) { 1359 ksft_print_msg("[%s] getsockopt(XDP_STATISTICS) error %u %s\n", 1360 __func__, -err, strerror(-err)); 1361 return TEST_FAILURE; 1362 } 1363 1364 expected_len = sizeof(struct xdp_statistics); 1365 if (optlen != expected_len) { 1366 ksft_print_msg("[%s] getsockopt optlen error. Expected: %u got: %u\n", 1367 __func__, expected_len, optlen); 1368 return TEST_FAILURE; 1369 } 1370 1371 return TEST_PASS; 1372 } 1373 1374 static int validate_rx_dropped(struct ifobject *ifobject) 1375 { 1376 struct xsk_socket *xsk = ifobject->xsk->xsk; 1377 struct xdp_statistics stats; 1378 int err; 1379 1380 err = kick_rx(ifobject->xsk); 1381 if (err) 1382 return TEST_FAILURE; 1383 1384 err = get_xsk_stats(xsk, &stats); 1385 if (err) 1386 return TEST_FAILURE; 1387 1388 /* The receiver calls getsockopt after receiving the last (valid) 1389 * packet which is not the final packet sent in this test (valid and 1390 * invalid packets are sent in alternating fashion with the final 1391 * packet being invalid). Since the last packet may or may not have 1392 * been dropped already, both outcomes must be allowed. 1393 */ 1394 if (stats.rx_dropped == ifobject->xsk->pkt_stream->nb_pkts / 2 || 1395 stats.rx_dropped == ifobject->xsk->pkt_stream->nb_pkts / 2 - 1) 1396 return TEST_PASS; 1397 1398 return TEST_FAILURE; 1399 } 1400 1401 static int validate_rx_full(struct ifobject *ifobject) 1402 { 1403 struct xsk_socket *xsk = ifobject->xsk->xsk; 1404 struct xdp_statistics stats; 1405 int err; 1406 1407 usleep(1000); 1408 err = kick_rx(ifobject->xsk); 1409 if (err) 1410 return TEST_FAILURE; 1411 1412 err = get_xsk_stats(xsk, &stats); 1413 if (err) 1414 return TEST_FAILURE; 1415 1416 if (stats.rx_ring_full) 1417 return TEST_PASS; 1418 1419 return TEST_FAILURE; 1420 } 1421 1422 static int validate_fill_empty(struct ifobject *ifobject) 1423 { 1424 struct xsk_socket *xsk = ifobject->xsk->xsk; 1425 struct xdp_statistics stats; 1426 int err; 1427 1428 usleep(1000); 1429 err = kick_rx(ifobject->xsk); 1430 if (err) 1431 return TEST_FAILURE; 1432 1433 err = get_xsk_stats(xsk, &stats); 1434 if (err) 1435 return TEST_FAILURE; 1436 1437 if (stats.rx_fill_ring_empty_descs) 1438 return TEST_PASS; 1439 1440 return TEST_FAILURE; 1441 } 1442 1443 static int validate_tx_invalid_descs(struct ifobject *ifobject) 1444 { 1445 struct xsk_socket *xsk = ifobject->xsk->xsk; 1446 int fd = xsk_socket__fd(xsk); 1447 struct xdp_statistics stats; 1448 socklen_t optlen; 1449 int err; 1450 1451 optlen = sizeof(stats); 1452 err = getsockopt(fd, SOL_XDP, XDP_STATISTICS, &stats, &optlen); 1453 if (err) { 1454 ksft_print_msg("[%s] getsockopt(XDP_STATISTICS) error %u %s\n", 1455 __func__, -err, strerror(-err)); 1456 return TEST_FAILURE; 1457 } 1458 1459 if (stats.tx_invalid_descs != ifobject->xsk->pkt_stream->nb_pkts / 2) { 1460 ksft_print_msg("[%s] tx_invalid_descs incorrect. Got [%llu] expected [%u]\n", 1461 __func__, 1462 (unsigned long long)stats.tx_invalid_descs, 1463 ifobject->xsk->pkt_stream->nb_pkts); 1464 return TEST_FAILURE; 1465 } 1466 1467 return TEST_PASS; 1468 } 1469 1470 static int xsk_configure(struct test_spec *test, struct ifobject *ifobject, 1471 struct xsk_umem_info *umem, bool tx) 1472 { 1473 int i, ret; 1474 1475 for (i = 0; i < test->nb_sockets; i++) { 1476 bool shared = (ifobject->shared_umem && tx) ? true : !!i; 1477 u32 ctr = 0; 1478 1479 while (ctr++ < SOCK_RECONF_CTR) { 1480 ret = xsk_configure_socket(&ifobject->xsk_arr[i], umem, 1481 ifobject, shared); 1482 if (!ret) 1483 break; 1484 1485 /* Retry if it fails as xsk_socket__create() is asynchronous */ 1486 if (ctr >= SOCK_RECONF_CTR) 1487 return ret; 1488 usleep(USLEEP_MAX); 1489 } 1490 if (ifobject->busy_poll) { 1491 ret = enable_busy_poll(&ifobject->xsk_arr[i]); 1492 if (ret) 1493 return ret; 1494 } 1495 } 1496 1497 return 0; 1498 } 1499 1500 static int thread_common_ops_tx(struct test_spec *test, struct ifobject *ifobject) 1501 { 1502 struct xsk_umem_info *umem_rx, *umem_tx; 1503 int ret; 1504 1505 if (!test->ifobj_rx || !test->ifobj_rx->xsk_arr[0].umem->umem) { 1506 ksft_print_msg("Error: RX UMEM is not initialized before shared-UMEM TX setup\n"); 1507 return -EINVAL; 1508 } 1509 1510 umem_rx = test->ifobj_rx->xsk_arr[0].umem; 1511 umem_tx = ifobject->xsk_arr[0].umem_real; 1512 memcpy(umem_tx, umem_rx, sizeof(*umem_tx)); 1513 umem_tx->base_addr = 0; 1514 umem_tx->next_buffer = 0; 1515 1516 ret = xsk_configure(test, ifobject, umem_rx, true); 1517 if (ret) 1518 return ret; 1519 ifobject->xsk = &ifobject->xsk_arr[0]; 1520 ifobject->xskmap = test->ifobj_rx->xskmap; 1521 1522 return 0; 1523 } 1524 1525 static int xsk_populate_fill_ring(struct xsk_umem_info *umem, struct pkt_stream *pkt_stream, 1526 bool fill_up) 1527 { 1528 u32 rx_frame_size = umem->frame_size - XDP_PACKET_HEADROOM; 1529 u32 idx = 0, filled = 0, buffers_to_fill, nb_pkts; 1530 int ret; 1531 1532 if (umem->num_frames < XSK_RING_PROD__DEFAULT_NUM_DESCS) 1533 buffers_to_fill = umem->num_frames; 1534 else 1535 buffers_to_fill = umem->fill_size; 1536 1537 ret = xsk_ring_prod__reserve(&umem->fq, buffers_to_fill, &idx); 1538 if (ret != buffers_to_fill) 1539 return -ENOSPC; 1540 1541 while (filled < buffers_to_fill) { 1542 struct pkt *pkt = pkt_stream_get_next_rx_pkt(pkt_stream, &nb_pkts); 1543 u64 addr; 1544 u32 i; 1545 1546 for (i = 0; i < pkt_nb_frags(rx_frame_size, pkt_stream, pkt); i++) { 1547 if (!pkt) { 1548 if (!fill_up) 1549 break; 1550 addr = filled * umem->frame_size + umem->base_addr; 1551 } else if (pkt->offset >= 0) { 1552 addr = pkt->offset % umem->frame_size + umem_alloc_buffer(umem); 1553 } else { 1554 addr = pkt->offset + umem_alloc_buffer(umem); 1555 } 1556 1557 *xsk_ring_prod__fill_addr(&umem->fq, idx++) = addr; 1558 if (++filled >= buffers_to_fill) 1559 break; 1560 } 1561 } 1562 xsk_ring_prod__submit(&umem->fq, filled); 1563 xsk_ring_prod__cancel(&umem->fq, buffers_to_fill - filled); 1564 1565 pkt_stream_reset(pkt_stream); 1566 umem_reset_alloc(umem); 1567 1568 return 0; 1569 } 1570 1571 static int thread_common_ops(struct test_spec *test, struct ifobject *ifobject) 1572 { 1573 struct xsk_umem_info *umem = ifobject->xsk->umem; 1574 LIBBPF_OPTS(bpf_xdp_query_opts, opts); 1575 int mmap_flags; 1576 u64 umem_sz, mmap_sz; 1577 void *bufs; 1578 int ret; 1579 u32 i; 1580 1581 umem_sz = umem_size(umem); 1582 mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE; 1583 1584 if (umem->unaligned_mode) 1585 mmap_flags |= MAP_HUGETLB | MAP_HUGE_2MB; 1586 1587 if (ifobject->shared_umem) 1588 umem_sz *= 2; 1589 1590 mmap_sz = umem->unaligned_mode ? 1591 ceil_u64(umem_sz, HUGEPAGE_SIZE) * HUGEPAGE_SIZE : umem_sz; 1592 1593 bufs = mmap(NULL, mmap_sz, PROT_READ | PROT_WRITE, mmap_flags, -1, 0); 1594 if (bufs == MAP_FAILED) 1595 return -errno; 1596 1597 umem->mmap_size = mmap_sz; 1598 1599 ret = xsk_configure_umem(ifobject, umem, bufs, umem_sz); 1600 if (ret) 1601 return ret; 1602 1603 ret = xsk_configure(test, ifobject, umem, false); 1604 if (ret) 1605 return ret; 1606 1607 ifobject->xsk = &ifobject->xsk_arr[0]; 1608 1609 if (!ifobject->rx_on) 1610 return 0; 1611 1612 ret = xsk_populate_fill_ring(umem, ifobject->xsk->pkt_stream, 1613 ifobject->use_fill_ring); 1614 if (ret) 1615 return ret; 1616 1617 for (i = 0; i < test->nb_sockets; i++) { 1618 ret = xsk_update_xskmap(ifobject->xskmap, ifobject->xsk_arr[i].xsk, i); 1619 if (ret) 1620 return ret; 1621 } 1622 1623 return 0; 1624 } 1625 1626 void *worker_testapp_validate_tx(void *arg) 1627 { 1628 struct test_spec *test = (struct test_spec *)arg; 1629 struct ifobject *ifobject = test->ifobj_tx; 1630 int err; 1631 1632 if (test->current_step == 1) { 1633 if (!ifobject->shared_umem) { 1634 if (thread_common_ops(test, ifobject)) { 1635 test->fail = true; 1636 pthread_exit(NULL); 1637 } 1638 } else { 1639 if (thread_common_ops_tx(test, ifobject)) { 1640 test->fail = true; 1641 pthread_exit(NULL); 1642 } 1643 } 1644 } 1645 1646 err = send_pkts(test, ifobject); 1647 1648 if (!err && ifobject->validation_func) 1649 err = ifobject->validation_func(ifobject); 1650 if (err) 1651 test->fail = true; 1652 1653 pthread_exit(NULL); 1654 } 1655 1656 void *worker_testapp_validate_rx(void *arg) 1657 { 1658 struct test_spec *test = (struct test_spec *)arg; 1659 struct ifobject *ifobject = test->ifobj_rx; 1660 int err; 1661 1662 if (test->current_step == 1) { 1663 err = thread_common_ops(test, ifobject); 1664 } else { 1665 xsk_clear_xskmap(ifobject->xskmap); 1666 err = xsk_update_xskmap(ifobject->xskmap, ifobject->xsk->xsk, 0); 1667 if (err) 1668 ksft_print_msg("Error: Failed to update xskmap, error %s\n", 1669 strerror(-err)); 1670 } 1671 1672 if (test->use_barrier) 1673 pthread_barrier_wait(&barr); 1674 1675 /* We leave only now in case of error to avoid getting stuck in the barrier */ 1676 if (err) { 1677 test->fail = true; 1678 pthread_exit(NULL); 1679 } 1680 1681 err = receive_pkts(test); 1682 1683 if (!err && ifobject->validation_func) 1684 err = ifobject->validation_func(ifobject); 1685 1686 if (err) { 1687 if (!test->adjust_tail) { 1688 test->fail = true; 1689 } else { 1690 bool supported; 1691 1692 if (is_adjust_tail_supported(ifobject->xdp_progs, &supported)) 1693 test->fail = true; 1694 else if (!supported) 1695 test->adjust_tail_support = false; 1696 else 1697 test->fail = true; 1698 } 1699 } 1700 1701 pthread_exit(NULL); 1702 } 1703 1704 static void testapp_clean_xsk_umem(struct ifobject *ifobj) 1705 { 1706 struct xsk_umem_info *umem = ifobj->xsk->umem; 1707 1708 xsk_umem__delete(umem->umem); 1709 munmap(umem->buffer, umem->mmap_size); 1710 } 1711 1712 static bool xdp_prog_changed_rx(struct test_spec *test) 1713 { 1714 struct ifobject *ifobj = test->ifobj_rx; 1715 1716 return ifobj->xdp_prog != test->xdp_prog_rx || ifobj->mode != test->mode; 1717 } 1718 1719 static bool xdp_prog_changed_tx(struct test_spec *test) 1720 { 1721 struct ifobject *ifobj = test->ifobj_tx; 1722 1723 return ifobj->xdp_prog != test->xdp_prog_tx || ifobj->mode != test->mode; 1724 } 1725 1726 static int xsk_reattach_xdp(struct ifobject *ifobj, struct bpf_program *xdp_prog, 1727 struct bpf_map *xskmap, enum test_mode mode) 1728 { 1729 int err; 1730 1731 xsk_detach_xdp_program(ifobj->ifindex, mode_to_xdp_flags(ifobj->mode)); 1732 err = xsk_attach_xdp_program(xdp_prog, ifobj->ifindex, mode_to_xdp_flags(mode)); 1733 if (err) { 1734 ksft_print_msg("Error attaching XDP program\n"); 1735 return err; 1736 } 1737 1738 if (ifobj->mode != mode && (mode == TEST_MODE_DRV || mode == TEST_MODE_ZC)) 1739 if (!xsk_is_in_mode(ifobj->ifindex, XDP_FLAGS_DRV_MODE)) { 1740 ksft_print_msg("ERROR: XDP prog not in DRV mode\n"); 1741 return -EINVAL; 1742 } 1743 1744 ifobj->xdp_prog = xdp_prog; 1745 ifobj->xskmap = xskmap; 1746 ifobj->mode = mode; 1747 1748 return 0; 1749 } 1750 1751 static int xsk_attach_xdp_progs(struct test_spec *test, struct ifobject *ifobj_rx, 1752 struct ifobject *ifobj_tx) 1753 { 1754 int err = 0; 1755 1756 if (xdp_prog_changed_rx(test)) { 1757 err = xsk_reattach_xdp(ifobj_rx, test->xdp_prog_rx, test->xskmap_rx, test->mode); 1758 if (err) 1759 return err; 1760 } 1761 1762 if (!ifobj_tx || ifobj_tx->shared_umem) 1763 return 0; 1764 1765 if (xdp_prog_changed_tx(test)) 1766 err = xsk_reattach_xdp(ifobj_tx, test->xdp_prog_tx, test->xskmap_tx, test->mode); 1767 1768 return err; 1769 } 1770 1771 static void clean_sockets(struct test_spec *test, struct ifobject *ifobj) 1772 { 1773 u32 i; 1774 1775 if (!ifobj || !test) 1776 return; 1777 1778 for (i = 0; i < test->nb_sockets; i++) 1779 xsk_socket__delete(ifobj->xsk_arr[i].xsk); 1780 } 1781 1782 static void clean_umem(struct test_spec *test, struct ifobject *ifobj1, struct ifobject *ifobj2) 1783 { 1784 if (!ifobj1) 1785 return; 1786 1787 testapp_clean_xsk_umem(ifobj1); 1788 if (ifobj2 && !ifobj2->shared_umem) 1789 testapp_clean_xsk_umem(ifobj2); 1790 } 1791 1792 static int __testapp_validate_traffic(struct test_spec *test, struct ifobject *ifobj1, 1793 struct ifobject *ifobj2) 1794 { 1795 pthread_t t0, t1; 1796 int err; 1797 1798 if (test->mtu > MAX_ETH_PKT_SIZE) { 1799 if (test->mode == TEST_MODE_ZC && (!ifobj1->multi_buff_zc_supp || 1800 (ifobj2 && !ifobj2->multi_buff_zc_supp))) { 1801 ksft_print_msg("Multi buffer for zero-copy not supported.\n"); 1802 return TEST_SKIP; 1803 } 1804 if (test->mode != TEST_MODE_ZC && (!ifobj1->multi_buff_supp || 1805 (ifobj2 && !ifobj2->multi_buff_supp))) { 1806 ksft_print_msg("Multi buffer not supported.\n"); 1807 return TEST_SKIP; 1808 } 1809 } 1810 err = test_spec_set_mtu(test, test->mtu); 1811 if (err) { 1812 ksft_print_msg("Error, could not set mtu.\n"); 1813 return TEST_FAILURE; 1814 } 1815 1816 err = xsk_attach_xdp_progs(test, ifobj1, ifobj2); 1817 if (err) { 1818 ksft_print_msg("Error: failed to attach XDP programs: %d (%s)\n", 1819 err, strerror(-err)); 1820 return TEST_FAILURE; 1821 } 1822 test->use_barrier = !!ifobj2; 1823 1824 if (test->use_barrier) { 1825 if (pthread_barrier_init(&barr, NULL, 2)) 1826 return TEST_FAILURE; 1827 1828 pkt_stream_reset(ifobj2->xsk->pkt_stream); 1829 } 1830 1831 test->current_step++; 1832 pkt_stream_reset(ifobj1->xsk->pkt_stream); 1833 pkts_in_flight = 0; 1834 1835 /*Spawn RX thread */ 1836 pthread_create(&t0, NULL, ifobj1->func_ptr, test); 1837 1838 if (test->use_barrier) { 1839 pthread_barrier_wait(&barr); 1840 if (pthread_barrier_destroy(&barr)) { 1841 test->use_barrier = false; 1842 pthread_join(t0, NULL); 1843 clean_sockets(test, ifobj1); 1844 clean_umem(test, ifobj1, NULL); 1845 return TEST_FAILURE; 1846 } 1847 } 1848 1849 if (ifobj2) { 1850 /*Spawn TX thread */ 1851 pthread_create(&t1, NULL, ifobj2->func_ptr, test); 1852 pthread_join(t1, NULL); 1853 } 1854 1855 pthread_join(t0, NULL); 1856 1857 if (test->total_steps == test->current_step || test->fail) { 1858 clean_sockets(test, ifobj1); 1859 clean_sockets(test, ifobj2); 1860 clean_umem(test, ifobj1, ifobj2); 1861 } 1862 1863 if (test->fail) 1864 return TEST_FAILURE; 1865 1866 return TEST_PASS; 1867 } 1868 1869 static int testapp_validate_traffic(struct test_spec *test) 1870 { 1871 struct ifobject *ifobj_rx = test->ifobj_rx; 1872 struct ifobject *ifobj_tx = test->ifobj_tx; 1873 1874 if ((ifobj_rx->xsk->umem->unaligned_mode && !ifobj_rx->unaligned_supp) || 1875 (ifobj_tx->xsk->umem->unaligned_mode && !ifobj_tx->unaligned_supp)) { 1876 ksft_print_msg("No huge pages present.\n"); 1877 return TEST_SKIP; 1878 } 1879 1880 if (test->set_ring) { 1881 if (ifobj_tx->hw_ring_size_supp) { 1882 if (set_ring_size(ifobj_tx)) { 1883 ksft_print_msg("Failed to change HW ring size.\n"); 1884 return TEST_FAILURE; 1885 } 1886 } else { 1887 ksft_print_msg("Changing HW ring size not supported.\n"); 1888 return TEST_SKIP; 1889 } 1890 } 1891 1892 return __testapp_validate_traffic(test, ifobj_rx, ifobj_tx); 1893 } 1894 1895 static int testapp_validate_traffic_single_thread(struct test_spec *test, struct ifobject *ifobj) 1896 { 1897 return __testapp_validate_traffic(test, ifobj, NULL); 1898 } 1899 1900 int testapp_teardown(struct test_spec *test) 1901 { 1902 int i; 1903 1904 for (i = 0; i < MAX_TEARDOWN_ITER; i++) { 1905 if (testapp_validate_traffic(test)) 1906 return TEST_FAILURE; 1907 test_spec_reset(test); 1908 } 1909 1910 return TEST_PASS; 1911 } 1912 1913 static void swap_directions(struct ifobject **ifobj1, struct ifobject **ifobj2) 1914 { 1915 thread_func_t tmp_func_ptr = (*ifobj1)->func_ptr; 1916 struct ifobject *tmp_ifobj = (*ifobj1); 1917 1918 (*ifobj1)->func_ptr = (*ifobj2)->func_ptr; 1919 (*ifobj2)->func_ptr = tmp_func_ptr; 1920 1921 *ifobj1 = *ifobj2; 1922 *ifobj2 = tmp_ifobj; 1923 } 1924 1925 int testapp_bidirectional(struct test_spec *test) 1926 { 1927 int res; 1928 1929 test->ifobj_tx->rx_on = true; 1930 test->ifobj_rx->tx_on = true; 1931 test->total_steps = 2; 1932 if (testapp_validate_traffic(test)) 1933 return TEST_FAILURE; 1934 1935 print_verbose("Switching Tx/Rx direction\n"); 1936 swap_directions(&test->ifobj_rx, &test->ifobj_tx); 1937 res = __testapp_validate_traffic(test, test->ifobj_rx, test->ifobj_tx); 1938 1939 swap_directions(&test->ifobj_rx, &test->ifobj_tx); 1940 return res; 1941 } 1942 1943 static int swap_xsk_resources(struct test_spec *test) 1944 { 1945 int ret; 1946 1947 test->ifobj_tx->xsk_arr[0].pkt_stream = NULL; 1948 test->ifobj_rx->xsk_arr[0].pkt_stream = NULL; 1949 test->ifobj_tx->xsk_arr[1].pkt_stream = test->tx_pkt_stream_default; 1950 test->ifobj_rx->xsk_arr[1].pkt_stream = test->rx_pkt_stream_default; 1951 test->ifobj_tx->xsk = &test->ifobj_tx->xsk_arr[1]; 1952 test->ifobj_rx->xsk = &test->ifobj_rx->xsk_arr[1]; 1953 1954 ret = xsk_update_xskmap(test->ifobj_rx->xskmap, test->ifobj_rx->xsk->xsk, 0); 1955 if (ret) 1956 return TEST_FAILURE; 1957 1958 return TEST_PASS; 1959 } 1960 1961 int testapp_xdp_prog_cleanup(struct test_spec *test) 1962 { 1963 test->total_steps = 2; 1964 test->nb_sockets = 2; 1965 if (testapp_validate_traffic(test)) 1966 return TEST_FAILURE; 1967 1968 if (swap_xsk_resources(test)) { 1969 clean_sockets(test, test->ifobj_rx); 1970 clean_sockets(test, test->ifobj_tx); 1971 clean_umem(test, test->ifobj_rx, test->ifobj_tx); 1972 return TEST_FAILURE; 1973 } 1974 1975 return testapp_validate_traffic(test); 1976 } 1977 1978 int testapp_headroom(struct test_spec *test) 1979 { 1980 test->ifobj_rx->xsk->umem->frame_headroom = UMEM_HEADROOM_TEST_SIZE; 1981 return testapp_validate_traffic(test); 1982 } 1983 1984 int testapp_stats_rx_dropped(struct test_spec *test) 1985 { 1986 struct xsk_umem_info *umem = test->ifobj_rx->xsk->umem; 1987 u32 umem_tr = test->ifobj_tx->umem_tailroom; 1988 1989 if (test->mode == TEST_MODE_ZC) { 1990 ksft_print_msg("Can not run RX_DROPPED test for ZC mode\n"); 1991 return TEST_SKIP; 1992 } 1993 1994 if (pkt_stream_replace_half(test, (MIN_PKT_SIZE * 3) + umem_tr, 0)) 1995 return TEST_FAILURE; 1996 umem->frame_headroom = umem->frame_size - 1997 XDP_PACKET_HEADROOM - (MIN_PKT_SIZE * 2) - umem_tr; 1998 if (pkt_stream_receive_half(test)) 1999 return TEST_FAILURE; 2000 test->ifobj_rx->validation_func = validate_rx_dropped; 2001 return testapp_validate_traffic(test); 2002 } 2003 2004 int testapp_stats_tx_invalid_descs(struct test_spec *test) 2005 { 2006 if (pkt_stream_replace_half(test, XSK_UMEM__INVALID_FRAME_SIZE, 0)) 2007 return TEST_FAILURE; 2008 test->ifobj_tx->validation_func = validate_tx_invalid_descs; 2009 return testapp_validate_traffic(test); 2010 } 2011 2012 int testapp_stats_rx_full(struct test_spec *test) 2013 { 2014 struct pkt_stream *tmp; 2015 2016 tmp = pkt_stream_generate(DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE); 2017 if (!tmp) 2018 return TEST_FAILURE; 2019 test->ifobj_tx->xsk->pkt_stream = tmp; 2020 2021 tmp = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE); 2022 if (!tmp) 2023 return TEST_FAILURE; 2024 test->ifobj_rx->xsk->pkt_stream = tmp; 2025 2026 test->ifobj_rx->xsk->rxqsize = DEFAULT_UMEM_BUFFERS; 2027 test->ifobj_rx->release_rx = false; 2028 test->ifobj_rx->validation_func = validate_rx_full; 2029 return testapp_validate_traffic(test); 2030 } 2031 2032 int testapp_stats_fill_empty(struct test_spec *test) 2033 { 2034 struct pkt_stream *tmp; 2035 2036 tmp = pkt_stream_generate(DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE); 2037 if (!tmp) 2038 return TEST_FAILURE; 2039 test->ifobj_tx->xsk->pkt_stream = tmp; 2040 2041 tmp = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE); 2042 if (!tmp) 2043 return TEST_FAILURE; 2044 test->ifobj_rx->xsk->pkt_stream = tmp; 2045 2046 test->ifobj_rx->use_fill_ring = false; 2047 test->ifobj_rx->validation_func = validate_fill_empty; 2048 return testapp_validate_traffic(test); 2049 } 2050 2051 int testapp_send_receive_unaligned(struct test_spec *test) 2052 { 2053 test_spec_set_unaligned(test); 2054 /* Let half of the packets straddle a 4K buffer boundary */ 2055 if (pkt_stream_replace_half(test, MIN_PKT_SIZE, -MIN_PKT_SIZE / 2)) 2056 return TEST_FAILURE; 2057 2058 return testapp_validate_traffic(test); 2059 } 2060 2061 int testapp_send_receive_unaligned_mb(struct test_spec *test) 2062 { 2063 test->mtu = MAX_ETH_JUMBO_SIZE; 2064 test_spec_set_unaligned(test); 2065 if (pkt_stream_replace(test, DEFAULT_PKT_CNT, MAX_ETH_JUMBO_SIZE)) 2066 return TEST_FAILURE; 2067 return testapp_validate_traffic(test); 2068 } 2069 2070 int testapp_single_pkt(struct test_spec *test) 2071 { 2072 struct pkt pkts[] = {{0, MIN_PKT_SIZE, 0, true}}; 2073 2074 if (pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts))) 2075 return TEST_FAILURE; 2076 return testapp_validate_traffic(test); 2077 } 2078 2079 int testapp_send_receive_mb(struct test_spec *test) 2080 { 2081 test->mtu = MAX_ETH_JUMBO_SIZE; 2082 if (pkt_stream_replace(test, DEFAULT_PKT_CNT, MAX_ETH_JUMBO_SIZE)) 2083 return TEST_FAILURE; 2084 2085 return testapp_validate_traffic(test); 2086 } 2087 2088 int testapp_invalid_desc_mb(struct test_spec *test) 2089 { 2090 struct xsk_umem_info *umem = test->ifobj_tx->xsk->umem; 2091 u64 umem_sz = umem_size(umem); 2092 struct pkt pkts[] = { 2093 /* Valid packet for synch to start with */ 2094 {0, MIN_PKT_SIZE, 0, true, 0}, 2095 /* Zero frame len is not legal */ 2096 {0, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XDP_PKT_CONTD}, 2097 {0, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XDP_PKT_CONTD}, 2098 {0, 0, 0, false, 0}, 2099 /* Invalid address in the second frame */ 2100 {0, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XDP_PKT_CONTD}, 2101 {umem_sz * 2, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XDP_PKT_CONTD}, 2102 {0, MIN_PKT_SIZE, 0, false, 0}, 2103 /* Invalid len in the middle */ 2104 {0, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XDP_PKT_CONTD}, 2105 {0, XSK_UMEM__INVALID_FRAME_SIZE, 0, false, XDP_PKT_CONTD}, 2106 {0, MIN_PKT_SIZE, 0, false, 0}, 2107 /* Invalid options in the middle */ 2108 {0, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XDP_PKT_CONTD}, 2109 {0, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XSK_DESC__INVALID_OPTION}, 2110 {0, MIN_PKT_SIZE, 0, false, 0}, 2111 /* Transmit 2 frags, receive 3 */ 2112 {0, XSK_UMEM__MAX_FRAME_SIZE, 0, true, XDP_PKT_CONTD}, 2113 {0, XSK_UMEM__MAX_FRAME_SIZE, 0, true, 0}, 2114 /* Middle frame crosses chunk boundary with small length */ 2115 {0, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XDP_PKT_CONTD}, 2116 {-MIN_PKT_SIZE / 2, MIN_PKT_SIZE, 0, false, 0}, 2117 /* Valid packet for synch so that something is received */ 2118 {0, MIN_PKT_SIZE, 0, true, 0}}; 2119 2120 if (umem->unaligned_mode) { 2121 /* Crossing a chunk boundary allowed */ 2122 pkts[15].valid = true; 2123 pkts[16].valid = true; 2124 } 2125 2126 test->mtu = MAX_ETH_JUMBO_SIZE; 2127 if (pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts))) 2128 return TEST_FAILURE; 2129 return testapp_validate_traffic(test); 2130 } 2131 2132 int testapp_invalid_desc(struct test_spec *test) 2133 { 2134 struct xsk_umem_info *umem = test->ifobj_tx->xsk->umem; 2135 u64 umem_sz = umem_size(umem); 2136 struct pkt pkts[] = { 2137 /* Zero packet address allowed */ 2138 {0, MIN_PKT_SIZE, 0, true}, 2139 /* Allowed packet */ 2140 {0, MIN_PKT_SIZE, 0, true}, 2141 /* Straddling the start of umem */ 2142 {-2, MIN_PKT_SIZE, 0, false}, 2143 /* Packet too large */ 2144 {0, XSK_UMEM__INVALID_FRAME_SIZE, 0, false}, 2145 /* Up to end of umem allowed */ 2146 {umem_sz - MIN_PKT_SIZE - 2 * umem->frame_size, MIN_PKT_SIZE, 0, true}, 2147 /* After umem ends */ 2148 {umem_sz, MIN_PKT_SIZE, 0, false}, 2149 /* Straddle the end of umem */ 2150 {umem_sz - MIN_PKT_SIZE / 2, MIN_PKT_SIZE, 0, false}, 2151 /* Straddle a 4K boundary */ 2152 {0x1000 - MIN_PKT_SIZE / 2, MIN_PKT_SIZE, 0, false}, 2153 /* Straddle a 2K boundary */ 2154 {0x800 - MIN_PKT_SIZE / 2, MIN_PKT_SIZE, 0, true}, 2155 /* Valid packet for synch so that something is received */ 2156 {0, MIN_PKT_SIZE, 0, true}}; 2157 2158 if (umem->unaligned_mode) { 2159 /* Crossing a page boundary allowed */ 2160 pkts[7].valid = true; 2161 } 2162 if (umem->frame_size == XSK_UMEM__DEFAULT_FRAME_SIZE / 2) { 2163 /* Crossing a 2K frame size boundary not allowed */ 2164 pkts[8].valid = false; 2165 } 2166 2167 if (test->ifobj_tx->shared_umem) { 2168 pkts[4].offset += umem_sz; 2169 pkts[5].offset += umem_sz; 2170 pkts[6].offset += umem_sz; 2171 } 2172 2173 if (pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts))) 2174 return TEST_FAILURE; 2175 return testapp_validate_traffic(test); 2176 } 2177 2178 int testapp_xdp_drop(struct test_spec *test) 2179 { 2180 struct xsk_xdp_progs *skel_rx = test->ifobj_rx->xdp_progs; 2181 struct xsk_xdp_progs *skel_tx = test->ifobj_tx->xdp_progs; 2182 2183 test_spec_set_xdp_prog(test, skel_rx->progs.xsk_xdp_drop, skel_tx->progs.xsk_xdp_drop, 2184 skel_rx->maps.xsk, skel_tx->maps.xsk); 2185 2186 if (pkt_stream_receive_half(test)) 2187 return TEST_FAILURE; 2188 return testapp_validate_traffic(test); 2189 } 2190 2191 int testapp_xdp_metadata_copy(struct test_spec *test) 2192 { 2193 struct xsk_xdp_progs *skel_rx = test->ifobj_rx->xdp_progs; 2194 struct xsk_xdp_progs *skel_tx = test->ifobj_tx->xdp_progs; 2195 2196 test_spec_set_xdp_prog(test, skel_rx->progs.xsk_xdp_populate_metadata, 2197 skel_tx->progs.xsk_xdp_populate_metadata, 2198 skel_rx->maps.xsk, skel_tx->maps.xsk); 2199 test->ifobj_rx->use_metadata = true; 2200 2201 skel_rx->bss->count = 0; 2202 2203 return testapp_validate_traffic(test); 2204 } 2205 2206 int testapp_xdp_shared_umem(struct test_spec *test) 2207 { 2208 struct xsk_xdp_progs *skel_rx = test->ifobj_rx->xdp_progs; 2209 struct xsk_xdp_progs *skel_tx = test->ifobj_tx->xdp_progs; 2210 int ret; 2211 2212 test->total_steps = 1; 2213 test->nb_sockets = 2; 2214 2215 test_spec_set_xdp_prog(test, skel_rx->progs.xsk_xdp_shared_umem, 2216 skel_tx->progs.xsk_xdp_shared_umem, 2217 skel_rx->maps.xsk, skel_tx->maps.xsk); 2218 2219 if (pkt_stream_even_odd_sequence(test)) 2220 return TEST_FAILURE; 2221 2222 ret = testapp_validate_traffic(test); 2223 2224 release_even_odd_sequence(test); 2225 2226 return ret; 2227 } 2228 2229 int testapp_poll_txq_tmout(struct test_spec *test) 2230 { 2231 bool shared_umem = test->ifobj_tx->shared_umem; 2232 int ret; 2233 2234 test->poll_tmout = true; 2235 /* 2236 * POLL_TXQ_FULL exercises TX timeout setup in isolation. 2237 * Keep TX out of shared-UMEM mode here so TX setup does not require 2238 * RX UMEM to be initialized first. 2239 */ 2240 test->ifobj_tx->shared_umem = false; 2241 test->ifobj_tx->use_poll = true; 2242 /* create invalid frame by set umem frame_size and pkt length equal to 2048 */ 2243 test->ifobj_tx->xsk->umem->frame_size = 2048; 2244 if (pkt_stream_replace(test, 2 * DEFAULT_PKT_CNT, 2048)) { 2245 test->ifobj_tx->shared_umem = shared_umem; 2246 return TEST_FAILURE; 2247 } 2248 2249 ret = testapp_validate_traffic_single_thread(test, test->ifobj_tx); 2250 test->ifobj_tx->shared_umem = shared_umem; 2251 2252 return ret; 2253 } 2254 2255 int testapp_poll_rxq_tmout(struct test_spec *test) 2256 { 2257 test->poll_tmout = true; 2258 test->ifobj_rx->use_poll = true; 2259 return testapp_validate_traffic_single_thread(test, test->ifobj_rx); 2260 } 2261 2262 int testapp_too_many_frags(struct test_spec *test) 2263 { 2264 struct pkt *pkts; 2265 u32 max_frags, i; 2266 int ret = TEST_FAILURE; 2267 2268 if (test->mode == TEST_MODE_ZC) { 2269 max_frags = test->ifobj_tx->xdp_zc_max_segs; 2270 } else { 2271 max_frags = test->ifobj_tx->max_skb_frags; 2272 max_frags += 1; 2273 } 2274 2275 pkts = calloc(2 * max_frags + 3, sizeof(struct pkt)); 2276 if (!pkts) 2277 return TEST_FAILURE; 2278 2279 test->mtu = MAX_ETH_JUMBO_SIZE; 2280 2281 /* Valid packet for synch */ 2282 pkts[0].len = MIN_PKT_SIZE; 2283 pkts[0].valid = true; 2284 2285 /* One valid packet with the max amount of frags */ 2286 for (i = 1; i < max_frags + 1; i++) { 2287 pkts[i].len = MIN_PKT_SIZE; 2288 pkts[i].options = XDP_PKT_CONTD; 2289 pkts[i].valid = true; 2290 } 2291 pkts[max_frags].options = 0; 2292 2293 /* An invalid packet with the max + 1 amount of frags */ 2294 for (i = max_frags + 1; i < 2 * max_frags + 2; i++) { 2295 pkts[i].len = MIN_PKT_SIZE; 2296 pkts[i].options = XDP_PKT_CONTD; 2297 pkts[i].valid = true; 2298 } 2299 pkts[2 * max_frags + 1].options = 0; 2300 2301 /* Valid packet for synch */ 2302 pkts[2 * max_frags + 2].len = MIN_PKT_SIZE; 2303 pkts[2 * max_frags + 2].valid = true; 2304 2305 if (pkt_stream_generate_custom(test, pkts, 2 * max_frags + 3)) { 2306 free(pkts); 2307 return TEST_FAILURE; 2308 } 2309 2310 /* The generated Tx stream must keep the too-big packet valid so that 2311 * __send_pkts() accounts its descriptors in outstanding_tx. The Rx 2312 * stream, however, must not expect this packet on the wire. 2313 */ 2314 test->ifobj_rx->xsk->pkt_stream->pkts[2].valid = false; 2315 test->ifobj_rx->xsk->pkt_stream->nb_valid_entries--; 2316 2317 ret = testapp_validate_traffic(test); 2318 free(pkts); 2319 return ret; 2320 } 2321 2322 static int xsk_load_xdp_programs(struct ifobject *ifobj) 2323 { 2324 ifobj->xdp_progs = xsk_xdp_progs__open_and_load(); 2325 if (libbpf_get_error(ifobj->xdp_progs)) 2326 return libbpf_get_error(ifobj->xdp_progs); 2327 2328 return 0; 2329 } 2330 2331 /* Simple test */ 2332 static bool hugepages_present(void) 2333 { 2334 size_t mmap_sz = 2 * DEFAULT_UMEM_BUFFERS * XSK_UMEM__DEFAULT_FRAME_SIZE; 2335 void *bufs; 2336 2337 bufs = mmap(NULL, mmap_sz, PROT_READ | PROT_WRITE, 2338 MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, MAP_HUGE_2MB); 2339 if (bufs == MAP_FAILED) 2340 return false; 2341 2342 mmap_sz = ceil_u64(mmap_sz, HUGEPAGE_SIZE) * HUGEPAGE_SIZE; 2343 munmap(bufs, mmap_sz); 2344 return true; 2345 } 2346 2347 int init_iface(struct ifobject *ifobj, thread_func_t func_ptr) 2348 { 2349 LIBBPF_OPTS(bpf_xdp_query_opts, query_opts); 2350 int err; 2351 2352 ifobj->func_ptr = func_ptr; 2353 2354 err = xsk_load_xdp_programs(ifobj); 2355 if (err) { 2356 ksft_print_msg("Error loading XDP program\n"); 2357 return err; 2358 } 2359 2360 if (hugepages_present()) 2361 ifobj->unaligned_supp = true; 2362 2363 err = bpf_xdp_query(ifobj->ifindex, XDP_FLAGS_DRV_MODE, &query_opts); 2364 if (err) { 2365 ksft_print_msg("Error querying XDP capabilities\n"); 2366 return err; 2367 } 2368 if (query_opts.feature_flags & NETDEV_XDP_ACT_RX_SG) 2369 ifobj->multi_buff_supp = true; 2370 if (query_opts.feature_flags & NETDEV_XDP_ACT_XSK_ZEROCOPY) { 2371 if (query_opts.xdp_zc_max_segs > 1) { 2372 ifobj->multi_buff_zc_supp = true; 2373 ifobj->xdp_zc_max_segs = query_opts.xdp_zc_max_segs; 2374 } else { 2375 ifobj->xdp_zc_max_segs = 0; 2376 } 2377 } 2378 2379 return 0; 2380 } 2381 2382 int testapp_send_receive(struct test_spec *test) 2383 { 2384 return testapp_validate_traffic(test); 2385 } 2386 2387 int testapp_send_receive_2k_frame(struct test_spec *test) 2388 { 2389 test_spec_set_frame_size(test, 2048); 2390 if (pkt_stream_replace(test, DEFAULT_PKT_CNT, MIN_PKT_SIZE)) 2391 return TEST_FAILURE; 2392 return testapp_validate_traffic(test); 2393 } 2394 2395 int testapp_poll_rx(struct test_spec *test) 2396 { 2397 test->ifobj_rx->use_poll = true; 2398 return testapp_validate_traffic(test); 2399 } 2400 2401 int testapp_poll_tx(struct test_spec *test) 2402 { 2403 test->ifobj_tx->use_poll = true; 2404 return testapp_validate_traffic(test); 2405 } 2406 2407 int testapp_aligned_inv_desc(struct test_spec *test) 2408 { 2409 return testapp_invalid_desc(test); 2410 } 2411 2412 int testapp_aligned_inv_desc_2k_frame(struct test_spec *test) 2413 { 2414 test_spec_set_frame_size(test, 2048); 2415 return testapp_invalid_desc(test); 2416 } 2417 2418 int testapp_unaligned_inv_desc(struct test_spec *test) 2419 { 2420 test_spec_set_unaligned(test); 2421 return testapp_invalid_desc(test); 2422 } 2423 2424 int testapp_unaligned_inv_desc_4001_frame(struct test_spec *test) 2425 { 2426 u64 page_size, umem_sz; 2427 2428 /* Odd frame size so the UMEM doesn't end near a page boundary. */ 2429 test_spec_set_frame_size(test, 4001); 2430 test_spec_set_unaligned(test); 2431 /* This test exists to test descriptors that staddle the end of 2432 * the UMEM but not a page. 2433 */ 2434 page_size = sysconf(_SC_PAGESIZE); 2435 umem_sz = umem_size(test->ifobj_tx->xsk->umem); 2436 assert(umem_sz % page_size > MIN_PKT_SIZE); 2437 assert(umem_sz % page_size < page_size - MIN_PKT_SIZE); 2438 2439 return testapp_invalid_desc(test); 2440 } 2441 2442 int testapp_aligned_inv_desc_mb(struct test_spec *test) 2443 { 2444 return testapp_invalid_desc_mb(test); 2445 } 2446 2447 int testapp_unaligned_inv_desc_mb(struct test_spec *test) 2448 { 2449 test_spec_set_unaligned(test); 2450 return testapp_invalid_desc_mb(test); 2451 } 2452 2453 int testapp_xdp_metadata(struct test_spec *test) 2454 { 2455 return testapp_xdp_metadata_copy(test); 2456 } 2457 2458 int testapp_xdp_metadata_mb(struct test_spec *test) 2459 { 2460 test->mtu = MAX_ETH_JUMBO_SIZE; 2461 return testapp_xdp_metadata_copy(test); 2462 } 2463 2464 int testapp_hw_sw_min_ring_size(struct test_spec *test) 2465 { 2466 int ret; 2467 2468 test->set_ring = true; 2469 test->total_steps = 2; 2470 test->ifobj_tx->ring.tx_pending = DEFAULT_BATCH_SIZE; 2471 test->ifobj_tx->ring.rx_pending = DEFAULT_BATCH_SIZE * 2; 2472 test->ifobj_tx->xsk->batch_size = 1; 2473 test->ifobj_rx->xsk->batch_size = 1; 2474 ret = testapp_validate_traffic(test); 2475 if (ret) 2476 return ret; 2477 2478 /* Set batch size to hw_ring_size - 1 */ 2479 test->ifobj_tx->xsk->batch_size = DEFAULT_BATCH_SIZE - 1; 2480 test->ifobj_rx->xsk->batch_size = DEFAULT_BATCH_SIZE - 1; 2481 return testapp_validate_traffic(test); 2482 } 2483 2484 int testapp_hw_sw_max_ring_size(struct test_spec *test) 2485 { 2486 u32 max_descs = XSK_RING_PROD__DEFAULT_NUM_DESCS * 4; 2487 int ret; 2488 2489 test->set_ring = true; 2490 test->total_steps = 2; 2491 test->ifobj_tx->ring.tx_pending = test->ifobj_tx->ring.tx_max_pending; 2492 test->ifobj_tx->ring.rx_pending = test->ifobj_tx->ring.rx_max_pending; 2493 test->ifobj_rx->xsk->umem->num_frames = max_descs; 2494 test->ifobj_rx->xsk->umem->fill_size = max_descs; 2495 test->ifobj_rx->xsk->umem->comp_size = max_descs; 2496 test->ifobj_tx->xsk->batch_size = XSK_RING_PROD__DEFAULT_NUM_DESCS; 2497 test->ifobj_rx->xsk->batch_size = XSK_RING_PROD__DEFAULT_NUM_DESCS; 2498 2499 ret = testapp_validate_traffic(test); 2500 if (ret) 2501 return ret; 2502 2503 /* Set batch_size to 8152 for testing, as the ice HW ignores the 3 lowest bits when 2504 * updating the Rx HW tail register. 2505 */ 2506 test->ifobj_tx->xsk->batch_size = test->ifobj_tx->ring.tx_max_pending - 8; 2507 test->ifobj_rx->xsk->batch_size = test->ifobj_tx->ring.tx_max_pending - 8; 2508 if (pkt_stream_replace(test, max_descs, MIN_PKT_SIZE)) { 2509 clean_sockets(test, test->ifobj_tx); 2510 clean_sockets(test, test->ifobj_rx); 2511 clean_umem(test, test->ifobj_rx, test->ifobj_tx); 2512 return TEST_FAILURE; 2513 } 2514 2515 return testapp_validate_traffic(test); 2516 } 2517 2518 static int testapp_xdp_adjust_tail(struct test_spec *test, int adjust_value) 2519 { 2520 struct xsk_xdp_progs *skel_rx = test->ifobj_rx->xdp_progs; 2521 struct xsk_xdp_progs *skel_tx = test->ifobj_tx->xdp_progs; 2522 2523 test_spec_set_xdp_prog(test, skel_rx->progs.xsk_xdp_adjust_tail, 2524 skel_tx->progs.xsk_xdp_adjust_tail, 2525 skel_rx->maps.xsk, skel_tx->maps.xsk); 2526 2527 skel_rx->bss->adjust_value = adjust_value; 2528 2529 return testapp_validate_traffic(test); 2530 } 2531 2532 static int testapp_adjust_tail(struct test_spec *test, u32 value, u32 pkt_len) 2533 { 2534 int ret; 2535 2536 test->adjust_tail_support = true; 2537 test->adjust_tail = true; 2538 test->total_steps = 1; 2539 2540 ret = pkt_stream_replace_ifobject(test->ifobj_tx, DEFAULT_BATCH_SIZE, pkt_len); 2541 if (ret) 2542 return TEST_FAILURE; 2543 2544 ret = pkt_stream_replace_ifobject(test->ifobj_rx, DEFAULT_BATCH_SIZE, pkt_len + value); 2545 if (ret) 2546 return TEST_FAILURE; 2547 2548 ret = testapp_xdp_adjust_tail(test, value); 2549 if (ret) 2550 return ret; 2551 2552 if (!test->adjust_tail_support) { 2553 ksft_print_msg("%s %sResize pkt with bpf_xdp_adjust_tail() not supported\n", 2554 mode_string(test), busy_poll_string(test)); 2555 return TEST_SKIP; 2556 } 2557 2558 return 0; 2559 } 2560 2561 int testapp_adjust_tail_shrink(struct test_spec *test) 2562 { 2563 /* Shrink by 4 bytes for testing purpose */ 2564 return testapp_adjust_tail(test, -4, MIN_PKT_SIZE * 2); 2565 } 2566 2567 int testapp_adjust_tail_shrink_mb(struct test_spec *test) 2568 { 2569 test->mtu = MAX_ETH_JUMBO_SIZE; 2570 /* Shrink by the frag size */ 2571 return testapp_adjust_tail(test, -XSK_UMEM__MAX_FRAME_SIZE, XSK_UMEM__LARGE_FRAME_SIZE * 2); 2572 } 2573 2574 int testapp_adjust_tail_grow(struct test_spec *test) 2575 { 2576 if (test->mode == TEST_MODE_SKB) 2577 return TEST_SKIP; 2578 2579 /* Grow by 4 bytes for testing purpose */ 2580 return testapp_adjust_tail(test, 4, MIN_PKT_SIZE * 2); 2581 } 2582 2583 int testapp_adjust_tail_grow_mb(struct test_spec *test) 2584 { 2585 u32 grow_size; 2586 2587 if (test->mode == TEST_MODE_SKB) 2588 return TEST_SKIP; 2589 2590 /* worst case scenario is when underlying setup will work on 3k 2591 * buffers, let us account for it; given that we will use 6k as 2592 * pkt_len, expect that it will be broken down to 2 descs each 2593 * with 3k payload; 2594 * 2595 * 4k is truesize, 3k payload, 256 HR, 320 TR; 2596 */ 2597 grow_size = XSK_UMEM__MAX_FRAME_SIZE - 2598 XSK_UMEM__LARGE_FRAME_SIZE - 2599 XDP_PACKET_HEADROOM - 2600 test->ifobj_tx->umem_tailroom; 2601 test->mtu = MAX_ETH_JUMBO_SIZE; 2602 2603 return testapp_adjust_tail(test, grow_size, XSK_UMEM__LARGE_FRAME_SIZE * 2); 2604 } 2605 2606 int testapp_tx_queue_consumer(struct test_spec *test) 2607 { 2608 int nr_packets; 2609 2610 if (test->mode == TEST_MODE_ZC) { 2611 ksft_print_msg("Can not run TX_QUEUE_CONSUMER test for ZC mode\n"); 2612 return TEST_SKIP; 2613 } 2614 2615 nr_packets = MAX_TX_BUDGET_DEFAULT + 1; 2616 if (pkt_stream_replace(test, nr_packets, MIN_PKT_SIZE)) 2617 return TEST_FAILURE; 2618 test->ifobj_tx->xsk->batch_size = nr_packets; 2619 test->ifobj_tx->xsk->check_consumer = true; 2620 2621 return testapp_validate_traffic(test); 2622 } 2623 2624 struct ifobject *ifobject_create(void) 2625 { 2626 struct ifobject *ifobj; 2627 2628 ifobj = calloc(1, sizeof(struct ifobject)); 2629 if (!ifobj) 2630 return NULL; 2631 2632 ifobj->xsk_arr = calloc(MAX_SOCKETS, sizeof(*ifobj->xsk_arr)); 2633 if (!ifobj->xsk_arr) 2634 goto out_xsk_arr; 2635 2636 ifobj->xsk_arr[0].umem_real = calloc(1, sizeof(struct xsk_umem_info)); 2637 if (!ifobj->xsk_arr[0].umem_real) 2638 goto out_umem; 2639 2640 return ifobj; 2641 2642 out_umem: 2643 free(ifobj->xsk_arr); 2644 out_xsk_arr: 2645 free(ifobj); 2646 return NULL; 2647 } 2648 2649 void ifobject_delete(struct ifobject *ifobj) 2650 { 2651 if (ifobj->xsk_arr) 2652 free(ifobj->xsk_arr[0].umem_real); 2653 2654 free(ifobj->xsk_arr); 2655 free(ifobj); 2656 } 2657