aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/x300
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2019-12-02 23:06:39 -0800
committerBrent Stapleton <brent.stapleton@ettus.com>2019-12-20 16:32:22 -0800
commit4547f2de85f0d8b258a89cea71af774fce8616b7 (patch)
treed1239e074c5a35b449638a34aa3a6f74a53adfbb /host/lib/usrp/x300
parent4e38eef817813c1bbd8a9cf972e4cf0134d24308 (diff)
downloaduhd-4547f2de85f0d8b258a89cea71af774fce8616b7.tar.gz
uhd-4547f2de85f0d8b258a89cea71af774fce8616b7.tar.bz2
uhd-4547f2de85f0d8b258a89cea71af774fce8616b7.zip
x300,mpmd: Enable DPDK
x300: - Remove obsolete variables from x300_eth_mgr and X300 motherboard components - Added some documentation / comments - Use constrained device args in more places - Enables the use of use_dpdk=1 - Switches between regular (kernel-based) and DPDK UDP mpmd: - Merge link_if_ctrl for udp and dpdk_udp - Update cmake options
Diffstat (limited to 'host/lib/usrp/x300')
-rw-r--r--host/lib/usrp/x300/CMakeLists.txt4
-rw-r--r--host/lib/usrp/x300/x300_eth_mgr.cpp152
-rw-r--r--host/lib/usrp/x300/x300_eth_mgr.hpp23
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp3
-rw-r--r--host/lib/usrp/x300/x300_impl.hpp1
5 files changed, 79 insertions, 104 deletions
diff --git a/host/lib/usrp/x300/CMakeLists.txt b/host/lib/usrp/x300/CMakeLists.txt
index 1bd71dab4..b00ee357c 100644
--- a/host/lib/usrp/x300/CMakeLists.txt
+++ b/host/lib/usrp/x300/CMakeLists.txt
@@ -35,4 +35,8 @@ if(ENABLE_X300)
${CMAKE_CURRENT_SOURCE_DIR}/x300_prop_tree.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cdecode.c
)
+
+ if(ENABLE_DPDK)
+ add_definitions(-DHAVE_DPDK)
+ endif(ENABLE_DPDK)
endif(ENABLE_X300)
diff --git a/host/lib/usrp/x300/x300_eth_mgr.cpp b/host/lib/usrp/x300/x300_eth_mgr.cpp
index 7177032c6..fd826e484 100644
--- a/host/lib/usrp/x300/x300_eth_mgr.cpp
+++ b/host/lib/usrp/x300/x300_eth_mgr.cpp
@@ -7,6 +7,7 @@
#include "x300_eth_mgr.hpp"
#include "x300_claim.hpp"
#include "x300_defaults.hpp"
+#include "x300_device_args.hpp"
#include "x300_fw_common.h"
#include "x300_mb_eeprom.hpp"
#include "x300_mb_eeprom_iface.hpp"
@@ -17,16 +18,17 @@
#include <uhd/transport/udp_constants.hpp>
#include <uhd/transport/udp_simple.hpp>
#include <uhd/transport/udp_zero_copy.hpp>
+#include <uhd/utils/algorithm.hpp>
#include <uhd/utils/byteswap.hpp>
#include <uhdlib/rfnoc/device_id.hpp>
#include <uhdlib/rfnoc/rfnoc_common.hpp>
#include <uhdlib/transport/udp_boost_asio_link.hpp>
#include <uhdlib/transport/udp_common.hpp>
#include <uhdlib/usrp/cores/i2c_core_100_wb32.hpp>
-//#ifdef HAVE_DPDK
-//# include <uhdlib/transport/dpdk_simple.hpp>
-//# include <uhdlib/transport/dpdk_zero_copy.hpp>
-//#endif
+#ifdef HAVE_DPDK
+# include <uhdlib/transport/dpdk_simple.hpp>
+# include <uhdlib/transport/udp_dpdk_link.hpp>
+#endif
#include <boost/asio.hpp>
#include <string>
@@ -69,42 +71,41 @@ constexpr size_t MAX_RATE_1GIGE = (size_t)( // bytes/s
/******************************************************************************
* Static Methods
*****************************************************************************/
-eth_manager::udp_simple_factory_t eth_manager::x300_get_udp_factory(
- const device_addr_t& args)
+eth_manager::udp_simple_factory_t eth_manager::x300_get_udp_factory(const bool use_dpdk)
{
udp_simple_factory_t udp_make_connected = udp_simple::make_connected;
- if (args.has_key("use_dpdk")) {
-//#ifdef HAVE_DPDK
-// udp_make_connected = [](const std::string& addr, const std::string& port) {
-// auto& ctx = uhd::transport::uhd_dpdk_ctx::get();
-// return dpdk_simple::make_connected(ctx, addr, port);
-// };
-//#else
+ if (use_dpdk) {
+#ifdef HAVE_DPDK
+ udp_make_connected = [](const std::string& addr, const std::string& port) {
+ return dpdk_simple::make_connected(addr, port);
+ };
+#else
UHD_LOG_WARNING(
"DPDK", "Detected use_dpdk argument, but DPDK support not built in.");
-//#endif
+#endif
}
return udp_make_connected;
}
device_addrs_t eth_manager::find(const device_addr_t& hint)
{
+ x300_device_args_t hint_args;
+ hint_args.parse(hint);
+
udp_simple_factory_t udp_make_broadcast = udp_simple::make_broadcast;
- udp_simple_factory_t udp_make_connected = x300_get_udp_factory(hint);
+ udp_simple_factory_t udp_make_connected =
+ x300_get_udp_factory(hint_args.get_use_dpdk());
#ifdef HAVE_DPDK
- if (hint.has_key("use_dpdk")) {
-// auto& dpdk_ctx = uhd::transport::uhd_dpdk_ctx::get();
-// if (not dpdk_ctx.is_init_done()) {
-// dpdk_ctx.init(hint);
-// }
-// udp_make_broadcast = [](const std::string& addr, const std::string& port) {
-// auto& ctx = uhd::transport::uhd_dpdk_ctx::get();
-// return dpdk_simple::make_broadcast(ctx, addr, port);
-// };
+ if (hint_args.get_use_dpdk()) {
+ auto dpdk_ctx = uhd::transport::dpdk::dpdk_ctx::get();
+ if (not dpdk_ctx->is_init_done()) {
+ dpdk_ctx->init(hint);
+ }
+ udp_make_broadcast = dpdk_simple::make_broadcast;
}
#endif
- udp_simple::sptr comm =
- udp_make_broadcast(hint["addr"], BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT));
+ udp_simple::sptr comm = udp_make_broadcast(
+ hint_args.get_first_addr(), BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT));
// load request struct
x300_fw_comms_t request = x300_fw_comms_t();
@@ -177,9 +178,8 @@ device_addrs_t eth_manager::find(const device_addr_t& hint)
/******************************************************************************
* Structors
*****************************************************************************/
-eth_manager::eth_manager(const x300_device_args_t& args,
- uhd::property_tree::sptr tree,
- const uhd::fs_path& root_path)
+eth_manager::eth_manager(
+ const x300_device_args_t& args, uhd::property_tree::sptr, const uhd::fs_path&)
: _args(args)
{
UHD_ASSERT_THROW(!args.get_first_addr().empty());
@@ -201,10 +201,7 @@ eth_manager::eth_manager(const x300_device_args_t& args,
_local_device_ids.push_back(device_id);
eth_conns[device_id] = init;
- _x300_make_udp_connected = x300_get_udp_factory(dev_addr);
-
- tree->create<double>(root_path / "link_max_rate").set(10e9);
- _tree = tree->subtree(root_path);
+ _x300_make_udp_connected = x300_get_udp_factory(args.get_use_dpdk());
}
both_links_t eth_manager::get_links(link_type_t link_type,
@@ -213,12 +210,13 @@ both_links_t eth_manager::get_links(link_type_t link_type,
const sep_id_t& /*remote_epid*/,
const device_addr_t& link_args)
{
- if (std::find(_local_device_ids.cbegin(), _local_device_ids.cend(), local_device_id)
- == _local_device_ids.cend()) {
- throw uhd::runtime_error(
- std::string("[X300] Cannot create Ethernet link through local device ID ")
+ if (!uhd::has(_local_device_ids, local_device_id)) {
+ const std::string err_msg =
+ std::string("Cannot create Ethernet link through local device ID ")
+ std::to_string(local_device_id)
- + ", no such device associated with this motherboard!");
+ + ", no such device associated with this motherboard!";
+ UHD_LOG_ERROR("X300", err_msg);
+ throw uhd::runtime_error(err_msg);
}
// FIXME: We now need to properly associate local_device_id with the right
// entry in eth_conn. We should probably do the load balancing elsewhere,
@@ -236,56 +234,6 @@ both_links_t eth_manager::get_links(link_type_t link_type,
default_buff_args.send_frame_size = std::min(send_mtu, ETH_MSG_FRAME_SIZE);
default_buff_args.recv_frame_size = std::min(recv_mtu, ETH_MSG_FRAME_SIZE);
- if (_args.get_use_dpdk()) {
-//#ifdef HAVE_DPDK
- // auto& dpdk_ctx = uhd::transport::uhd_dpdk_ctx::get();
-
-// default_buff_args.num_recv_frames = ETH_MSG_NUM_FRAMES;
-// default_buff_args.num_send_frames = ETH_MSG_NUM_FRAMES;
-// if (link_type == link_type_t::CTRL) {
-//// Increasing number of recv frames here because ctrl_iface uses it
-//// to determine how many control packets can be in flight before it
-//// must wait for an ACK
-// default_buff_args.num_recv_frames =
-// uhd::rfnoc::CMD_FIFO_SIZE / uhd::rfnoc::MAX_CMD_PKT_SIZE;
-//} else if (xport_type == uhd::transport::link_type_t::TX_DATA) {
-// size_t default_frame_size = conn.link_rate == MAX_RATE_1GIGE
-//? GE_DATA_FRAME_SEND_SIZE
-//: XGE_DATA_FRAME_SEND_SIZE;
-// default_buff_args.send_frame_size = args.cast<size_t>(
-//"send_frame_size", std::min(default_frame_size, send_mtu));
-// default_buff_args.num_send_frames =
-// args.cast<size_t>("num_send_frames", default_buff_args.num_send_frames);
-// default_buff_args.send_buff_size = args.cast<size_t>("send_buff_size", 0);
-//} else if (xport_type == uhd::transport::link_type_t::RX_DATA) {
-// size_t default_frame_size = conn.link_rate == MAX_RATE_1GIGE
-//? GE_DATA_FRAME_RECV_SIZE
-//: XGE_DATA_FRAME_RECV_SIZE;
-// default_buff_args.recv_frame_size = args.cast<size_t>(
-//"recv_frame_size", std::min(default_frame_size, recv_mtu));
-// default_buff_args.num_recv_frames =
-// args.cast<size_t>("num_recv_frames", default_buff_args.num_recv_frames);
-// default_buff_args.recv_buff_size = args.cast<size_t>("recv_buff_size", 0);
-//}
-
-// int dpdk_port_id = dpdk_ctx.get_route(conn.addr);
-// if (dpdk_port_id < 0) {
-// throw uhd::runtime_error(
-//"Could not find a DPDK port with route to " + conn.addr);
-//}
-// auto recv = transport::dpdk_zero_copy::make(dpdk_ctx,
-//(const unsigned int)dpdk_port_id,
-// conn.addr,
-// BOOST_STRINGIZE(X300_VITA_UDP_PORT),
-//"0",
-// default_buff_args,
-// uhd::device_addr_t());
-
-//#else
- UHD_LOG_WARNING("X300", "Cannot create DPDK transport, falling back to UDP");
-//#endif
- }
-
// Buffering is done in the socket buffers, so size them relative to
// the link rate
link_params_t default_link_params;
@@ -315,7 +263,19 @@ both_links_t eth_manager::get_links(link_type_t link_type,
link_params.num_send_frames = std::max(uhd::rfnoc::MIN_NUM_FRAMES, link_params.num_send_frames);
link_params.num_recv_frames = std::max(uhd::rfnoc::MIN_NUM_FRAMES, link_params.num_recv_frames);
+ // Dummy variables for populating the return tuple
size_t recv_buff_size, send_buff_size;
+ if (_args.get_use_dpdk()) {
+#ifdef HAVE_DPDK
+ auto link = uhd::transport::udp_dpdk_link::make(
+ conn.addr, BOOST_STRINGIZE(X300_VITA_UDP_PORT), link_params);
+ return std::make_tuple(link, send_buff_size, link, recv_buff_size, true);
+#else
+ UHD_LOG_WARNING("X300", "Cannot create DPDK transport, falling back to UDP");
+#endif
+ }
+
+ // No DPDK, then return regular/kernel UDP
auto link = uhd::transport::udp_boost_asio_link::make(conn.addr,
BOOST_STRINGIZE(X300_VITA_UDP_PORT),
link_params,
@@ -333,11 +293,10 @@ wb_iface::sptr eth_manager::get_ctrl_iface()
get_pri_eth().addr, BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)));
}
+// - Populates _max_frame_sizes
void eth_manager::init_link(
const mboard_eeprom_t& mb_eeprom, const std::string& loaded_fpga_image)
{
- double link_max_rate = 0.0;
-
// Discover ethernet interfaces on the device
discover_eth(mb_eeprom, loaded_fpga_image);
@@ -392,6 +351,8 @@ void eth_manager::init_link(
UHD_LOGGER_ERROR("X300") << e.what();
}
+ // Check actual frame sizes against user-requested frame sizes, and print
+ // warnings if they don't match
if ((recv_args.has_key("recv_frame_size"))
&& (req_max_frame_size.recv_frame_size > _max_frame_sizes.recv_frame_size)) {
UHD_LOGGER_WARNING("X300")
@@ -416,11 +377,10 @@ void eth_manager::init_link(
<< "UHD will use the auto-detected max frame size for this connection.";
}
- // Check frame sizes
+ // Check actual frame sizes against detected frame sizes, and print
+ // warnings if they don't match
for (auto conn_pair : eth_conns) {
auto conn = conn_pair.second;
- link_max_rate += conn.link_rate;
-
size_t rec_send_frame_size = conn.link_rate == MAX_RATE_1GIGE
? GE_DATA_FRAME_SEND_SIZE
: XGE_DATA_FRAME_SEND_SIZE;
@@ -452,10 +412,6 @@ void eth_manager::init_link(
"argument.";
}
}
-
- _tree->create<size_t>("mtu/recv").set(_max_frame_sizes.recv_frame_size);
- _tree->create<size_t>("mtu/send").set(_max_frame_sizes.send_frame_size);
- _tree->access<double>("link_max_rate").set(link_max_rate);
}
size_t eth_manager::get_mtu(uhd::direction_t dir)
@@ -468,7 +424,7 @@ size_t eth_manager::get_mtu(uhd::direction_t dir)
void eth_manager::discover_eth(
const mboard_eeprom_t mb_eeprom, const std::string& loaded_fpga_image)
{
- udp_simple_factory_t udp_make_connected = x300_get_udp_factory(_args.get_orig_args());
+ udp_simple_factory_t udp_make_connected = x300_get_udp_factory(_args.get_use_dpdk());
// Load all valid, non-duplicate IP addrs
std::vector<std::string> ip_addrs{_args.get_first_addr()};
if (not _args.get_second_addr().empty()
diff --git a/host/lib/usrp/x300/x300_eth_mgr.hpp b/host/lib/usrp/x300/x300_eth_mgr.hpp
index 1f4013e17..19b6064dd 100644
--- a/host/lib/usrp/x300/x300_eth_mgr.hpp
+++ b/host/lib/usrp/x300/x300_eth_mgr.hpp
@@ -99,7 +99,13 @@ private:
return eth_conns.at(_local_device_ids.at(0));
}
- static udp_simple_factory_t x300_get_udp_factory(const device_addr_t& args);
+ //! Create a factory function for UDP traffic
+ //
+ // \note This is static rather than local to x300_eth_mgr.cpp to get access
+ // to udp_simple_factory_t
+ // \param use_dpdk If true, use a DPDK transport instead of a regular UDP
+ // transport
+ static udp_simple_factory_t x300_get_udp_factory(const bool use_dpdk);
/*!
* Automatically determine the maximum frame size available by sending a UDP packet
@@ -109,15 +115,22 @@ private:
frame_size_t determine_max_frame_size(
const std::string& addr, const frame_size_t& user_mtu);
- // Discover the ethernet connections per motherboard
+ //! Discover the ethernet connections per motherboard
+ //
+ // - Gets called during init_link()
+ // - Populates eth_conn
+ // - Populates _local_device_ids
+ //
+ // \throws uhd::runtime_error if no Ethernet connections can be found
void discover_eth(
const uhd::usrp::mboard_eeprom_t mb_eeprom, const std::string& loaded_fpga_image);
-
+ /**************************************************************************
+ * Attributes
+ *************************************************************************/
+ // Cache the initial device args that brought up this motherboard
const x300_device_args_t _args;
- uhd::property_tree::sptr _tree;
-
udp_simple_factory_t _x300_make_udp_connected;
std::map<uhd::rfnoc::device_id_t, x300_eth_conn_t> eth_conns;
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index 636202d33..273485577 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -23,6 +23,9 @@
#include <chrono>
#include <fstream>
#include <thread>
+#ifdef HAVE_DPDK
+# include <uhdlib/transport/dpdk/common.hpp>
+#endif
uhd::uart_iface::sptr x300_make_uart_iface(uhd::wb_iface::sptr iface);
diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp
index a3276152a..a493d4e8c 100644
--- a/host/lib/usrp/x300/x300_impl.hpp
+++ b/host/lib/usrp/x300/x300_impl.hpp
@@ -90,7 +90,6 @@ private:
std::string loaded_fpga_image;
size_t hw_rev;
- std::string current_refclk_src;
uhd::usrp::x300::conn_manager::sptr conn_mgr;
};