DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
dunedaq::dpdklibs::ealutils Namespace Reference

Functions

std::string get_mac_addr_str (const rte_ether_addr &addr)
void iface_conf_rss_mode (struct rte_eth_conf &iface_conf, bool mode=false, bool offload=false)
int iface_promiscuous_mode (std::uint16_t iface, bool mode=false)
int iface_init (uint16_t iface, uint16_t rx_rings, uint16_t tx_rings, uint16_t rx_ring_size, uint16_t tx_ring_size, std::map< int, std::unique_ptr< rte_mempool > > &mbuf_pool, bool with_reset=false, bool with_mq_rss=false, bool check_link_status=false)
std::unique_ptr< rte_mempool > get_mempool (const std::string &pool_name, int num_mbufs=NUM_MBUFS, int mbuf_cache_size=MBUF_CACHE_SIZE, int data_room_size=9800, int socket_id=0)
std::vector< const char * > construct_eal_argv (const std::vector< std::string > &std_argv)
void init_eal (int argc, const char *argv[])
void init_eal (const std::vector< std::string > &args)
int get_available_ifaces ()
int wait_for_lcores ()
void finish_eal ()

Variables

static volatile uint8_t dpdk_quit_signal
static const struct rte_eth_conf iface_conf_default

Function Documentation

◆ construct_eal_argv()

std::vector< const char * > dunedaq::dpdklibs::ealutils::construct_eal_argv ( const std::vector< std::string > & std_argv)

Definition at line 279 of file EALSetup.cpp.

280{
281 std::vector<const char*> vec_argv;
282 for (int i = 0; i < std_argv.size(); i++) {
283 vec_argv.insert(vec_argv.end(), std_argv[i].data());
284 }
285 return vec_argv;
286}

◆ finish_eal()

void dunedaq::dpdklibs::ealutils::finish_eal ( )

Definition at line 340 of file EALSetup.cpp.

341{
342 rte_eal_cleanup();
343}

◆ get_available_ifaces()

int dunedaq::dpdklibs::ealutils::get_available_ifaces ( )

Definition at line 317 of file EALSetup.cpp.

318{
319 // Check that there is an even number of interfaces to send/receive on
320 unsigned nb_ifaces;
321 nb_ifaces = rte_eth_dev_count_avail();
322 TLOG() << "Available interfaces: " << nb_ifaces;
323 return nb_ifaces;
324}
#define TLOG(...)
Definition macro.hpp:21

◆ get_mac_addr_str()

std::string dunedaq::dpdklibs::ealutils::get_mac_addr_str ( const rte_ether_addr & addr)

Definition at line 51 of file EALSetup.cpp.

52{
53 std::stringstream macstr;
54 macstr << std::hex << static_cast<int>(addr.addr_bytes[0]) << ":" << static_cast<int>(addr.addr_bytes[1]) << ":"
55 << static_cast<int>(addr.addr_bytes[2]) << ":" << static_cast<int>(addr.addr_bytes[3]) << ":"
56 << static_cast<int>(addr.addr_bytes[4]) << ":" << static_cast<int>(addr.addr_bytes[5]) << std::dec;
57 return macstr.str();
58}

◆ get_mempool()

std::unique_ptr< rte_mempool > dunedaq::dpdklibs::ealutils::get_mempool ( const std::string & pool_name,
int num_mbufs = NUM_MBUFS,
int mbuf_cache_size = MBUF_CACHE_SIZE,
int data_room_size = 9800,
int socket_id = 0 )

Definition at line 263 of file EALSetup.cpp.

264{
265 TLOG() << "get_mempool with: NUM_MBUFS = " << num_mbufs << " | MBUF_CACHE_SIZE = " << mbuf_cache_size
266 << " | data_room_size = " << data_room_size << " | SOCKET_ID = " << socket_id;
267
268 struct rte_mempool* mbuf_pool;
269 mbuf_pool = rte_pktmbuf_pool_create(pool_name.c_str(), num_mbufs, mbuf_cache_size, 0, data_room_size, socket_id);
270
271 if (mbuf_pool == NULL) {
272 // ers fatal
273 rte_exit(EXIT_FAILURE, "ERROR: Cannot create rte_mempool!\n");
274 }
275 return std::unique_ptr<rte_mempool>(mbuf_pool);
276}

