Skip to content

Commit 37745fb

Browse files
authored
Merge pull request #106 from DUNE-DAQ/feature/dpdk_multiproc
Moved EALSetup code to source file
2 parents eb148c0 + a40a4f2 commit 37745fb

File tree

3 files changed

+335
-270
lines changed

3 files changed

+335
-270
lines changed

include/dpdklibs/EALSetup.hpp

Lines changed: 13 additions & 260 deletions
Original file line numberDiff line numberDiff line change
@@ -19,288 +19,41 @@ namespace dunedaq {
1919
namespace dpdklibs {
2020
namespace ealutils {
2121

22-
#define RX_RING_SIZE 1024
23-
#define TX_RING_SIZE 1024
2422

2523
#define NUM_MBUFS 8191
2624
#define MBUF_CACHE_SIZE 250
2725

28-
#define PG_JUMBO_FRAME_LEN (9600 + RTE_ETHER_CRC_LEN + RTE_ETHER_HDR_LEN)
29-
#ifndef RTE_JUMBO_ETHER_MTU
30-
#define RTE_JUMBO_ETHER_MTU (PG_JUMBO_FRAME_LEN - RTE_ETHER_HDR_LEN - RTE_ETHER_CRC_LEN) /*< Ethernet MTU. */
31-
#endif
32-
3326
static volatile uint8_t dpdk_quit_signal;
3427

35-
static const struct rte_eth_conf iface_conf_default = {
36-
.rxmode = {
37-
.mtu = 9000,
38-
.max_lro_pkt_size = 9000,
39-
//.split_hdr_size = 0, // deprecated in [email protected]
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-
};
49-
50-
51-
std::string get_mac_addr_str(const rte_ether_addr& addr) {
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-
}
56-
28+
std::string get_mac_addr_str(const rte_ether_addr& addr);
5729

5830
// Modifies Ethernet device configuration to multi-queue RSS with offload
59-
inline void
60-
iface_conf_rss_mode(struct rte_eth_conf& iface_conf, bool mode = false, bool offload = false)
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-
}
31+
void iface_conf_rss_mode(struct rte_eth_conf& iface_conf, bool mode = false, bool offload = false);
7132

7233
// Enables RX in promiscuous mode for the Ethernet device.
73-
inline int
74-
iface_promiscuous_mode(std::uint16_t iface, bool mode = false)
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-
}
91-
34+
int iface_promiscuous_mode(std::uint16_t iface, bool mode = false);
9235

93-
94-
inline int
95-
iface_init(uint16_t iface, uint16_t rx_rings, uint16_t tx_rings,
36+
int iface_init(uint16_t iface, uint16_t rx_rings, uint16_t tx_rings,
9637
uint16_t rx_ring_size, uint16_t tx_ring_size,
9738
std::map<int, std::unique_ptr<rte_mempool>>& mbuf_pool,
98-
bool with_reset=false, bool with_mq_rss=false)
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-
uint16_t nb_rxd = rx_ring_size;
104-
uint16_t nb_txd = tx_ring_size;
105-
int retval = -1;
106-
uint16_t q;
107-
struct rte_eth_dev_info dev_info;
108-
struct rte_eth_txconf txconf;
109-
110-
// Get interface validity
111-
if (!rte_eth_dev_is_valid_port(iface)) {
112-
TLOG() << "Specified interface " << iface << " is not valid in EAL!";
113-
return retval;
114-
}
115-
116-
// Get interface info
117-
retval = rte_eth_dev_info_get(iface, &dev_info);
118-
if (retval != 0) {
119-
TLOG() << "Error during getting device (iface " << iface << ") retval: " << retval;
120-
return retval;
121-
}
122-
123-
TLOG() << "Iface " << iface << " RX Ring info :"
124-
<< " min " << dev_info.rx_desc_lim.nb_min
125-
<< " max " << dev_info.rx_desc_lim.nb_max
126-
<< " align " << dev_info.rx_desc_lim.nb_align
127-
;
128-
129-
// Carry out a reset of the interface
130-
if (with_reset) {
131-
retval = rte_eth_dev_reset(iface);
132-
if (retval != 0) {
133-
TLOG() << "Resetting device (iface " << iface << ") failed. Retval: " << 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-
// Configure the Ethernet interface
150-
retval = rte_eth_dev_configure(iface, rx_rings, tx_rings, &iface_conf);
151-
if (retval != 0)
152-
return retval;
153-
154-
// Set MTU of interface
155-
rte_eth_dev_set_mtu(iface, RTE_JUMBO_ETHER_MTU);
156-
{
157-
uint16_t mtu;
158-
rte_eth_dev_get_mtu(iface, &mtu);
159-
TLOG() << "Interface: " << iface << " MTU: " << mtu;
160-
}
161-
162-
// Adjust RX/TX ring sizes
163-
retval = rte_eth_dev_adjust_nb_rx_tx_desc(iface, &nb_rxd, &nb_txd);
164-
if (retval != 0)
165-
return retval;
39+
bool with_reset=false, bool with_mq_rss=false);
16640

167-
// Allocate and set up RX queues for interface.
168-
for (q = 0; q < rx_rings; q++) {
169-
retval = rte_eth_rx_queue_setup(iface, q, nb_rxd, rte_eth_dev_socket_id(iface), NULL, mbuf_pool[q].get());
170-
if (retval < 0)
171-
return retval;
172-
}
173-
174-
txconf = dev_info.default_txconf;
175-
txconf.offloads = iface_conf.txmode.offloads;
176-
177-
// These values influenced by Sec. 8.4.4 of https://doc.dpdk.org/guides-1.8/prog_guide/poll_mode_drv.html
178-
txconf.tx_rs_thresh = 32;
179-
txconf.tx_free_thresh = 32;
180-
txconf.tx_thresh.wthresh = 0;
181-
182-
// Allocate and set up TX queues for interface.
183-
for (q = 0; q < tx_rings; q++) {
184-
retval = rte_eth_tx_queue_setup(iface, q, nb_txd, rte_eth_dev_socket_id(iface), &txconf);
185-
if (retval < 0)
186-
return retval;
187-
}
188-
189-
// Start the Ethernet interface.
190-
retval = rte_eth_dev_start(iface);
191-
if (retval < 0)
192-
return retval;
193-
194-
// Display the interface MAC address.
195-
struct rte_ether_addr addr;
196-
retval = rte_eth_macaddr_get(iface, &addr);
197-
if (retval == 0) {
198-
TLOG() << "MAC address: " << get_mac_addr_str(addr);
199-
} else {
200-
return retval;
201-
}
202-
203-
// Get interface info
204-
retval = rte_eth_dev_info_get(iface, &dev_info);
205-
if (retval != 0) {
206-
TLOG() << "Error during getting device (iface " << iface << ") retval: " << retval;
207-
return retval;
208-
}
209-
210-
TLOG() << "Iface[" << iface << "] Rx Ring info:"
211-
<< " min=" << dev_info.rx_desc_lim.nb_min
212-
<< " max=" << dev_info.rx_desc_lim.nb_max
213-
<< " align=" << dev_info.rx_desc_lim.nb_align;
214-
TLOG() << "Iface[" << iface << "] Tx Ring info:"
215-
<< " min=" << dev_info.rx_desc_lim.nb_min
216-
<< " max=" << dev_info.rx_desc_lim.nb_max
217-
<< " align=" << dev_info.rx_desc_lim.nb_align;
218-
219-
for (size_t j = 0; j < dev_info.nb_rx_queues; j++) {
220-
221-
struct rte_eth_rxq_info queue_info;
222-
int count;
223-
224-
retval = rte_eth_rx_queue_info_get(iface, j, &queue_info);
225-
if (retval != 0)
226-
break;
227-
228-
count = rte_eth_rx_queue_count(iface, j);
229-
TLOG() << "rx[" << j << "] descriptors=" << count << "/" << queue_info.nb_desc
230-
<< " scattered=" << (queue_info.scattered_rx ? "yes" : "no")
231-
<< " conf.drop_en=" << (queue_info.conf.rx_drop_en ? "yes" : "no")
232-
<< " conf.rx_deferred_start=" << (queue_info.conf.rx_deferred_start ? "yes" : "no")
233-
<< " rx_buf_size=" << queue_info.rx_buf_size;
234-
}
235-
236-
return 0;
237-
}
238-
239-
std::unique_ptr<rte_mempool>
240-
get_mempool(const std::string& pool_name,
41+
std::unique_ptr<rte_mempool> get_mempool(const std::string& pool_name,
24142
int num_mbufs=NUM_MBUFS, int mbuf_cache_size=MBUF_CACHE_SIZE,
242-
int data_room_size=9800, int socket_id=0) {
243-
TLOG() << "get_mempool with: NUM_MBUFS = " << num_mbufs
244-
<< " | MBUF_CACHE_SIZE = " << mbuf_cache_size
245-
<< " | data_room_size = " << data_room_size
246-
<< " | SOCKET_ID = " << socket_id;
247-
248-
struct rte_mempool *mbuf_pool;
249-
mbuf_pool = rte_pktmbuf_pool_create(pool_name.c_str(), num_mbufs,
250-
mbuf_cache_size, 0, data_room_size,
251-
socket_id);
252-
253-
if (mbuf_pool == NULL) {
254-
// ers fatal
255-
rte_exit(EXIT_FAILURE, "ERROR: Cannot create rte_mempool!\n");
256-
}
257-
return std::unique_ptr<rte_mempool>(mbuf_pool);
258-
}
43+
int data_room_size=9800, int socket_id=0);
25944

260-
std::vector<char*>
261-
construct_eal_argv(std::vector<std::string> &std_argv){
262-
std::vector<char*> vec_argv;
263-
for (int i=0; i < std_argv.size() ; i++){
264-
vec_argv.insert(vec_argv.end(), std_argv[i].data());
265-
}
266-
return vec_argv;
267-
}
45+
std::vector<const char*> construct_eal_argv(const std::vector<std::string> &std_argv);
26846

47+
void init_eal(int argc, const char* argv[]);
26948

270-
void
271-
init_eal(int argc, char* argv[]) {
49+
void init_eal( const std::vector<std::string>& args );
27250

273-
// Init EAL
274-
int ret = rte_eal_init(argc, argv);
275-
if (ret < 0) {
276-
rte_exit(EXIT_FAILURE, "ERROR: EAL initialization failed.\n");
277-
}
278-
TLOG() << "EAL initialized with provided parameters.";
279-
}
51+
int get_available_ifaces();
28052

281-
int
282-
get_available_ifaces() {
283-
// Check that there is an even number of interfaces to send/receive on
284-
unsigned nb_ifaces;
285-
nb_ifaces = rte_eth_dev_count_avail();
286-
TLOG() << "Available interfaces: " << nb_ifaces;
287-
return nb_ifaces;
288-
}
53+
int wait_for_lcores();
28954

290-
int
291-
wait_for_lcores() {
292-
int lcore_id;
293-
int ret = 0;
294-
RTE_LCORE_FOREACH_WORKER(lcore_id) {
295-
//TLOG() << "Waiting for lcore[" << lcore_id << "] to finish packet processing.";
296-
ret = rte_eal_wait_lcore(lcore_id);
297-
}
298-
return ret;
299-
}
55+
void finish_eal();
30056

301-
void finish_eal() {
302-
rte_eal_cleanup();
303-
}
30457

30558
} // namespace ealutils
30659
} // namespace dpdklibs

plugins/NICReceiver.cpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -148,16 +148,7 @@ NICReceiver::do_configure(const data_t& args)
148148
}
149149
}
150150

151-
std::stringstream ss;
152-
for( const auto& arg : eal_args) {
153-
ss << arg << " ";
154-
}
155-
TLOG() << "EAL Init arguments: " << ss.str();
156-
157-
std::vector<char*> eal_argv = ealutils::construct_eal_argv(eal_args);
158-
char** constructed_eal_argv = eal_argv.data();
159-
int constructed_eal_argc = eal_args.size();
160-
ealutils::init_eal(constructed_eal_argc, constructed_eal_argv);
151+
ealutils::init_eal(eal_args);
161152

162153
// Get available Interfaces from EAL
163154
auto available_ifaces = ifaceutils::get_num_available_ifaces();

0 commit comments

Comments
 (0)