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 281 of file EALSetup.cpp.

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

◆ finish_eal()

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

Definition at line 337 of file EALSetup.cpp.

337 {
338 rte_eal_cleanup();
339}

◆ get_available_ifaces()

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

Definition at line 318 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:22

◆ 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.

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

◆ 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 260 of file EALSetup.cpp.

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

◆ 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 60 of file EALSetup.cpp.

61{
62 if (mode) {
63 iface_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_RSS;
64 if (offload) {
65 iface_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
66 }
67 } else {
68 iface_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_NONE;
69 }
70}

◆ 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.

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

75{
76 int retval = -1;
77 retval = rte_eth_promiscuous_get(iface);
78 TLOG() << "Before modification attempt, promiscuous mode is: " << retval;
79 if (mode) {
80 retval = rte_eth_promiscuous_enable(iface);
81 } else {
82 retval = rte_eth_promiscuous_disable(iface);
83 }
84 if (retval != 0) {
85 TLOG() << "Couldn't modify promiscuous mode of iface[" << iface << "]! Error code: " << retval;
86 }
87 retval = rte_eth_promiscuous_get(iface);
88 TLOG() << "New promiscuous mode of iface[" << iface << "] is: " << retval;
89 return retval;
90}

◆ init_eal() [1/2]

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

Definition at line 309 of file EALSetup.cpp.

309 {
310
311 std::vector<const char*> eal_argv = ealutils::construct_eal_argv(args);
312 const char** constructed_eal_argv = eal_argv.data();
313 int constructed_eal_argc = args.size();
314 ealutils::init_eal(constructed_eal_argc, constructed_eal_argv);
315}

◆ init_eal() [2/2]

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

Definition at line 292 of file EALSetup.cpp.

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

◆ wait_for_lcores()

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

Definition at line 327 of file EALSetup.cpp.

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

Variable Documentation

◆ dpdk_quit_signal

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

Definition at line 26 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.

35 {
36 .rxmode = {
37 .mtu = 9000,
38 .max_lro_pkt_size = 9000,
39 //.split_hdr_size = 0, // deprecated in dpdk@22.10
40 .offloads = (RTE_ETH_RX_OFFLOAD_TIMESTAMP
41 | RTE_ETH_RX_OFFLOAD_IPV4_CKSUM
42 | RTE_ETH_RX_OFFLOAD_UDP_CKSUM),
43 },
44
45 .txmode = {
46 .offloads = (RTE_ETH_TX_OFFLOAD_MULTI_SEGS),
47 },
48};