1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 2021 NVIDIA Corporation & Affiliates 3 */ 4 5 #include <rte_ethdev.h> 6 7 #include "testpmd.h" 8 9 /* 10 * Rx only sub-burst forwarding. 11 */ 12 static void 13 forward_rx_only(uint16_t nb_rx, struct rte_mbuf **pkts_burst) 14 { 15 rte_pktmbuf_free_bulk(pkts_burst, nb_rx); 16 } 17 18 /** 19 * Get packet source stream by source port and queue. 20 * All streams of same shared Rx queue locates on same core. 21 */ 22 static struct fwd_stream * 23 forward_stream_get(struct fwd_stream *fs, uint16_t port) 24 { 25 streamid_t sm_id; 26 struct fwd_lcore *fc; 27 struct fwd_stream **fsm; 28 streamid_t nb_fs; 29 30 fc = fs->lcore; 31 fsm = &fwd_streams[fc->stream_idx]; 32 nb_fs = fc->stream_nb; 33 for (sm_id = 0; sm_id < nb_fs; sm_id++) { 34 if (fsm[sm_id]->rx_port == port && 35 fsm[sm_id]->rx_queue == fs->rx_queue) 36 return fsm[sm_id]; 37 } 38 return NULL; 39 } 40 41 /** 42 * Forward packet by source port and queue. 43 */ 44 static void 45 forward_sub_burst(struct fwd_stream *src_fs, uint16_t port, uint16_t nb_rx, 46 struct rte_mbuf **pkts) 47 { 48 struct fwd_stream *fs = forward_stream_get(src_fs, port); 49 50 if (fs != NULL) { 51 fs->rx_packets += nb_rx; 52 forward_rx_only(nb_rx, pkts); 53 } else { 54 /* Source stream not found, drop all packets. */ 55 src_fs->fwd_dropped += nb_rx; 56 while (nb_rx > 0) 57 rte_pktmbuf_free(pkts[--nb_rx]); 58 } 59 } 60 61 /** 62 * Forward packets from shared Rx queue. 63 * 64 * Source port of packets are identified by mbuf->port. 65 */ 66 static void 67 forward_shared_rxq(struct fwd_stream *fs, uint16_t nb_rx, 68 struct rte_mbuf **pkts_burst) 69 { 70 uint16_t i, nb_sub_burst, port, last_port; 71 72 nb_sub_burst = 0; 73 last_port = pkts_burst[0]->port; 74 /* Locate sub-burst according to mbuf->port. */ 75 for (i = 0; i < nb_rx - 1; ++i) { 76 rte_prefetch0(pkts_burst[i + 1]); 77 port = pkts_burst[i]->port; 78 if (i > 0 && last_port != port) { 79 /* Forward packets with same source port. */ 80 forward_sub_burst(fs, last_port, nb_sub_burst, 81 &pkts_burst[i - nb_sub_burst]); 82 nb_sub_burst = 0; 83 last_port = port; 84 } 85 nb_sub_burst++; 86 } 87 /* Last sub-burst. */ 88 nb_sub_burst++; 89 forward_sub_burst(fs, last_port, nb_sub_burst, 90 &pkts_burst[nb_rx - nb_sub_burst]); 91 } 92 93 static void 94 shared_rxq_fwd(struct fwd_stream *fs) 95 { 96 struct rte_mbuf *pkts_burst[nb_pkt_per_burst]; 97 uint16_t nb_rx; 98 uint64_t start_tsc = 0; 99 100 get_start_cycles(&start_tsc); 101 nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst, 102 nb_pkt_per_burst); 103 inc_rx_burst_stats(fs, nb_rx); 104 if (unlikely(nb_rx == 0)) 105 return; 106 forward_shared_rxq(fs, nb_rx, pkts_burst); 107 get_end_cycles(fs, start_tsc); 108 } 109 110 struct fwd_engine shared_rxq_engine = { 111 .fwd_mode_name = "shared_rxq", 112 .port_fwd_begin = NULL, 113 .port_fwd_end = NULL, 114 .packet_fwd = shared_rxq_fwd, 115 }; 116