aboutsummaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
authorMichael West <michael.west@ettus.com>2019-06-19 13:25:32 -0700
committerMartin Braun <martin.braun@ettus.com>2019-07-18 08:46:16 -0700
commit028a052dec8733f552fbfe0792126f5e9f8ca526 (patch)
tree67d42f21e4a2d20eadad036b655c2a0a40f71605 /host
parentab6893ab32f001d9aab1606bad34fafc4ab76933 (diff)
downloaduhd-028a052dec8733f552fbfe0792126f5e9f8ca526.tar.gz
uhd-028a052dec8733f552fbfe0792126f5e9f8ca526.tar.bz2
uhd-028a052dec8733f552fbfe0792126f5e9f8ca526.zip
Device3: Fix MTU and default frame sizes
The latest changes to the get_*x_stream() functions to calculate the MTU for the channel caused default frame size values to be ignored. This change fixes that by changing the key from "send/recv_frame_size" to "mtu" and then changing the implementations of make_transport() constrain the frame size values based on the "mtu" value as well as any device and/or transport-specific limits. Signed-off-by: Michael West <michael.west@ettus.com>
Diffstat (limited to 'host')
-rw-r--r--host/lib/transport/udp_zero_copy.cpp5
-rw-r--r--host/lib/usrp/device3/device3_io_impl.cpp86
-rw-r--r--host/lib/usrp/mpmd/mpmd_xport_ctrl_dpdk_udp.cpp41
-rw-r--r--host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.cpp48
-rw-r--r--host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.cpp86
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp169
6 files changed, 277 insertions, 158 deletions
diff --git a/host/lib/transport/udp_zero_copy.cpp b/host/lib/transport/udp_zero_copy.cpp
index 6d615570f..e3df80da6 100644
--- a/host/lib/transport/udp_zero_copy.cpp
+++ b/host/lib/transport/udp_zero_copy.cpp
@@ -384,6 +384,11 @@ udp_zero_copy::sptr udp_zero_copy::make(const std::string& addr,
xport_params.send_frame_size = UDP_ZERO_COPY_DEFAULT_FRAME_SIZE;
}
+ UHD_LOG_TRACE("UDP",
+ "send_frame_size: " << xport_params.send_frame_size);
+ UHD_LOG_TRACE("UDP",
+ "recv_frame_size: " << xport_params.recv_frame_size);
+
if (xport_params.recv_buff_size == 0) {
UHD_LOG_TRACE("UDP", "Using default value for recv_buff_size");
xport_params.recv_buff_size = std::max(UDP_ZERO_COPY_DEFAULT_BUFF_SIZE,
diff --git a/host/lib/usrp/device3/device3_io_impl.cpp b/host/lib/usrp/device3/device3_io_impl.cpp
index 06415dd91..800d2f5a8 100644
--- a/host/lib/usrp/device3/device3_io_impl.cpp
+++ b/host/lib/usrp/device3/device3_io_impl.cpp
@@ -168,7 +168,9 @@ static size_t get_rx_flow_control_window(
size_t window_in_bytes = (static_cast<size_t>(fullness_factor * sw_buff_size));
if (rx_args.has_key("max_recv_window")) {
window_in_bytes = std::min(
- window_in_bytes, pkt_size * rx_args.cast<size_t>("max_recv_window", 1));
+ window_in_bytes,
+ pkt_size * rx_args.cast<size_t>("max_recv_window", 1)
+ );
}
if (window_in_bytes < pkt_size) {
throw uhd::value_error("recv_buff_size must be larger than the recv_frame_size.");
@@ -336,10 +338,13 @@ rx_streamer::sptr device3_impl::get_rx_stream(const stream_args_t& args_)
// Setup the DSP transport hints
device_addr_t rx_hints = get_rx_hints(mb_index);
- // Traverse the upstream nodes for minimum mtu
- size_t min_mtu = blk_ctrl->get_mtu(block_port);
- UHD_RX_STREAMER_LOG() << "Maximum MTU supported by " << blk_ctrl->unique_id()
- << ": " << min_mtu;
+ // Search the device and all nodes for lowest MTU
+ size_t mtu = std::min(
+ get_mtu(mb_index, uhd::direction_t::RX_DIRECTION),
+ blk_ctrl->get_mtu(block_port));
+ UHD_RX_STREAMER_LOG() << "Maximum MTU supported by "
+ << blk_ctrl->unique_id()
+ << ": " << blk_ctrl->get_mtu(block_port);
std::vector<boost::shared_ptr<uhd::rfnoc::source_block_ctrl_base>>
upstream_source_nodes =
blk_ctrl->find_upstream_node<uhd::rfnoc::source_block_ctrl_base>();
@@ -349,20 +354,19 @@ rx_streamer::sptr device3_impl::get_rx_stream(const stream_args_t& args_)
// currently we use port 0 of a block in case of channel 1.
UHD_RX_STREAMER_LOG() << "Maximum MTU supported by " << node->unique_id()
<< ": " << node->get_mtu(0);
- min_mtu = std::min(min_mtu, node->get_mtu(0));
+ mtu = std::min(mtu, node->get_mtu(0));
}
- // Contraint min_mtu by device mtu
- min_mtu = std::min(min_mtu, get_mtu(mb_index, uhd::direction_t::RX_DIRECTION));
- if (rx_hints.has_key("recv_frame_size")) {
- if (rx_hints.cast<size_t>("recv_frame_size", min_mtu) > min_mtu) {
- UHD_RX_STREAMER_LOG()
- << "Requested recv_frame_size of " << rx_hints["recv_frame_size"]
- << " exceeds the maximum possible on this stream. Using " << min_mtu;
- }
- min_mtu =
- std::min(min_mtu, rx_hints.cast<size_t>("recv_frame_size", min_mtu));
+ rx_hints["mtu"] = std::to_string(mtu);
+
+ // Make sure user supplied recv_frame_size is less than the MTU
+ if (rx_hints.cast<size_t>("recv_frame_size", mtu) > mtu) {
+ UHD_LOGGER_WARNING("STREAMER")
+ << "Requested recv_frame_size of "
+ << rx_hints["recv_frame_size"]
+ << " exceeds the maximum possible on this stream. Using "
+ << mtu;
+ rx_hints["recv_frame_size"] = std::to_string(mtu);
}
- rx_hints["recv_frame_size"] = std::to_string(min_mtu);
// allocate sid and create transport
uhd::sid_t stream_address = blk_ctrl->get_address(block_port);
@@ -448,8 +452,7 @@ rx_streamer::sptr device3_impl::get_rx_stream(const stream_args_t& args_)
convert::get_bytes_per_item(args.otw_format); // bytes per item
const size_t spp = std::min(args.args.cast<size_t>("spp", bpp / bpi),
bpp / bpi); // samples per packet
- UHD_RX_STREAMER_LOG()
- << "bpp == " << bpp << ", bpi == " << bpi << ", spp == " << spp;
+ UHD_RX_STREAMER_LOG() << "bpp == " << bpp << ", bpi == " << bpi << ", spp == " << spp;
my_streamer = boost::make_shared<device3_recv_packet_streamer>(
spp, recv_terminator, xport);
@@ -605,10 +608,13 @@ tx_streamer::sptr device3_impl::get_tx_stream(const uhd::stream_args_t& args_)
// Setup the dsp transport hints
device_addr_t tx_hints = get_tx_hints(mb_index);
- // Traverse the downstream nodes for minimum mtu
- size_t min_mtu = blk_ctrl->get_mtu(block_port);
- UHD_TX_STREAMER_LOG() << "Maximum MTU supported by " << blk_ctrl->unique_id()
- << ": " << min_mtu;
+ // Search the device and all nodes for lowest MTU
+ size_t mtu = std::min(
+ get_mtu(mb_index, uhd::direction_t::TX_DIRECTION),
+ blk_ctrl->get_mtu(block_port));
+ UHD_TX_STREAMER_LOG() << "Maximum MTU supported by "
+ << blk_ctrl->unique_id() << ": "
+ << blk_ctrl->get_mtu(block_port);
std::vector<boost::shared_ptr<uhd::rfnoc::sink_block_ctrl_base>>
downstream_sink_nodes =
blk_ctrl->find_downstream_node<uhd::rfnoc::sink_block_ctrl_base>();
@@ -616,21 +622,22 @@ tx_streamer::sptr device3_impl::get_tx_stream(const uhd::stream_args_t& args_)
downstream_sink_nodes) {
// Get MTU from Port 0 of the downstream nodes. This is okay for now as
// currently we use port 0 of a block in case of channel 1.
- UHD_TX_STREAMER_LOG() << "Maximum MTU supported by " << node->unique_id()
- << ": " << node->get_mtu(0);
- min_mtu = std::min(min_mtu, node->get_mtu(0));
+ UHD_TX_STREAMER_LOG() << "Maximum MTU supported by "
+ << node->unique_id() << ": "
+ << node->get_mtu(0);
+ mtu = std::min(mtu, node->get_mtu(0));
}
- min_mtu = std::min(min_mtu, get_mtu(mb_index, uhd::direction_t::TX_DIRECTION));
- if (tx_hints.has_key("send_frame_size")) {
- if (tx_hints.cast<size_t>("send_frame_size", min_mtu) > min_mtu) {
- UHD_TX_STREAMER_LOG()
- << "Requested send_frame_size of " << tx_hints["send_frame_size"]
- << " exceeds the maximum possible on this stream. Using " << min_mtu;
- }
- min_mtu =
- std::min(min_mtu, tx_hints.cast<size_t>("send_frame_size", min_mtu));
+ tx_hints["mtu"] = std::to_string(mtu);
+
+ // Make sure user supplied send_frame_size is less than the MTU
+ if (tx_hints.cast<size_t>("send_frame_size", mtu) > mtu) {
+ UHD_LOGGER_WARNING("STREAMER")
+ << "Requested send_frame_size of "
+ << tx_hints["send_frame_size"]
+ << " exceeds the maximum possible on this stream. Using "
+ << mtu;
+ tx_hints["send_frame_size"] = std::to_string(mtu);
}
- tx_hints["send_frame_size"] = std::to_string(min_mtu);
const size_t fifo_size = blk_ctrl->get_fifo_size(block_port);
// Allocate sid and create transport
@@ -729,13 +736,16 @@ tx_streamer::sptr device3_impl::get_tx_stream(const uhd::stream_args_t& args_)
// To calculate the max number of samples per packet, we assume the maximum
// header length to avoid fragmentation should the entire header be used.
const size_t bpp =
- tx_hints.cast<size_t>("bpp", pkt_size) - stream_options.tx_max_len_hdr;
+ tx_hints.cast<size_t>("bpp", pkt_size) -
+ stream_options.tx_max_len_hdr;
const size_t bpi =
convert::get_bytes_per_item(args.otw_format); // bytes per item
const size_t spp = std::min(args.args.cast<size_t>("spp", bpp / bpi),
bpp / bpi); // samples per packet
UHD_TX_STREAMER_LOG()
- << "bpp == " << bpp << ", bpi == " << bpi << ", spp == " << spp;
+ << "bpp == " << bpp
+ << ", bpi == " << bpi
+ << ", spp == " << spp;
my_streamer = boost::make_shared<device3_send_packet_streamer>(
spp, send_terminator, xport, async_xport);
diff --git a/host/lib/usrp/mpmd/mpmd_xport_ctrl_dpdk_udp.cpp b/host/lib/usrp/mpmd/mpmd_xport_ctrl_dpdk_udp.cpp
index a496e8e69..38d295728 100644
--- a/host/lib/usrp/mpmd/mpmd_xport_ctrl_dpdk_udp.cpp
+++ b/host/lib/usrp/mpmd/mpmd_xport_ctrl_dpdk_udp.cpp
@@ -21,6 +21,8 @@ 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;
@@ -194,27 +196,36 @@ uhd::both_xports_t
mpmd_xport_ctrl_dpdk_udp::make_transport(
mpmd_xport_mgr::xport_info_t &xport_info,
const usrp::device3_impl::xport_type_t xport_type,
- const uhd::device_addr_t& xport_args_
+ const uhd::device_addr_t& xport_args
) {
- auto xport_args = xport_args_;
- transport::zero_copy_xport_params default_buff_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
- default_buff_args.recv_frame_size =
- xport_args.cast<size_t>("recv_frame_size", get_mtu(uhd::RX_DIRECTION));
- default_buff_args.send_frame_size =
- xport_args.cast<size_t>("send_frame_size", get_mtu(uhd::TX_DIRECTION));
- if (xport_type == usrp::device3_impl::ASYNC_MSG or
- xport_type == usrp::device3_impl::CTRL) {
- default_buff_args.num_recv_frames =
- xport_args.cast<size_t>("num_recv_frames", MPMD_ETH_NUM_CTRL_FRAMES);
- default_buff_args.num_send_frames =
- xport_args.cast<size_t>("num_send_frames", MPMD_ETH_NUM_CTRL_FRAMES);
- } else {
+ 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 == usrp::device3_impl::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 == usrp::device3_impl::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
@@ -234,7 +245,7 @@ mpmd_xport_ctrl_dpdk_udp::make_transport(
xport_info["port"],
"0",
default_buff_args,
- xport_args
+ uhd::device_addr_t()
);
const uint16_t port = recv->get_local_port();
const std::string src_ip_addr = recv->get_local_addr();
diff --git a/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.cpp b/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.cpp
index 78751c94f..c53eb97a1 100644
--- a/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.cpp
+++ b/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.cpp
@@ -47,15 +47,49 @@ mpmd_xport_ctrl_liberio::mpmd_xport_ctrl_liberio(const uhd::device_addr_t& mb_ar
uhd::both_xports_t mpmd_xport_ctrl_liberio::make_transport(
mpmd_xport_mgr::xport_info_t& xport_info,
const usrp::device3_impl::xport_type_t xport_type,
- const uhd::device_addr_t& xport_args)
+ const uhd::device_addr_t& xport_args_)
{
+ auto xport_args = (xport_type == usrp::device3_impl::CTRL) ?
+ uhd::device_addr_t() : xport_args_;
+
+ // Constrain by this transport's MTU and the MTU passed in
+ 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)));
+ size_t send_frame_size = xport_args.cast<size_t>("send_frame_size", send_mtu);
+ size_t recv_frame_size = xport_args.cast<size_t>("recv_frame_size", recv_mtu);
+
+ // Check any user supplied frame sizes and constrain to MTU
+ if (xport_args.has_key("send_frame_size") and
+ xport_type == usrp::device3_impl::TX_DATA)
+ {
+ if (send_frame_size > send_mtu) {
+ UHD_LOGGER_WARNING("MPMD")
+ << boost::format("Requested send_frame_size of %d exceeds the "
+ "maximum supported by the hardware. Using %d.")
+ % send_frame_size % send_mtu;
+ send_frame_size = send_mtu;
+ }
+ }
+ if (xport_args.has_key("recv_frame_size") and
+ xport_type == usrp::device3_impl::RX_DATA)
+ {
+ size_t recv_frame_size = xport_args.cast<size_t>("recv_frame_size", recv_mtu);
+ if (recv_frame_size > recv_mtu) {
+ UHD_LOGGER_WARNING("MPMD")
+ << boost::format("Requested recv_frame_size of %d exceeds the "
+ "maximum supported by the hardware. Using %d.")
+ % recv_frame_size % recv_mtu;
+ recv_frame_size = recv_mtu;
+ }
+ }
+
transport::zero_copy_xport_params default_buff_args;
/* default ones for RX / TX, override below */
- default_buff_args.send_frame_size =
- xport_args.cast<size_t>("send_frame_size", get_mtu(uhd::TX_DIRECTION));
- default_buff_args.recv_frame_size =
- xport_args.cast<size_t>("recv_frame_size", get_mtu(uhd::RX_DIRECTION));
+ default_buff_args.send_frame_size = send_mtu;
+ default_buff_args.recv_frame_size = recv_mtu;
default_buff_args.num_recv_frames = LIBERIO_NUM_RECV_FRAMES;
default_buff_args.num_send_frames = LIBERIO_NUM_SEND_FRAMES;
@@ -70,9 +104,11 @@ uhd::both_xports_t mpmd_xport_ctrl_liberio::make_transport(
default_buff_args.send_frame_size = LIBERIO_ASYNC_FRAME_MAX_SIZE;
default_buff_args.recv_frame_size = LIBERIO_ASYNC_FRAME_MAX_SIZE;
} else if (xport_type == usrp::device3_impl::RX_DATA) {
+ default_buff_args.recv_frame_size = recv_frame_size;
default_buff_args.send_frame_size = LIBERIO_FC_FRAME_MAX_SIZE;
} else {
default_buff_args.recv_frame_size = LIBERIO_FC_FRAME_MAX_SIZE;
+ default_buff_args.send_frame_size = send_frame_size;
}
const std::string tx_dev = xport_info["tx_dev"];
@@ -140,7 +176,7 @@ bool mpmd_xport_ctrl_liberio::is_valid(
return xport_info.at("type") == "liberio";
}
-size_t mpmd_xport_ctrl_liberio::get_mtu(const uhd::direction_t dir) const
+size_t mpmd_xport_ctrl_liberio::get_mtu(const uhd::direction_t /*dir*/) const
{
return LIBERIO_PAGES_PER_BUF * getpagesize();
}
diff --git a/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.cpp b/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.cpp
index bdb32b8f6..ba827fcf4 100644
--- a/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.cpp
+++ b/host/lib/usrp/mpmd/mpmd_xport_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
//
@@ -20,11 +21,20 @@ namespace {
//! Maximum CHDR packet size in bytes
const size_t MPMD_10GE_DATA_FRAME_MAX_SIZE = 4000;
-//! Maximum CHDR packet size in bytes
-const size_t MPMD_10GE_ASYNCMSG_FRAME_MAX_SIZE = 1472;
-
-//! Number of send/recv frames
-const size_t MPMD_ETH_NUM_FRAMES = 32;
+//! Default number of send frames
+const size_t MPMD_UDP_DEFAULT_NUM_SEND_FRAMES = 1;
+//! Default number of recv frames
+const size_t MPMD_UDP_DEFAULT_NUM_RECV_FRAMES = 1;
+//! Default message frame size
+const size_t MPMD_UDP_MSG_FRAME_SIZE = 256;
+//! Default 1GbE send frame size
+const size_t MPMD_UDP_1GE_DEFAULT_SEND_FRAME_SIZE = 1472;
+//! Default 1GbE receive frame size
+const size_t MPMD_UDP_1GE_DEFAULT_RECV_FRAME_SIZE = 1472;
+//! Default 10GbE send frame size
+const size_t MPMD_UDP_10GE_DEFAULT_SEND_FRAME_SIZE = 4000;
+//! Default 10GbE receive frame size
+const size_t MPMD_UDP_10GE_DEFAULT_RECV_FRAME_SIZE = 4000;
//!
const double MPMD_BUFFER_DEPTH = 50.0e-3; // s
@@ -33,8 +43,8 @@ const double MPMD_BUFFER_DEPTH = 50.0e-3; // s
const double MPMD_MTU_DISCOVERY_TIMEOUT = 0.02;
// TODO: move these to appropriate header file for all other devices
-const size_t MAX_RATE_1GIGE = 1e9 / 8; // byte/s
-const size_t MAX_RATE_10GIGE = 10e9 / 8; // byte/s
+const double MAX_RATE_1GIGE = 1e9 / 8; // byte/s
+const double MAX_RATE_10GIGE = 10e9 / 8; // byte/s
std::vector<std::string> get_addrs_from_mb_args(const uhd::device_addr_t& mb_args)
{
@@ -163,11 +173,10 @@ mpmd_xport_ctrl_udp::mpmd_xport_ctrl_udp(const uhd::device_addr_t& mb_args)
uhd::both_xports_t mpmd_xport_ctrl_udp::make_transport(
mpmd_xport_mgr::xport_info_t& xport_info,
const usrp::device3_impl::xport_type_t xport_type,
- const uhd::device_addr_t& xport_args_)
+ const uhd::device_addr_t& xport_args)
{
- auto xport_args = xport_args_;
- size_t link_speed = MAX_RATE_1GIGE;
+ double link_speed = MAX_RATE_1GIGE;
if (xport_info.count("link_speed") == 0) {
UHD_LOG_WARNING("MPMD",
"Could not determine link speed; using 1GibE max speed of "
@@ -176,29 +185,54 @@ uhd::both_xports_t mpmd_xport_ctrl_udp::make_transport(
link_speed = xport_info.at("link_speed") == "10000" ? MAX_RATE_10GIGE
: MAX_RATE_1GIGE;
}
- transport::zero_copy_xport_params default_buff_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 UDP transport
- default_buff_args.num_send_frames = 1;
- default_buff_args.num_recv_frames =
- xport_type == usrp::device3_impl::CTRL ?
- (uhd::rfnoc::CMD_FIFO_SIZE / uhd::rfnoc::MAX_CMD_PKT_SIZE) :
- 1;
- default_buff_args.recv_frame_size =
- xport_args.cast<size_t>("recv_frame_size", get_mtu(uhd::RX_DIRECTION));
- default_buff_args.recv_buff_size = link_speed * MPMD_BUFFER_DEPTH;
- default_buff_args.send_buff_size = link_speed * MPMD_BUFFER_DEPTH;
- if (xport_type == usrp::device3_impl::ASYNC_MSG) {
- default_buff_args.send_frame_size = MPMD_10GE_ASYNCMSG_FRAME_MAX_SIZE;
- } else {
+ transport::zero_copy_xport_params default_buff_args;
+ default_buff_args.num_send_frames = MPMD_UDP_DEFAULT_NUM_SEND_FRAMES;
+ default_buff_args.num_recv_frames = MPMD_UDP_DEFAULT_NUM_RECV_FRAMES;
+ default_buff_args.recv_frame_size = MPMD_UDP_MSG_FRAME_SIZE;
+ default_buff_args.send_frame_size = MPMD_UDP_MSG_FRAME_SIZE;
+ if (xport_type == usrp::device3_impl::CTRL) {
+ default_buff_args.num_recv_frames =
+ uhd::rfnoc::CMD_FIFO_SIZE / uhd::rfnoc::MAX_CMD_PKT_SIZE;
+ } else if (xport_type == usrp::device3_impl::TX_DATA) {
+ const size_t default_frame_size = (link_speed == MAX_RATE_10GIGE ?
+ MPMD_UDP_10GE_DEFAULT_SEND_FRAME_SIZE :
+ MPMD_UDP_1GE_DEFAULT_SEND_FRAME_SIZE);
default_buff_args.send_frame_size =
- xport_args.cast<size_t>("send_frame_size", get_mtu(uhd::TX_DIRECTION));
+ xport_args.cast<size_t>("send_frame_size",
+ std::min(default_frame_size, send_mtu));
+ default_buff_args.num_send_frames =
+ xport_args.cast<size_t>("num_send_frames",
+ default_buff_args.num_send_frames);
+ default_buff_args.send_buff_size =
+ xport_args.cast<size_t>("send_buff_size",
+ default_buff_args.send_buff_size);
+ } else if (xport_type == usrp::device3_impl::RX_DATA) {
+ const size_t default_frame_size = (link_speed == MAX_RATE_10GIGE ?
+ MPMD_UDP_10GE_DEFAULT_RECV_FRAME_SIZE :
+ MPMD_UDP_1GE_DEFAULT_RECV_FRAME_SIZE);
+ default_buff_args.recv_frame_size =
+ xport_args.cast<size_t>("recv_frame_size",
+ std::min(default_frame_size, recv_mtu));
+ default_buff_args.num_recv_frames =
+ xport_args.cast<size_t>("num_recv_frames",
+ default_buff_args.num_recv_frames);
+ default_buff_args.recv_buff_size =
+ xport_args.cast<size_t>("recv_buff_size",
+ default_buff_args.recv_buff_size);
}
transport::udp_zero_copy::buff_params buff_params;
auto recv = transport::udp_zero_copy::make(xport_info["ipv4"],
xport_info["port"],
default_buff_args,
- buff_params,
- xport_args);
+ buff_params);
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);
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index 76759acb3..1113374f5 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -869,9 +869,12 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t& dev_addr)
_tree->create<std::string>(mb_path / "codename").set("Yetti");
////////////////////////////////////////////////////////////////////
- // discover ethernet interfaces, frame sizes, and link rates
+ // discover interfaces, frame sizes, and link rates
////////////////////////////////////////////////////////////////////
- if (mb.xport_path == "eth") {
+ if (mb.xport_path == "nirio") {
+ _max_frame_sizes.recv_frame_size = PCIE_RX_DATA_FRAME_SIZE;
+ _max_frame_sizes.send_frame_size = PCIE_TX_DATA_FRAME_SIZE;
+ } else if (mb.xport_path == "eth") {
double link_max_rate = 0.0;
// Discover ethernet interfaces
@@ -1315,12 +1318,17 @@ uhd::both_xports_t x300_impl::make_transport(const uhd::sid_t& address,
{
const size_t mb_index = address.get_dst_addr() - x300::DST_ADDR;
mboard_members_t& mb = _mb[mb_index];
- const uhd::device_addr_t& xport_args = (xport_type == CTRL) ? uhd::device_addr_t()
- : args;
zero_copy_xport_params default_buff_args;
both_xports_t xports;
xports.endianness = mb.if_pkt_is_big_endian ? ENDIANNESS_BIG : ENDIANNESS_LITTLE;
+
+ // Calculate MTU based on MTU in args and device limitations
+ const size_t send_mtu = args.cast<size_t>("mtu",
+ get_mtu(mb_index, uhd::TX_DIRECTION));
+ const size_t recv_mtu = args.cast<size_t>("mtu",
+ get_mtu(mb_index, uhd::RX_DIRECTION));
+
if (mb.xport_path == "nirio") {
xports.lossless = true;
xports.send_sid =
@@ -1350,26 +1358,30 @@ uhd::both_xports_t x300_impl::make_transport(const uhd::sid_t& address,
}
// Create a virtual async message transport
xports.recv = mb.async_msg_dma_xport->make_stream(xports.recv_sid.get_dst());
- } else {
- // Transport for data stream
- default_buff_args.send_frame_size = (xport_type == TX_DATA)
- ? x300::PCIE_TX_DATA_FRAME_SIZE
- : x300::PCIE_MSG_FRAME_SIZE;
-
- default_buff_args.recv_frame_size = (xport_type == RX_DATA)
- ? x300::PCIE_RX_DATA_FRAME_SIZE
- : x300::PCIE_MSG_FRAME_SIZE;
-
- default_buff_args.num_send_frames = (xport_type == TX_DATA)
- ? x300::PCIE_TX_DATA_NUM_FRAMES
- : x300::PCIE_MSG_NUM_FRAMES;
-
- default_buff_args.num_recv_frames = (xport_type == RX_DATA)
- ? x300::PCIE_RX_DATA_NUM_FRAMES
- : x300::PCIE_MSG_NUM_FRAMES;
-
+ } else if (xport_type == TX_DATA) {
+ default_buff_args.send_frame_size = args.cast<size_t>(
+ "send_frame_size", std::min(send_mtu,
+ x300::PCIE_TX_DATA_FRAME_SIZE));
+ default_buff_args.num_send_frames = args.cast<size_t>(
+ "num_send_frames", x300::PCIE_TX_DATA_NUM_FRAMES);
+ default_buff_args.send_buff_size = args.cast<size_t>(
+ "send_buff_size", 0);
+ default_buff_args.recv_frame_size = x300::PCIE_MSG_FRAME_SIZE;
+ default_buff_args.num_recv_frames = x300::PCIE_MSG_NUM_FRAMES;
xports.recv = nirio_zero_copy::make(
- mb.rio_fpga_interface, dma_channel_num, default_buff_args, xport_args);
+ mb.rio_fpga_interface, dma_channel_num, default_buff_args);
+ } else if (xport_type == RX_DATA) {
+ default_buff_args.send_frame_size = x300::PCIE_MSG_FRAME_SIZE;
+ default_buff_args.num_send_frames = x300::PCIE_MSG_NUM_FRAMES;
+ default_buff_args.recv_frame_size = args.cast<size_t>(
+ "recv_frame_size", std::min(recv_mtu,
+ x300::PCIE_RX_DATA_FRAME_SIZE));
+ default_buff_args.num_recv_frames = args.cast<size_t>(
+ "num_recv_frames", x300::PCIE_RX_DATA_NUM_FRAMES);
+ default_buff_args.recv_buff_size = args.cast<size_t>(
+ "recv_buff_size", 0);
+ xports.recv = nirio_zero_copy::make(
+ mb.rio_fpga_interface, dma_channel_num, default_buff_args);
}
xports.send = xports.recv;
@@ -1413,22 +1425,42 @@ uhd::both_xports_t x300_impl::make_transport(const uhd::sid_t& address,
xports.recv_sid = xports.send_sid.reversed();
// Set size and number of frames
- size_t system_max_send_frame_size = (size_t)_max_frame_sizes.send_frame_size;
- size_t system_max_recv_frame_size = (size_t)_max_frame_sizes.recv_frame_size;
- default_buff_args.send_frame_size = xport_args.cast<size_t>("send_frame_size",
- std::min(system_max_send_frame_size, x300::ETH_MSG_FRAME_SIZE));
- default_buff_args.recv_frame_size = xport_args.cast<size_t>("recv_frame_size",
- std::min(system_max_recv_frame_size, x300::ETH_MSG_FRAME_SIZE));
- default_buff_args.num_recv_frames =
- xport_args.cast<size_t>("num_recv_frames", x300::ETH_MSG_NUM_FRAMES);
- default_buff_args.num_send_frames =
- xport_args.cast<size_t>("num_send_frames", x300::ETH_MSG_NUM_FRAMES);
+ default_buff_args.send_frame_size = std::min(send_mtu,
+ x300::ETH_MSG_FRAME_SIZE);
+ default_buff_args.recv_frame_size = std::min(recv_mtu,
+ x300::ETH_MSG_FRAME_SIZE);
+ default_buff_args.num_recv_frames = x300::ETH_MSG_NUM_FRAMES;
+ default_buff_args.num_send_frames = x300::ETH_MSG_NUM_FRAMES;
if (xport_type == 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 == TX_DATA) {
+ size_t default_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE
+ ? x300::GE_DATA_FRAME_SEND_SIZE
+ : x300::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 == RX_DATA) {
+ size_t default_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE
+ ? x300::GE_DATA_FRAME_RECV_SIZE
+ : x300::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);
@@ -1436,13 +1468,15 @@ uhd::both_xports_t x300_impl::make_transport(const uhd::sid_t& address,
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,
+ 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,
- xport_args);
+ uhd::device_addr_t()
+ );
xports.recv = recv; // Note: This is a type cast!
xports.send = xports.recv;
@@ -1504,12 +1538,10 @@ uhd::both_xports_t x300_impl::make_transport(const uhd::sid_t& address,
xports.recv_sid = xports.send_sid.reversed();
// Set size and number of frames
- size_t system_max_send_frame_size = (size_t)_max_frame_sizes.send_frame_size;
- size_t system_max_recv_frame_size = (size_t)_max_frame_sizes.recv_frame_size;
- default_buff_args.send_frame_size =
- std::min(system_max_send_frame_size, x300::ETH_MSG_FRAME_SIZE);
- default_buff_args.recv_frame_size =
- std::min(system_max_recv_frame_size, x300::ETH_MSG_FRAME_SIZE);
+ default_buff_args.send_frame_size = std::min(send_mtu,
+ x300::ETH_MSG_FRAME_SIZE);
+ default_buff_args.recv_frame_size = std::min(recv_mtu,
+ x300::ETH_MSG_FRAME_SIZE);
// Buffering is done in the socket buffers, so size them relative to
// the link rate
default_buff_args.send_buff_size = conn.link_rate / 50; // 20ms
@@ -1531,33 +1563,29 @@ uhd::both_xports_t x300_impl::make_transport(const uhd::sid_t& address,
size_t default_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE
? x300::GE_DATA_FRAME_SEND_SIZE
: x300::XGE_DATA_FRAME_SEND_SIZE;
- default_buff_args.send_frame_size = args.cast<size_t>("send_frame_size",
- std::min(default_frame_size, system_max_send_frame_size));
- if (default_buff_args.send_frame_size > system_max_send_frame_size) {
- UHD_LOGGER_WARNING("X300")
- << boost::format("Requested send_frame_size of %d exceeds the "
- "maximum allowed on the %s connection. Using %d.")
- % default_buff_args.send_frame_size % conn.addr
- % system_max_send_frame_size;
- default_buff_args.send_frame_size = system_max_send_frame_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",
+ default_buff_args.send_buff_size);
} else if (xport_type == RX_DATA) {
size_t default_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE
? x300::GE_DATA_FRAME_RECV_SIZE
: x300::XGE_DATA_FRAME_RECV_SIZE;
- default_buff_args.recv_frame_size = args.cast<size_t>("recv_frame_size",
- std::min(default_frame_size, system_max_recv_frame_size));
- if (default_buff_args.recv_frame_size > system_max_recv_frame_size) {
- UHD_LOGGER_WARNING("X300")
- << boost::format("Requested recv_frame_size of %d exceeds the "
- "maximum allowed on the %s connection. Using %d.")
- % default_buff_args.recv_frame_size % conn.addr
- % system_max_recv_frame_size;
- default_buff_args.recv_frame_size = system_max_recv_frame_size;
- }
+ default_buff_args.recv_frame_size =
+ args.cast<size_t>("recv_frame_size",
+ std::min(default_frame_size, recv_mtu));
+ // set some buffers so the offload thread actually offloads the
+ // socket I/O
default_buff_args.num_recv_frames =
- 2; // set some buffers so the offload thread actually offloads the socket
- // I/O
+ args.cast<size_t>("num_recv_frames", 2);
+ default_buff_args.recv_buff_size =
+ args.cast<size_t>("recv_buff_size",
+ default_buff_args.recv_buff_size);
}
// make a new transport - fpga has no idea how to talk to us on this yet
@@ -1565,8 +1593,7 @@ uhd::both_xports_t x300_impl::make_transport(const uhd::sid_t& address,
xports.recv = udp_zero_copy::make(conn.addr,
BOOST_STRINGIZE(X300_VITA_UDP_PORT),
default_buff_args,
- buff_params,
- xport_args);
+ buff_params);
// Create a threaded transport for the receive chain only
// Note that this shouldn't affect PCIe
@@ -1992,14 +2019,10 @@ x300_impl::frame_size_t x300_impl::determine_max_frame_size(
return frame_size;
}
-size_t x300_impl::get_mtu(const size_t mb_index, const uhd::direction_t dir)
+size_t x300_impl::get_mtu(const size_t /*mb_index*/, const uhd::direction_t dir)
{
- if (_mb[mb_index].xport_path == "nirio") {
- return (dir == RX_DIRECTION ? x300::PCIE_RX_DATA_FRAME_SIZE
- : x300::PCIE_TX_DATA_FRAME_SIZE);
- }
- return (dir == RX_DIRECTION) ? _max_frame_sizes.recv_frame_size
- : _max_frame_sizes.send_frame_size;
+ return (dir == RX_DIRECTION) ? _max_frame_sizes.recv_frame_size :
+ _max_frame_sizes.send_frame_size;
}
/***********************************************************************