Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(c) 2023 Marvell. 3 : : */ 4 : : 5 : : #include <errno.h> 6 : : #include <stdbool.h> 7 : : #include <stdint.h> 8 : : #include <stdio.h> 9 : : #include <stdlib.h> 10 : : #include <string.h> 11 : : 12 : : #include <rte_common.h> 13 : : #include <rte_ethdev.h> 14 : : #include <rte_graph.h> 15 : : #include <rte_graph_worker.h> 16 : : #include <rte_lcore.h> 17 : : #include <rte_node_eth_api.h> 18 : : 19 : : #include "module_api.h" 20 : : 21 : : static int 22 : 0 : l2fwd_pattern_configure(void) 23 : : { 24 : : struct rte_graph_param graph_conf; 25 : : const char **node_patterns; 26 : : uint64_t pcap_pkts_count; 27 : : struct lcore_conf *qconf; 28 : : uint16_t nb_patterns; 29 : : uint8_t pcap_ena; 30 : : char *pcap_file; 31 : : int lcore_id; 32 : : 33 : : nb_patterns = 0; 34 : 0 : node_patterns = malloc((ETHDEV_RX_QUEUE_PER_LCORE_MAX + nb_patterns) * 35 : : sizeof(*node_patterns)); 36 : 0 : if (!node_patterns) 37 : : return -ENOMEM; 38 : : 39 : : memset(&graph_conf, 0, sizeof(graph_conf)); 40 : 0 : graph_conf.node_patterns = node_patterns; 41 : : 42 : : /* Pcap config */ 43 : 0 : graph_pcap_config_get(&pcap_ena, &pcap_pkts_count, &pcap_file); 44 : 0 : graph_conf.pcap_enable = pcap_ena; 45 : 0 : graph_conf.num_pkt_to_capture = pcap_pkts_count; 46 : 0 : graph_conf.pcap_filename = strdup(pcap_file); 47 : : 48 : 0 : for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { 49 : : rte_graph_t graph_id; 50 : : rte_edge_t i; 51 : : 52 : 0 : if (rte_lcore_is_enabled(lcore_id) == 0) 53 : 0 : continue; 54 : : 55 : : qconf = &lcore_conf[lcore_id]; 56 : : 57 : : /* Skip graph creation if no source exists */ 58 : 0 : if (!qconf->n_rx_queue) 59 : 0 : continue; 60 : : 61 : : /* Add rx node patterns of this lcore */ 62 : 0 : for (i = 0; i < qconf->n_rx_queue; i++) { 63 : 0 : graph_conf.node_patterns[nb_patterns + i] = 64 : 0 : qconf->rx_queue_list[i].node_name; 65 : : } 66 : : 67 : 0 : graph_conf.nb_node_patterns = nb_patterns + i; 68 : 0 : graph_conf.socket_id = rte_lcore_to_socket_id(lcore_id); 69 : : 70 : 0 : snprintf(qconf->name, sizeof(qconf->name), "worker_%u", 71 : : lcore_id); 72 : : 73 : 0 : graph_id = rte_graph_create(qconf->name, &graph_conf); 74 : 0 : if (graph_id == RTE_GRAPH_ID_INVALID) 75 : 0 : rte_exit(EXIT_FAILURE, 76 : : "rte_graph_create(): graph_id invalid" 77 : : " for lcore %u\n", lcore_id); 78 : : 79 : 0 : qconf->graph_id = graph_id; 80 : 0 : qconf->graph = rte_graph_lookup(qconf->name); 81 : : /* >8 End of graph initialization. */ 82 : 0 : if (!qconf->graph) 83 : 0 : rte_exit(EXIT_FAILURE, 84 : : "rte_graph_lookup(): graph %s not found\n", 85 : : qconf->name); 86 : : } 87 : : 88 : : /* Launch per-lcore init on every worker lcore */ 89 : 0 : rte_eal_mp_remote_launch(graph_walk_start, NULL, SKIP_MAIN); 90 : : 91 : : /* Accumulate and print stats on main until exit */ 92 : 0 : if (rte_graph_has_stats_feature() && app_graph_stats_enabled()) 93 : 0 : graph_stats_print(); 94 : : 95 : : return 0; 96 : : } 97 : : 98 : : static int 99 : 0 : ethdev_rx_to_tx_node_link(uint32_t lcore_id) 100 : : { 101 : : char name[RTE_NODE_NAMESIZE]; 102 : 0 : const char *next_node = name; 103 : : struct lcore_conf *qconf; 104 : : uint16_t queue, port_id; 105 : : rte_node_t rx_id; 106 : : int16_t txport; 107 : : int rc = 0; 108 : : 109 : : qconf = &lcore_conf[lcore_id]; 110 : : 111 : 0 : for (queue = 0; queue < qconf->n_rx_queue; ++queue) { 112 : 0 : port_id = qconf->rx_queue_list[queue].port_id; 113 : 0 : txport = ethdev_txport_by_rxport_get(port_id); 114 : 0 : if (txport >= 0) { 115 : 0 : rx_id = rte_node_from_name(qconf->rx_queue_list[queue].node_name); 116 : 0 : snprintf(name, sizeof(name), "ethdev_tx-%u", txport); 117 : 0 : rte_node_edge_update(rx_id, RTE_EDGE_ID_INVALID, &next_node, 1); 118 : 0 : rc = rte_node_ethdev_rx_next_update(rx_id, name); 119 : 0 : if (rc) 120 : 0 : goto exit; 121 : : } else { 122 : : rc = -EINVAL; 123 : 0 : goto exit; 124 : : } 125 : : } 126 : 0 : exit: 127 : 0 : return rc; 128 : : } 129 : : 130 : : 131 : : int 132 : 0 : usecase_l2fwd_configure(struct rte_node_ethdev_config *conf, uint16_t nb_confs, uint16_t nb_graphs) 133 : : { 134 : : uint32_t lcore_id; 135 : : int rc; 136 : : 137 : 0 : rc = rte_node_eth_config(conf, nb_confs, nb_graphs); 138 : 0 : if (rc) 139 : 0 : rte_exit(EXIT_FAILURE, "rte_node_eth_config: err=%d\n", rc); 140 : : 141 : 0 : for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { 142 : 0 : rc = ethdev_rx_to_tx_node_link(lcore_id); 143 : 0 : if (rc) 144 : 0 : rte_exit(EXIT_FAILURE, "rte_node_eth_config: err=%d\n", rc); 145 : : } 146 : : 147 : 0 : rc = l2fwd_pattern_configure(); 148 : 0 : if (rc) 149 : 0 : rte_exit(EXIT_FAILURE, "l2fwd_pattern_failure: err=%d\n", rc); 150 : : 151 : 0 : return rc; 152 : : }