◆ iface_conf_rss_mode()

void dunedaq::dpdklibs::ealutils::iface_conf_rss_mode ( struct rte_eth_conf & iface_conf,
bool mode = false,
bool offload = false )

Definition at line 62 of file EALSetup.cpp.

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}

◆ iface_init()

int dunedaq::dpdklibs::ealutils::iface_init ( uint16_t iface,
uint16_t rx_rings,
uint16_t tx_rings,
uint16_t rx_ring_size,
uint16_t tx_ring_size,
std::map< int, std::unique_ptr< rte_mempool > > & mbuf_pool,
bool with_reset = false,
bool with_mq_rss = false,
bool check_link_status = false )

Definition at line 95 of file EALSetup.cpp.

104{
105 struct rte_eth_conf iface_conf = iface_conf_default;
106 uint16_t nb_rxd = rx_ring_size;
107 uint16_t nb_txd = tx_ring_size;
108 int retval = -1;
109 uint16_t q;
110 struct rte_eth_dev_info dev_info;
111 struct rte_eth_txconf txconf;
112 struct rte_eth_link link;
113
114 // Get interface validity
115 if (!rte_eth_dev_is_valid_port(iface)) {
116 TLOG() << "Specified interface " << iface << " is not valid in EAL!";
117 throw InvalidEALPort(ERS_HERE, iface);
118 }
119
120 // Get interface info
121 if ((retval = rte_eth_dev_info_get(iface, &dev_info)) != 0) {
122 TLOG() << "Error during getting device (iface " << iface << ") retval: " << retval;
123 throw FailedToRetrieveInterfaceInfo(ERS_HERE, iface, retval);
124 }
125
126 TLOG() << "Iface " << iface << " RX Ring info :"
127 << " min " << dev_info.rx_desc_lim.nb_min << " max " << dev_info.rx_desc_lim.nb_max << " align "
128 << dev_info.rx_desc_lim.nb_align;
129
130 // Carry out a reset of the interface
131 if (with_reset) {
132 if ((retval = rte_eth_dev_reset(iface)) != 0) {
133 throw FailedToResetInterface(ERS_HERE, iface, retval);
134 }
135 }
136
137 // Should we configure MQ RSS and offload?
138 if (with_mq_rss) {
139 iface_conf_rss_mode(iface_conf, true, true); // with_rss, with_offload
140 // RSS
141 if ((iface_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) != 0) {
142 TLOG() << "Ethdev port config prepared with RX RSS mq_mode!";
143 if ((iface_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH) != 0) {
144 TLOG() << "Ethdev port config prepared with RX RSS mq_mode with offloading is requested!";
145 }
146 }
147 }
148
149 TLOG() << "Configuring Iface " << iface << " rx rings: " << rx_rings << ", tx rings " << tx_rings;
150
151 // Configure the Ethernet interface
152 if ((retval = rte_eth_dev_configure(iface, rx_rings, tx_rings, &iface_conf)) != 0) {
153 throw FailedToConfigureInterface(ERS_HERE, iface, "Device Configuration", retval);
154 }
155
156 // Set MTU of interface
157 rte_eth_dev_set_mtu(iface, RTE_JUMBO_ETHER_MTU);
158 {
159 uint16_t mtu;
160 rte_eth_dev_get_mtu(iface, &mtu);
161 TLOG() << "Interface: " << iface << " MTU: " << mtu;
162 }
163
164 // Set PTYPE parsing. RS FIXME: This function needs to be factorized, with overall better offloading control.
165 // On most Intel and Mellanox drivers, packet_type will automatically be set if:
166 // - the hardware supports RTE_ETH_RX_OFFLOAD_*PTYPE
167 // - and ptype RX parsing is enabled in the PMD
168 // Some PMDs require calling:
169 rte_eth_dev_set_ptypes(iface, RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK, NULL, 0);
170
171 // // Adjust RX/TX ring sizes
172 // retval = rte_eth_dev_adjust_nb_rx_tx_desc(iface, &nb_rxd, &nb_txd);
173 // if (retval != 0)
174 // return retval;
175
176 if ((retval = rte_eth_dev_adjust_nb_rx_tx_desc(iface, &nb_rxd, &nb_txd)) != 0) {
177 throw FailedToConfigureInterface(ERS_HERE, iface, "Adjust tx/rx descriptors", retval);
178 }
179
180 // Allocate and set up RX queues for interface.
181 for (q = 0; q < rx_rings; q++) {
182 // retval = rte_eth_rx_queue_setup(iface, q, nb_rxd, rte_eth_dev_socket_id(iface), NULL, mbuf_pool[q].get());
183 if ((retval = rte_eth_rx_queue_setup(iface, q, nb_rxd, rte_eth_dev_socket_id(iface), NULL, mbuf_pool[q].get())) <
184 0) {
185 // return retval;
186 throw FailedToConfigureInterface(ERS_HERE, iface, "Rx queues setup", retval);
187 }
188 }
189
190 txconf = dev_info.default_txconf;
191 txconf.offloads = iface_conf.txmode.offloads;
192
193 // These values influenced by Sec. 8.4.4 of https://doc.dpdk.org/guides-1.8/prog_guide/poll_mode_drv.html
194 txconf.tx_rs_thresh = 32;
195 txconf.tx_free_thresh = 32;
196 txconf.tx_thresh.wthresh = 0;
197
198 // Allocate and set up TX queues for interface.
199 for (q = 0; q < tx_rings; q++) {
200 if ((retval = rte_eth_tx_queue_setup(iface, q, nb_txd, rte_eth_dev_socket_id(iface), &txconf)) < 0) {
201 throw FailedToConfigureInterface(ERS_HERE, iface, "Tx queues setup", retval);
202 }
203 }
204
205 // Start the Ethernet interface.
206 if ((retval = rte_eth_dev_start(iface)) < 0) {
207 throw FailedToConfigureInterface(ERS_HERE, iface, "MAC address retrival", retval);
208 }
209
210 if ((retval = rte_eth_link_get(iface, &link)) != 0) {
211 throw FailedToRetrieveLinkStatus(ERS_HERE, iface, retval);
212 }
213
214 TLOG() << "Link: speed=" << link.link_speed << " duplex=" << link.link_duplex << " autoneg=" << link.link_autoneg
215 << " status=" << link.link_status;
216
217 if (check_link_status && link.link_status == 0) {
218 throw LinkOffline(ERS_HERE, iface);
219 }
220
221 // Display the interface MAC address.
222 struct rte_ether_addr addr;
223 if ((retval = rte_eth_macaddr_get(iface, &addr)) == 0) {
224 TLOG() << "MAC address: " << get_mac_addr_str(addr);
225 } else {
226 throw FailedToConfigureInterface(ERS_HERE, iface, "MAC address retrival", retval);
227 }
228
229 // Get interface info
230 if ((retval = rte_eth_dev_info_get(iface, &dev_info)) != 0) {
231 TLOG() << "Error during getting device (iface " << iface << ") retval: " << retval;
232 throw FailedToConfigureInterface(ERS_HERE, iface, "Device information retrival", retval);
233 }
234
235 TLOG() << "Iface[" << iface << "] Rx Ring info:"
236 << " min=" << dev_info.rx_desc_lim.nb_min << " max=" << dev_info.rx_desc_lim.nb_max
237 << " align=" << dev_info.rx_desc_lim.nb_align;
238 TLOG() << "Iface[" << iface << "] Tx Ring info:"
239 << " min=" << dev_info.rx_desc_lim.nb_min << " max=" << dev_info.rx_desc_lim.nb_max
240 << " align=" << dev_info.rx_desc_lim.nb_align;
241
242 for (size_t j = 0; j < dev_info.nb_rx_queues; j++) {
243
244 struct rte_eth_rxq_info queue_info;
245 int count;
246
247 retval = rte_eth_rx_queue_info_get(iface, j, &queue_info);
248 if (retval != 0)
249 continue;
250
251 count = rte_eth_rx_queue_count(iface, j);
252 TLOG() << "rx[" << j << "] descriptors=" << count << "/" << queue_info.nb_desc
253 << " scattered=" << (queue_info.scattered_rx ? "yes" : "no")
254 << " conf.drop_en=" << (queue_info.conf.rx_drop_en ? "yes" : "no")
255 << " conf.rx_deferred_start=" << (queue_info.conf.rx_deferred_start ? "yes" : "no")
256 << " rx_buf_size=" << queue_info.rx_buf_size;
257 }
258
259 return 0;
260}
#define ERS_HERE
#define RTE_JUMBO_ETHER_MTU
static const struct rte_eth_conf iface_conf_default
Definition EALSetup.cpp:35
void iface_conf_rss_mode(struct rte_eth_conf &iface_conf, bool mode=false, bool offload=false)
Definition EALSetup.cpp:62
std::string get_mac_addr_str(const rte_ether_addr &addr)
Definition EALSetup.cpp:51

