DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
RTEIfaceSetup.hpp
Go to the documentation of this file.
1
8#ifndef DPDKLIBS_INCLUDE_DPDKLIBS_RTEIFACESETUP_HPP_
9#define DPDKLIBS_INCLUDE_DPDKLIBS_RTEIFACESETUP_HPP_
10
11#include "logging/Logging.hpp"
12
13#include <rte_eal.h>
14#include <rte_ethdev.h>
15
16#include <algorithm>
17#include <string>
18
19namespace dunedaq {
20namespace dpdklibs {
21namespace ifaceutils {
22
23#define RX_RING_SIZE 1024
24#define TX_RING_SIZE 1024
25
26#define NUM_MBUFS 8191
27#define MBUF_CACHE_SIZE 250
28
29#define PG_JUMBO_FRAME_LEN (9600 + RTE_ETHER_CRC_LEN + RTE_ETHER_HDR_LEN)
30#ifndef RTE_JUMBO_ETHER_MTU
31#define RTE_JUMBO_ETHER_MTU (PG_JUMBO_FRAME_LEN - RTE_ETHER_HDR_LEN - RTE_ETHER_CRC_LEN) /*< Ethernet MTU. */
32#endif
33
34static volatile uint8_t dpdk_quit_signal;
35
36static const struct rte_eth_conf iface_conf_default = {
37 .rxmode = {
38 .mtu = 9000,
39 .max_lro_pkt_size = 9000,
40 //.split_hdr_size = 0, // Deprecated in dpdk@22.11
41 .offloads = (RTE_ETH_RX_OFFLOAD_TIMESTAMP
42 | RTE_ETH_RX_OFFLOAD_IPV4_CKSUM
43 | RTE_ETH_RX_OFFLOAD_UDP_CKSUM),
44 },
45
46 .txmode = {
47 .offloads = (RTE_ETH_TX_OFFLOAD_MULTI_SEGS),
48 },
49};
50
51// Get number of available interfaces
52inline int
54 unsigned nb_ifaces = rte_eth_dev_count_avail();
55 TLOG() << "Available interfaces: " << nb_ifaces;
56 return nb_ifaces;
57}
58
59// Modifies Ethernet device configuration to multi-queue RSS with offload
60inline void
61iface_conf_rss_mode(struct rte_eth_conf& iface_conf, bool mode = false, bool offload = false)
62{
63 if (mode) {
64 iface_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_RSS;
65 if (offload) {
66 iface_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
67 }
68 } else {
69 iface_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_NONE;
70 }
71}
72
73// Enables RX in promiscuous mode for the Ethernet device.
74inline int
75iface_promiscuous_mode(std::uint16_t iface, bool mode = false)
76{
77 int retval = -1;
78 retval = rte_eth_promiscuous_get(iface);
79 TLOG() << "Before modification attempt, promiscuous mode is: " << retval;
80 if (mode) {
81 retval = rte_eth_promiscuous_enable(iface);
82 } else {
83 retval = rte_eth_promiscuous_disable(iface);
84 }
85 if (retval != 0) {
86 TLOG() << "Couldn't modify promiscuous mode of iface[" << iface << "]! Error code: " << retval;
87 }
88 retval = rte_eth_promiscuous_get(iface);
89 TLOG() << "New promiscuous mode of iface[" << iface << "] is: " << retval;
90 return retval;
91}
92
93// Get interface validity
94inline bool
95iface_valid(uint16_t iface)
96{
97 return rte_eth_dev_is_valid_port(iface);
98}
99
100inline void
101hex_digits_to_stream(std::ostringstream& ostrs, int value, char separator = ' ', char fill = '0', int digits = 2) {
102 ostrs << std::setfill(fill) << std::setw(digits) << std::hex << value << std::dec << separator;
103}
104
105// Get interface MAC address
106inline std::string
107get_iface_mac_str(uint16_t iface)
108{
109 int retval = -1;
110 struct rte_ether_addr mac_addr;
111 retval = rte_eth_macaddr_get(iface, &mac_addr);
112 if (retval != 0) {
113 TLOG() << "Failed to get MAC address of interface! Err id: " << retval;
114 return std::string("");
115 } else {
116 std::ostringstream ostrs;
117 hex_digits_to_stream(ostrs, (int)mac_addr.addr_bytes[0], ':');
118 hex_digits_to_stream(ostrs, (int)mac_addr.addr_bytes[1], ':');
119 hex_digits_to_stream(ostrs, (int)mac_addr.addr_bytes[2], ':');
120 hex_digits_to_stream(ostrs, (int)mac_addr.addr_bytes[3], ':');
121 hex_digits_to_stream(ostrs, (int)mac_addr.addr_bytes[4], ':');
122 hex_digits_to_stream(ostrs, (int)mac_addr.addr_bytes[5]);
123 std::string mac_str = ostrs.str();
124 mac_str.erase(std::remove(mac_str.begin(), mac_str.end(), ' '), mac_str.end());
125 return mac_str;
126 }
127}
128
129inline std::string
130get_iface_pci_str(uint16_t iface)
131{
132 std::string iface_pci_addr_str;
133 int retval = -1;
134 struct rte_eth_dev_info dev_info;
135 // Get interface info
136 retval = rte_eth_dev_info_get(iface, &dev_info);
137 if (retval != 0) {
138 TLOG() << "Error during getting device (iface " << iface << ") retval: " << retval;
139 } else if (dev_info.device) {
140 auto dev_name = rte_dev_name(dev_info.device);
141 iface_pci_addr_str = dev_name;
142 //TLOG() << "Dev name: " << dev_name;
143 //const auto bus = rte_dev_bus(dev_info.device);
144 //const auto bus_info = rte_dev_bus_info(dev_info.device);
145 //const auto dev_driver = rte_dev_driver(dev_info.device);
146 }
147 return iface_pci_addr_str;
148}
149
150inline int
151iface_reset(uint16_t iface)
152{
153 int retval = -1;
154 struct rte_eth_dev_info dev_info;
155
156 // Get interface validity
157 if (!rte_eth_dev_is_valid_port(iface)) {
158 TLOG() << "Specified interface " << iface << " is not valid in EAL!";
159 return retval;
160 }
161
162 // Carry out a reset of the interface
163 retval = rte_eth_dev_reset(iface);
164 if (retval != 0) {
165 TLOG() << "Error during resetting device (iface " << iface << ") retval: " << retval;
166 return retval;
167 }
168
169 return retval;
170}
171
172// inline int
173// iface_init(uint16_t iface, uint16_t rx_rings, uint16_t tx_rings,
174// std::map<int, std::unique_ptr<rte_mempool>>& mbuf_pool,
175// bool with_reset=false, bool with_mq_rss=false)
176// {
177// struct rte_eth_conf iface_conf = iface_conf_default;
178// uint16_t nb_rxd = RX_RING_SIZE;
179// uint16_t nb_txd = TX_RING_SIZE;
180// int retval = -1;
181// uint16_t q;
182// struct rte_eth_dev_info dev_info;
183// struct rte_eth_txconf txconf;
184
185// // Get interface validity
186// if (!rte_eth_dev_is_valid_port(iface)) {
187// TLOG() << "Specified interface " << iface << " is not valid in EAL!";
188// return retval;
189// }
190
191// // Get interface info
192// retval = rte_eth_dev_info_get(iface, &dev_info);
193// if (retval != 0) {
194// TLOG() << "Error during getting device (iface " << iface << ") retval: " << retval;
195// return retval;
196// }
197
198// // Carry out a reset of the interface
199// if (with_reset) {
200// retval = rte_eth_dev_reset(iface);
201// if (retval != 0) {
202// TLOG() << "Error during resetting device (iface " << iface << ") retval: " << retval;
203// return retval;
204// }
205// }
206
207// // Should we configure MQ RSS and offload?
208// if (with_mq_rss) {
209// iface_conf_rss_mode(iface_conf, true, true); // with_rss, with_offload
210// // RSS
211// if ((iface_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) != 0) {
212// TLOG() << "Ethdev port config prepared with RX RSS mq_mode!";
213// if ((iface_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH) != 0) {
214// TLOG() << "Ethdev port config prepared with RX RSS mq_mode with offloading is requested!";
215// }
216// }
217// }
218
219// // Configure the Ethernet interface
220// retval = rte_eth_dev_configure(iface, rx_rings, tx_rings, &iface_conf);
221// if (retval != 0)
222// return retval;
223
224// // Set MTU of interface
225// rte_eth_dev_set_mtu(iface, RTE_JUMBO_ETHER_MTU);
226// {
227// uint16_t mtu;
228// rte_eth_dev_get_mtu(iface, &mtu);
229// TLOG() << "Interface: " << iface << " MTU: " << mtu;
230// }
231
232// // Adjust RX/TX ring sizes
233// retval = rte_eth_dev_adjust_nb_rx_tx_desc(iface, &nb_rxd, &nb_txd);
234// if (retval != 0)
235// return retval;
236
237// // Allocate and set up RX queues for interface.
238// for (q = 0; q < rx_rings; q++) {
239// retval = rte_eth_rx_queue_setup(iface, q, nb_rxd, rte_eth_dev_socket_id(iface), NULL, mbuf_pool[q].get());
240// if (retval < 0)
241// return retval;
242// }
243
244// txconf = dev_info.default_txconf;
245// txconf.offloads = iface_conf.txmode.offloads;
246// // Allocate and set up TX queues for interface.
247// for (q = 0; q < tx_rings; q++) {
248// retval = rte_eth_tx_queue_setup(iface, q, nb_txd, rte_eth_dev_socket_id(iface), &txconf);
249// if (retval < 0)
250// return retval;
251// }
252
253// // Start the Ethernet interface.
254// retval = rte_eth_dev_start(iface);
255// if (retval < 0)
256// return retval;
257
258// // Display the interface MAC address.
259// struct rte_ether_addr addr;
260// retval = rte_eth_macaddr_get(iface, &addr);
261// if (retval != 0)
262// return retval;
263
264// return 0;
265// }
266
267} // namespace ifaceutils
268} // namespace dpdklibs
269} // namespace dunedaq
270
271#endif // DPDKLIBS_INCLUDE_DPDKLIBS_RTEIFACESETUP_HPP_
static void fill(const ResourceSet &rs, std::vector< const ResourceSetOR * > &rs_or, std::vector< const ResourceSetAND * > &rs_and, TestCircularDependency &cd_fuse)
#define TLOG(...)
Definition macro.hpp:22
std::string get_iface_mac_str(uint16_t iface)
void hex_digits_to_stream(std::ostringstream &ostrs, int value, char separator=' ', char fill='0', int digits=2)
int iface_promiscuous_mode(std::uint16_t iface, bool mode=false)
bool iface_valid(uint16_t iface)
std::string get_iface_pci_str(uint16_t iface)
static const struct rte_eth_conf iface_conf_default
static volatile uint8_t dpdk_quit_signal
int iface_reset(uint16_t iface)
void iface_conf_rss_mode(struct rte_eth_conf &iface_conf, bool mode=false, bool offload=false)
Including Qt Headers.