diff options
author | Martin Braun <martin.braun@ettus.com> | 2019-12-02 23:06:39 -0800 |
---|---|---|
committer | Brent Stapleton <brent.stapleton@ettus.com> | 2019-12-20 16:32:22 -0800 |
commit | 4547f2de85f0d8b258a89cea71af774fce8616b7 (patch) | |
tree | d1239e074c5a35b449638a34aa3a6f74a53adfbb /host/lib/usrp/mpmd | |
parent | 4e38eef817813c1bbd8a9cf972e4cf0134d24308 (diff) | |
download | uhd-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/mpmd')
-rw-r--r-- | host/lib/usrp/mpmd/CMakeLists.txt | 30 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_find.cpp | 10 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.cpp | 279 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.hpp | 48 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp | 126 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.hpp | 2 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_link_if_mgr.cpp | 3 |
7 files changed, 137 insertions, 361 deletions
diff --git a/host/lib/usrp/mpmd/CMakeLists.txt b/host/lib/usrp/mpmd/CMakeLists.txt index ce06913a3..1eab1f39b 100644 --- a/host/lib/usrp/mpmd/CMakeLists.txt +++ b/host/lib/usrp/mpmd/CMakeLists.txt @@ -1,21 +1,11 @@ # # Copyright 2017 Ettus Research, a National Instruments Company +# Copyright 2019 Ettus Research, a National Instruments Brand # # SPDX-License-Identifier: GPL-3.0-or-later # if(ENABLE_MPMD) - if(ENABLE_LIBERIO) - message(STATUS "Compiling MPMD with liberio support...") - add_definitions(-DHAVE_LIBERIO) - endif(ENABLE_LIBERIO) - - if(ENABLE_DPDK) - message(STATUS "Compiling MPMD without DPDK support for now...") - # message(STATUS "Compiling MPMD with DPDK support...") - # add_definitions(-DHAVE_DPDK) - endif(ENABLE_DPDK) - LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/mpmd_find.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mpmd_image_loader.cpp @@ -29,15 +19,23 @@ if(ENABLE_MPMD) ) if(ENABLE_LIBERIO) + message(STATUS "Compiling MPMD with liberio support...") LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/mpmd_link_if_ctrl_liberio.cpp ) + set_property( + SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/mpmd_link_if_mgr.cpp + PROPERTY COMPILE_DEFINITIONS HAVE_LIBERIO + ) endif(ENABLE_LIBERIO) - # if(ENABLE_DPDK) - # LIBUHD_APPEND_SOURCES( - # ${CMAKE_CURRENT_SOURCE_DIR}/mpmd_link_if_ctrl_dpdk_udp.cpp - # ) - # endif(ENABLE_DPDK) + if(ENABLE_DPDK) + set_property( + SOURCE + ${CMAKE_CURRENT_SOURCE_DIR}/mpmd_link_if_ctrl_udp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mpmd_find.cpp + PROPERTY COMPILE_DEFINITIONS HAVE_DPDK + ) + endif(ENABLE_DPDK) endif(ENABLE_MPMD) diff --git a/host/lib/usrp/mpmd/mpmd_find.cpp b/host/lib/usrp/mpmd/mpmd_find.cpp index 3e8bcc72f..b5f20559c 100644 --- a/host/lib/usrp/mpmd/mpmd_find.cpp +++ b/host/lib/usrp/mpmd/mpmd_find.cpp @@ -9,13 +9,15 @@ #include "mpmd_devices.hpp" #include "mpmd_impl.hpp" #include "mpmd_link_if_mgr.hpp" -#include <uhdlib/transport/dpdk_common.hpp> #include <uhd/transport/if_addrs.hpp> #include <uhd/transport/udp_simple.hpp> #include <uhd/types/device_addr.hpp> #include <boost/algorithm/string.hpp> #include <boost/asio.hpp> #include <future> +#ifdef HAVE_DPDK +# include <uhdlib/transport/dpdk/common.hpp> +#endif using namespace uhd; using namespace uhd::mpmd; @@ -198,9 +200,9 @@ device_addrs_t mpmd_find(const device_addr_t& hint_) #ifdef HAVE_DPDK // Start DPDK so links come up 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_); + auto dpdk_ctx = uhd::transport::dpdk::dpdk_ctx::get(); + if (not dpdk_ctx->is_init_done()) { + dpdk_ctx->init(hint_); } } #endif diff --git a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.cpp b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.cpp deleted file mode 100644 index 2a3a48b62..000000000 --- a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.cpp +++ /dev/null @@ -1,279 +0,0 @@ -// -// Copyright 2017 Ettus Research, National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#include "mpmd_impl.hpp" -#include "mpmd_link_if_mgr.hpp" -#include "mpmd_link_if_ctrl_dpdk_udp.hpp" -#include <uhd/transport/udp_simple.hpp> -#include <uhd/transport/udp_constants.hpp> -#include <uhdlib/transport/dpdk_zero_copy.hpp> -#include <arpa/inet.h> - - -using namespace uhd; -using namespace uhd::mpmd::xport; - -namespace { -constexpr unsigned int MPMD_UDP_RESERVED_FRAME_SIZE = 64; - -//! Maximum CHDR packet size in bytes -const size_t MPMD_10GE_DATA_FRAME_MAX_SIZE = 4000; -const size_t MPMD_10GE_DATA_FRAME_DEFAULT_SIZE = 4000; -const size_t MPMD_10GE_MSG_FRAME_DEFAULT_SIZE = 256; - -//! Number of send/recv frames -const size_t MPMD_ETH_NUM_SEND_FRAMES = 32; -const size_t MPMD_ETH_NUM_RECV_FRAMES = 128; -const size_t MPMD_ETH_NUM_CTRL_FRAMES = 32; - -//! For MTU discovery, the time we wait for a packet before calling it -// oversized (seconds). -const double MPMD_MTU_DISCOVERY_TIMEOUT = 0.02; - -std::vector<std::string> get_addrs_from_mb_args( - const uhd::device_addr_t& mb_args -) { - // mb_args must always include addr - if (not mb_args.has_key(FIRST_ADDR_KEY)) { - throw uhd::runtime_error("The " + FIRST_ADDR_KEY + " key must be specified in " - "device args to create an Ethernet transport to an RFNoC block"); - } - std::vector<std::string> addrs{mb_args[FIRST_ADDR_KEY]}; - if (mb_args.has_key(SECOND_ADDR_KEY)){ - addrs.push_back(mb_args[SECOND_ADDR_KEY]); - } - return addrs; -} - -/*! Do a binary search to discover MTU - * - * Uses the MPM echo service to figure out MTU. We simply send a bunch of - * packets and see if they come back until we converged on the path MTU. - * The end result must lie between \p min_frame_size and \p max_frame_size. - * - * \param address IP address - * \param port UDP port - * \param min_frame_size Minimum frame size, initialize algorithm to start - * with this value - * \param max_frame_size Maximum frame size, initialize algorithm to start - * with this value - * \param echo_timeout Timeout value in seconds. For frame sizes that - * exceed the MTU, we don't expect a response, and this - * is the amount of time we'll wait before we assume - * the frame size exceeds the MTU. - */ -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; -} - -} - - -mpmd_link_if_ctrl_dpdk_udp::mpmd_link_if_ctrl_dpdk_udp( - const uhd::device_addr_t& mb_args -) : _mb_args(mb_args) - , _ctx(uhd::transport::uhd_dpdk_ctx::get()) - , _recv_args(filter_args(mb_args, "recv")) - , _send_args(filter_args(mb_args, "send")) - , _available_addrs(get_addrs_from_mb_args(mb_args)) - , _mtu(MPMD_10GE_DATA_FRAME_MAX_SIZE) -{ - if (not _ctx.is_init_done()) { - _ctx.init(mb_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){ - 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 - ); - }; - - for (const auto &ip_addr : _available_addrs) { - _mtu = std::min(_mtu, discover_mtu_for_ip(ip_addr)); - } -} - -// uhd::both_xports_t -// mpmd_link_if_ctrl_dpdk_udp::make_transport( -// mpmd_link_if_mgr::xport_info_t &xport_info, -// const uhd::transport::link_type_t xport_type, -// const uhd::device_addr_t& xport_args -//) { - -//// Constrain by this transport's MTU and the MTU in the xport_args -// const size_t send_mtu = std::min(get_mtu(uhd::TX_DIRECTION), -// xport_args.cast<size_t>("mtu", get_mtu(uhd::TX_DIRECTION))); -// const size_t recv_mtu = std::min(get_mtu(uhd::RX_DIRECTION), -// xport_args.cast<size_t>("mtu", get_mtu(uhd::RX_DIRECTION))); - -//// Create actual UHD-DPDK UDP transport -// transport::zero_copy_xport_params default_buff_args; -// default_buff_args.num_recv_frames = MPMD_ETH_NUM_CTRL_FRAMES; -// default_buff_args.num_send_frames = MPMD_ETH_NUM_CTRL_FRAMES; -// default_buff_args.recv_frame_size = MPMD_10GE_MSG_FRAME_DEFAULT_SIZE; -// default_buff_args.send_frame_size = MPMD_10GE_MSG_FRAME_DEFAULT_SIZE; - -// if (xport_type == uhd::transport::link_type_t::RX_DATA) { -// default_buff_args.num_recv_frames = -// xport_args.cast<size_t>("num_recv_frames", MPMD_ETH_NUM_RECV_FRAMES); -// default_buff_args.recv_frame_size = std::min( -// xport_args.cast<size_t>("recv_frame_size", -// MPMD_10GE_DATA_FRAME_DEFAULT_SIZE), -// recv_mtu); -//} else if (xport_type == uhd::transport::link_type_t::TX_DATA) { -// default_buff_args.num_send_frames = -// xport_args.cast<size_t>("num_send_frames", MPMD_ETH_NUM_SEND_FRAMES); -// default_buff_args.send_frame_size = std::min( -// xport_args.cast<size_t>("send_frame_size", -// MPMD_10GE_DATA_FRAME_DEFAULT_SIZE), -// send_mtu); -//} - -// UHD_LOG_TRACE("BUFF", "num_recv_frames=" << default_buff_args.num_recv_frames -//<< ", num_send_frames=" << default_buff_args.num_send_frames -//<< ", recv_frame_size=" << default_buff_args.recv_frame_size -//<< ", send_frame_size=" << default_buff_args.send_frame_size); - -// int dpdk_port_id = _ctx.get_route(xport_info["ipv4"]); -// if (dpdk_port_id < 0) { -// throw uhd::runtime_error("Could not find a DPDK port with route to " + -// xport_info["ipv4"]); -//} -// auto recv = transport::dpdk_zero_copy::make( -//_ctx, -//(const unsigned int) dpdk_port_id, -// xport_info["ipv4"], -// xport_info["port"], -//"0", -// default_buff_args, -// uhd::device_addr_t() -//); -// const uint16_t port = recv->get_local_port(); -// const std::string src_ip_addr = recv->get_local_addr(); -// xport_info["src_port"] = std::to_string(port); -// xport_info["src_ipv4"] = src_ip_addr; - -//// Create both_xports_t object and finish: -// both_xports_t xports; -// xports.endianness = uhd::ENDIANNESS_BIG; -// xports.send_sid = sid_t(xport_info["send_sid"]); -// xports.recv_sid = xports.send_sid.reversed(); -// xports.recv_buff_size = -// (default_buff_args.recv_frame_size-MPMD_UDP_RESERVED_FRAME_SIZE)*default_buff_args.num_recv_frames; -// xports.send_buff_size = -// (default_buff_args.send_frame_size-MPMD_UDP_RESERVED_FRAME_SIZE)*default_buff_args.num_send_frames; -// xports.recv = recv; // Note: This is a type cast! -// xports.send = recv; // This too -// return xports; -//} - -bool mpmd_link_if_ctrl_dpdk_udp::is_valid( - const mpmd_link_if_mgr::xport_info_t& xport_info -) const { - int dpdk_port_id = _ctx.get_route(xport_info.at("ipv4")); - return (dpdk_port_id >= 0); -} - -size_t mpmd_link_if_ctrl_dpdk_udp::get_mtu(const uhd::direction_t /*dir*/) const -{ - return _mtu; -} diff --git a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.hpp b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.hpp deleted file mode 100644 index 8f4f1c7d1..000000000 --- a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_MPMD_XPORT_CTRL_DPDK_UDP_HPP -#define INCLUDED_MPMD_XPORT_CTRL_DPDK_UDP_HPP - -#include "mpmd_link_if_ctrl_base.hpp" -#include <uhd/types/device_addr.hpp> -#include <uhdlib/transport/dpdk_zero_copy.hpp> - -namespace uhd { namespace mpmd { namespace xport { - -/*! UDP transport manager - * - * Opens UDP sockets - */ -class mpmd_link_if_ctrl_dpdk_udp : public mpmd_link_if_ctrl_base -{ -public: - mpmd_link_if_ctrl_dpdk_udp( - const uhd::device_addr_t& mb_args - ); - - bool is_valid( - const mpmd_link_if_mgr::xport_info_t& xport_info - ) const; - - size_t get_mtu( - const uhd::direction_t dir - ) const; - -private: - const uhd::device_addr_t _mb_args; - uhd::transport::uhd_dpdk_ctx &_ctx; - const uhd::dict<std::string, std::string> _recv_args; - const uhd::dict<std::string, std::string> _send_args; - //! A list of IP addresses we can connect our CHDR connections to - const std::vector<std::string> _available_addrs; - //! MTU - size_t _mtu; -}; - -}}} /* namespace uhd::mpmd::xport */ - -#endif /* INCLUDED_MPMD_XPORT_CTRL_DPDK_UDP_HPP */ 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); } diff --git a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.hpp b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.hpp index 33db83b47..c80f1e613 100644 --- a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.hpp +++ b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.hpp @@ -14,7 +14,7 @@ namespace uhd { namespace mpmd { namespace xport { -/*! UDP link interface controller +/*! UDP link interface controller (for both kernel-based UDP and DPDK) * * Opens UDP sockets */ diff --git a/host/lib/usrp/mpmd/mpmd_link_if_mgr.cpp b/host/lib/usrp/mpmd/mpmd_link_if_mgr.cpp index 6bb6cae3a..4b36e7ba4 100644 --- a/host/lib/usrp/mpmd/mpmd_link_if_mgr.cpp +++ b/host/lib/usrp/mpmd/mpmd_link_if_mgr.cpp @@ -12,9 +12,6 @@ #ifdef HAVE_LIBERIO # include "mpmd_link_if_ctrl_liberio.hpp" #endif -#ifdef HAVE_DPDK -# include "mpmd_link_if_ctrl_dpdk_udp.hpp" -#endif uhd::dict<std::string, std::string> uhd::mpmd::xport::filter_args( const uhd::device_addr_t& args, const std::string& prefix) |