◆ iface_promiscuous_mode()

int dunedaq::dpdklibs::ealutils::iface_promiscuous_mode ( std::uint16_t iface,
bool mode = false )

Definition at line 76 of file EALSetup.cpp.

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}

◆ init_eal() [1/2]

void dunedaq::dpdklibs::ealutils::init_eal ( const std::vector< std::string > & args)

Definition at line 307 of file EALSetup.cpp.

308{
309
310 std::vector<const char*> eal_argv = ealutils::construct_eal_argv(args);
311 const char** constructed_eal_argv = eal_argv.data();
312 int constructed_eal_argc = args.size();
313 ealutils::init_eal(constructed_eal_argc, constructed_eal_argv);
314}
std::vector< const char * > construct_eal_argv(const std::vector< std::string > &std_argv)
Definition EALSetup.cpp:279
void init_eal(int argc, const char *argv[])
Definition EALSetup.cpp:289

◆ init_eal() [2/2]

void dunedaq::dpdklibs::ealutils::init_eal ( int argc,
const char * argv[] )

Definition at line 289 of file EALSetup.cpp.

290{
291
292 std::stringstream ss;
293 for (size_t i(0); i < argc; ++i) {
294 ss << argv[i] << " ";
295 }
296 TLOG() << "EAL init arguments: " << ss.str();
297
298 // Init EAL
299 int ret = rte_eal_init(argc, (char**)argv);
300 if (ret < 0) {
301 rte_exit(EXIT_FAILURE, "ERROR: EAL initialization failed.\n");
302 }
303 TLOG() << "EAL initialized with provided parameters.";
304}

