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