aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp')
-rw-r--r--host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp126
1 files changed, 116 insertions, 10 deletions
diff --git a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp
index a87a9cada..aeb1c6436 100644
--- a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp
+++ b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp
@@ -1,5 +1,6 @@
//
// Copyright 2017 Ettus Research, National Instruments Company
+// Copyright 2019 Ettus Research, National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
@@ -16,6 +17,10 @@
#include <uhdlib/transport/udp_common.hpp>
#include <uhdlib/utils/narrow.hpp>
#include <string>
+#ifdef HAVE_DPDK
+//# include <uhdlib/transport/dpdk_simple.hpp>
+# include <uhdlib/transport/udp_dpdk_link.hpp>
+#endif
using namespace uhd;
using namespace uhd::transport;
@@ -124,8 +129,19 @@ size_t discover_mtu(const std::string& address,
const std::string& port,
size_t min_frame_size,
size_t max_frame_size,
- const double echo_timeout = 0.020)
+ const double echo_timeout,
+ const bool use_dpdk)
{
+ if (use_dpdk) {
+#ifdef HAVE_DPDK
+ // FIXME
+ UHD_LOG_WARNING("MPMD", "Using hard-coded MTU of 8000 for DPDK");
+ return 8000;
+#else
+ UHD_LOG_WARNING("MPMD",
+ "DPDK was requested but is not available, falling back to regular UDP");
+#endif
+ }
const size_t echo_prefix_offset = uhd::mpmd::mpmd_impl::MPM_ECHO_CMD.size();
const size_t mtu_hdr_len = echo_prefix_offset + 10;
UHD_ASSERT_THROW(min_frame_size < max_frame_size);
@@ -186,6 +202,87 @@ size_t discover_mtu(const std::string& address,
return min_frame_size;
}
+// DPDK version
+//size_t discover_mtu(const std::string& address,
+ //const std::string& port,
+ //size_t min_frame_size,
+ //size_t max_frame_size,
+ //const double echo_timeout = 0.020)
+//{
+ //const auto& ctx = uhd::transport::uhd_dpdk_ctx::get();
+ //const size_t echo_prefix_offset = uhd::mpmd::mpmd_impl::MPM_ECHO_CMD.size();
+ //const size_t mtu_hdr_len = echo_prefix_offset + 10;
+ //const int port_id = ctx.get_route(address);
+ //UHD_ASSERT_THROW(port_id >= 0);
+ //UHD_ASSERT_THROW(min_frame_size < max_frame_size);
+ //UHD_ASSERT_THROW(min_frame_size % 4 == 0);
+ //UHD_ASSERT_THROW(max_frame_size % 4 == 0);
+ //UHD_ASSERT_THROW(min_frame_size >= echo_prefix_offset + mtu_hdr_len);
+ //using namespace uhd::transport;
+ //uhd::transport::zero_copy_xport_params buff_args;
+ //buff_args.recv_frame_size = max_frame_size;
+ //buff_args.send_frame_size = max_frame_size;
+ //buff_args.num_send_frames = 1;
+ //buff_args.num_recv_frames = 1;
+ //auto dev_addr = uhd::device_addr_t();
+ //dpdk_zero_copy::sptr sock = dpdk_zero_copy::make(
+ //ctx, (unsigned int)port_id, address, port, "0", buff_args, dev_addr);
+ //std::string send_buf(uhd::mpmd::mpmd_impl::MPM_ECHO_CMD);
+ //send_buf.resize(max_frame_size, '#');
+ //UHD_ASSERT_THROW(send_buf.size() == max_frame_size);
+
+ //// Little helper to check returned packets match the sent ones
+ //auto require_bufs_match = [&send_buf, mtu_hdr_len](
+ //const uint8_t* recv_buf, const size_t len) {
+ //if (len < mtu_hdr_len
+ //or std::memcmp((void*)&recv_buf[0], (void*)&send_buf[0], mtu_hdr_len) != 0) {
+ //throw uhd::runtime_error("Unexpected content of MTU "
+ //"discovery return packet!");
+ //}
+ //};
+ //UHD_LOG_TRACE("MPMD", "Determining UDP MTU... ");
+ //size_t seq_no = 0;
+ //while (min_frame_size < max_frame_size) {
+ //managed_send_buffer::sptr msbuf = sock->get_send_buff(0);
+ //UHD_ASSERT_THROW(msbuf.get() != nullptr);
+ //max_frame_size = std::min(msbuf->size(), max_frame_size);
+ //// Only test multiples of 4 bytes!
+ //const size_t test_frame_size = (max_frame_size / 2 + min_frame_size / 2 + 3)
+ //& ~size_t(3);
+ //// Encode sequence number and current size in the string, makes it
+ //// easy to debug in code or Wireshark. Is also used for identifying
+ //// response packets.
+ //std::sprintf(
+ //&send_buf[echo_prefix_offset], ";%04lu,%04lu", seq_no++, test_frame_size);
+ //// Copy to real buffer
+ //UHD_LOG_TRACE("MPMD", "Testing frame size " << test_frame_size);
+ //auto* tx_buf = msbuf->cast<uint8_t*>();
+ //std::memcpy(tx_buf, &send_buf[0], test_frame_size);
+ //msbuf->commit(test_frame_size);
+ //msbuf.reset();
+
+ //managed_recv_buffer::sptr mrbuf = sock->get_recv_buff(echo_timeout);
+ //if (mrbuf.get() == nullptr || mrbuf->size() == 0) {
+ //// Nothing received, so this is probably too big
+ //max_frame_size = test_frame_size - 4;
+ //} else if (mrbuf->size() >= test_frame_size) {
+ //// Size went through, so bump the minimum
+ //require_bufs_match(mrbuf->cast<uint8_t*>(), mrbuf->size());
+ //min_frame_size = test_frame_size;
+ //} else if (mrbuf->size() < test_frame_size) {
+ //// This is an odd case. Something must have snipped the packet
+ //// on the way back. Still, we'll just back off and try
+ //// something smaller.
+ //UHD_LOG_DEBUG("MPMD", "Unexpected packet truncation during MTU discovery.");
+ //require_bufs_match(mrbuf->cast<uint8_t*>(), mrbuf->size());
+ //max_frame_size = mrbuf->size();
+ //}
+ //mrbuf.reset();
+ //}
+ //UHD_LOG_DEBUG("MPMD", "Path MTU for address " << address << ": " << min_frame_size);
+ //return min_frame_size;
+//}
+
} // namespace
@@ -198,14 +295,16 @@ mpmd_link_if_ctrl_udp::mpmd_link_if_ctrl_udp(const uhd::device_addr_t& mb_args,
, _udp_info(get_udp_info_from_xport_info(xport_info))
, _mtu(MPMD_10GE_DATA_FRAME_MAX_SIZE)
{
+ const bool use_dpdk = mb_args.has_key("use_dpdk"); // FIXME use constrained_device_args
const std::string mpm_discovery_port = _mb_args.get(
mpmd_impl::MPM_DISCOVERY_PORT_KEY, std::to_string(mpmd_impl::MPM_DISCOVERY_PORT));
- auto discover_mtu_for_ip = [mpm_discovery_port](const std::string& ip_addr) {
+ auto discover_mtu_for_ip = [mpm_discovery_port, use_dpdk](const std::string& ip_addr) {
return discover_mtu(ip_addr,
mpm_discovery_port,
IP_PROTOCOL_MIN_MTU_SIZE - IP_PROTOCOL_UDP_PLUS_IP_HEADER,
MPMD_10GE_DATA_FRAME_MAX_SIZE,
- MPMD_MTU_DISCOVERY_TIMEOUT);
+ MPMD_MTU_DISCOVERY_TIMEOUT,
+ use_dpdk);
};
const std::vector<std::string> requested_addrs(
@@ -259,19 +358,26 @@ uhd::transport::both_links_t mpmd_link_if_ctrl_udp::get_link(const size_t link_i
link_args);
// Enforce a minimum bound of the number of receive and send frames.
- 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);
+ 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);
+ if (_mb_args.has_key("use_dpdk")) { // FIXME use constrained device args
+#ifdef HAVE_DPDK
+ auto link = uhd::transport::udp_dpdk_link::make(ip_addr, udp_port, link_params);
+ return std::make_tuple(
+ link, link_params.send_buff_size, link, link_params.recv_buff_size, true);
+#else
+ UHD_LOG_WARNING("X300", "Cannot create DPDK transport, falling back to UDP");
+#endif
+ }
auto link = uhd::transport::udp_boost_asio_link::make(ip_addr,
udp_port,
link_params,
link_params.recv_buff_size,
link_params.send_buff_size);
- return std::tuple<send_link_if::sptr,
- size_t,
- recv_link_if::sptr,
- size_t,
- bool>(
+ return std::make_tuple(
link, link_params.send_buff_size, link, link_params.recv_buff_size, true);
}