◆ wait_for_lcores()

int dunedaq::dpdklibs::ealutils::wait_for_lcores ( )

Definition at line 327 of file EALSetup.cpp.

328{
329 int lcore_id;
330 int ret = 0;
331 RTE_LCORE_FOREACH_WORKER(lcore_id)
332 {
333 // TLOG() << "Waiting for lcore[" << lcore_id << "] to finish packet processing.";
334 ret = rte_eal_wait_lcore(lcore_id);
335 }
336 return ret;
337}

Variable Documentation

◆ dpdk_quit_signal

volatile uint8_t dunedaq::dpdklibs::ealutils::dpdk_quit_signal
static

Definition at line 25 of file EALSetup.hpp.

◆ iface_conf_default

const struct rte_eth_conf dunedaq::dpdklibs::ealutils::iface_conf_default
static
Initial value:
= {
.rxmode = {
.mtu = 9000,
.max_lro_pkt_size = 9000,
.offloads = (RTE_ETH_RX_OFFLOAD_TIMESTAMP
| RTE_ETH_RX_OFFLOAD_IPV4_CKSUM
| RTE_ETH_RX_OFFLOAD_UDP_CKSUM),
},
.txmode = {
.offloads = (RTE_ETH_TX_OFFLOAD_MULTI_SEGS),
},
}

Definition at line 35 of file EALSetup.cpp.