Branch data Line data Source code
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 : 0 : rte_pktmbuf_free_bulk(pkts_burst, nb_rx); 16 : 0 : } 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 : 0 : fc = fs->lcore; 31 : 0 : fsm = &fwd_streams[fc->stream_idx]; 32 : 0 : nb_fs = fc->stream_nb; 33 : 0 : for (sm_id = 0; sm_id < nb_fs; sm_id++) { 34 : 0 : if (fsm[sm_id]->rx_port == port && 35 : 0 : 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 : 0 : 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 : 0 : if (fs != NULL) { 51 : 0 : fs->rx_packets += nb_rx; 52 : : forward_rx_only(nb_rx, pkts); 53 : : } else { 54 : : /* Source stream not found, drop all packets. */ 55 : 0 : src_fs->fwd_dropped += nb_rx; 56 : 0 : rte_pktmbuf_free_bulk(pkts, nb_rx); 57 : : } 58 : 0 : } 59 : : 60 : : /** 61 : : * Forward packets from shared Rx queue. 62 : : * 63 : : * Source port of packets are identified by mbuf->port. 64 : : */ 65 : : static void 66 : 0 : forward_shared_rxq(struct fwd_stream *fs, uint16_t nb_rx, 67 : : struct rte_mbuf **pkts_burst) 68 : : { 69 : : uint16_t i, nb_sub_burst, port, last_port; 70 : : 71 : : nb_sub_burst = 0; 72 : 0 : last_port = pkts_burst[0]->port; 73 : : /* Locate sub-burst according to mbuf->port. */ 74 : 0 : for (i = 0; i < nb_rx - 1; ++i) { 75 : 0 : rte_prefetch0(pkts_burst[i + 1]); 76 : 0 : port = pkts_burst[i]->port; 77 : 0 : if (i > 0 && last_port != port) { 78 : : /* Forward packets with same source port. */ 79 : 0 : forward_sub_burst(fs, last_port, nb_sub_burst, 80 : 0 : &pkts_burst[i - nb_sub_burst]); 81 : : nb_sub_burst = 0; 82 : : last_port = port; 83 : : } 84 : 0 : nb_sub_burst++; 85 : : } 86 : : /* Last sub-burst. */ 87 : 0 : nb_sub_burst++; 88 : 0 : forward_sub_burst(fs, last_port, nb_sub_burst, 89 : 0 : &pkts_burst[nb_rx - nb_sub_burst]); 90 : 0 : } 91 : : 92 : : static bool 93 : 0 : shared_rxq_fwd(struct fwd_stream *fs) 94 : : { 95 : : struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; 96 : : uint16_t nb_rx; 97 : : 98 : 0 : nb_rx = common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_burst); 99 : 0 : if (unlikely(nb_rx == 0)) 100 : : return false; 101 : 0 : forward_shared_rxq(fs, nb_rx, pkts_burst); 102 : : 103 : 0 : return true; 104 : : } 105 : : 106 : : static void 107 : 0 : shared_rxq_stream_init(struct fwd_stream *fs) 108 : : { 109 : 0 : fs->disabled = ports[fs->rx_port].rxq[fs->rx_queue].state == 110 : : RTE_ETH_QUEUE_STATE_STOPPED; 111 : 0 : } 112 : : 113 : : struct fwd_engine shared_rxq_engine = { 114 : : .fwd_mode_name = "shared_rxq", 115 : : .stream_init = shared_rxq_stream_init, 116 : : .packet_fwd = shared_rxq_fwd, 117 : : };