diff options
author | mattprost <matt.prost@ni.com> | 2021-03-31 11:33:33 -0500 |
---|---|---|
committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2021-04-29 14:35:26 -0500 |
commit | d689df23fb4bf38e1abc23b06767fc26aa27c163 (patch) | |
tree | b89a640a8e86ec572958d7602cc2c9d834f68fdf /host | |
parent | 99e5230e4bf26166ee1accce1e57ff24b0629826 (diff) | |
download | uhd-d689df23fb4bf38e1abc23b06767fc26aa27c163.tar.gz uhd-d689df23fb4bf38e1abc23b06767fc26aa27c163.tar.bz2 uhd-d689df23fb4bf38e1abc23b06767fc26aa27c163.zip |
rfnoc: Add option to disable flow control on rx streaming
Disabling this feature will allow the USRP to send a continuous stream
of Rx data to a host machine without throttling due to lack of flow
control credits. This is unnecessary overhead on lossless transports
such as pcie or aurora.
Usage: add 'enable_fc=false' to stream_args.args
Signed-off-by: mattprost <matt.prost@ni.com>
Diffstat (limited to 'host')
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/mgmt_portal.hpp | 10 | ||||
-rw-r--r-- | host/lib/include/uhdlib/transport/links.hpp | 3 | ||||
-rw-r--r-- | host/lib/rfnoc/chdr_rx_data_xport.cpp | 4 | ||||
-rw-r--r-- | host/lib/rfnoc/mgmt_portal.cpp | 19 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp | 16 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_mb_iface.cpp | 55 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_eth_mgr.cpp | 17 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_mb_iface.cpp | 70 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_pcie_mgr.cpp | 12 |
9 files changed, 146 insertions, 60 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/mgmt_portal.hpp b/host/lib/include/uhdlib/rfnoc/mgmt_portal.hpp index afe438140..0e3e887f3 100644 --- a/host/lib/include/uhdlib/rfnoc/mgmt_portal.hpp +++ b/host/lib/include/uhdlib/rfnoc/mgmt_portal.hpp @@ -148,9 +148,13 @@ public: // // \param xport The host stream endpoint's CTRL transport (same EPID as RX stream) // \param epid The endpoint ID of the data source + // \param timeout The max time to wait on stream validation + // \param fc_enabled Enable flow control in the FPGA // - virtual stream_buff_params_t config_local_rx_stream_commit( - chdr_ctrl_xport& xport, const sep_id_t& epid, const double timeout = 0.2) = 0; + virtual stream_buff_params_t config_local_rx_stream_commit(chdr_ctrl_xport& xport, + const sep_id_t& epid, + const double timeout = 0.2, + const bool fc_enabled = true) = 0; //! Configure a flow controlled transmit data stream from this SW mgmt portal to the // endpoint with the specified ID. @@ -177,6 +181,8 @@ public: // \param mdata_buff_fmt Datatype of SW buffer that holds the data metadata // \param fc_freq Flow control response frequency parameters // \param fc_freq Flow control headroom parameters + // \param reset Reset source and destination stream endpoint states + // \param timeout The max time to wait on stream validation // virtual stream_buff_params_t config_remote_stream(chdr_ctrl_xport& xport, const sep_id_t& dst_epid, diff --git a/host/lib/include/uhdlib/transport/links.hpp b/host/lib/include/uhdlib/transport/links.hpp index f9d08de11..89d5774ce 100644 --- a/host/lib/include/uhdlib/transport/links.hpp +++ b/host/lib/include/uhdlib/transport/links.hpp @@ -20,7 +20,8 @@ using both_links_t = std::tuple<uhd::transport::send_link_if::sptr, uhd::transport::recv_link_if::sptr, size_t, // num_recv_frames bool, // lossy_xport - bool>; // packet flow control + bool, // packet flow control + bool>; // enable flow control /*! * Parameters for link creation. diff --git a/host/lib/rfnoc/chdr_rx_data_xport.cpp b/host/lib/rfnoc/chdr_rx_data_xport.cpp index 74b310fa1..7089c9071 100644 --- a/host/lib/rfnoc/chdr_rx_data_xport.cpp +++ b/host/lib/rfnoc/chdr_rx_data_xport.cpp @@ -200,7 +200,9 @@ chdr_rx_data_xport::fc_params_t chdr_rx_data_xport::configure_sep(io_service::sp recv_io->release_recv_buff(std::move(buff)); // Finally, let the management portal know the setup is complete - mgmt_portal.config_local_rx_stream_commit(*ctrl_xport, remote_epid); + const bool fc_enabled = (fc_freq.bytes != 0) || (fc_freq.packets != 0); + mgmt_portal.config_local_rx_stream_commit( + *ctrl_xport, remote_epid, 0.2 /*default timeout*/, fc_enabled); // The flow control frequency requested is contained in the strc UHD_LOG_TRACE("XPORT::RX_DATA_XPORT", diff --git a/host/lib/rfnoc/mgmt_portal.cpp b/host/lib/rfnoc/mgmt_portal.cpp index 0ebc9654d..2b843ae03 100644 --- a/host/lib/rfnoc/mgmt_portal.cpp +++ b/host/lib/rfnoc/mgmt_portal.cpp @@ -503,14 +503,16 @@ public: (boost::format("Initiated RX stream setup for EPID=%d") % epid)); } - stream_buff_params_t config_local_rx_stream_commit( - chdr_ctrl_xport& xport, const sep_id_t& epid, const double timeout = 0.2) override + stream_buff_params_t config_local_rx_stream_commit(chdr_ctrl_xport& xport, + const sep_id_t& epid, + const double timeout = 0.2, + const bool fc_enabled = true) override { std::lock_guard<std::recursive_mutex> lock(_mutex); // Wait for stream configuration to finish on the HW side const node_addr_t& node_addr = _lookup_sep_node_addr(epid); - _validate_stream_setup(xport, node_addr, timeout); + _validate_stream_setup(xport, node_addr, timeout, fc_enabled); UHD_LOG_DEBUG("RFNOC::MGMT", (boost::format("Finished RX stream setup for EPID=%d") % epid)); @@ -574,6 +576,7 @@ public: { std::lock_guard<std::recursive_mutex> lock(_mutex); auto my_epid = xport.get_epid(); + const bool fc_enabled = (fc_freq.bytes != 0) || (fc_freq.packets != 0); // First setup a route between the two endpoints setup_remote_route(xport, dst_epid, src_epid); @@ -638,7 +641,7 @@ public: } // Wait for stream configuration to finish on the HW side - _validate_stream_setup(xport, src_node_addr, timeout); + _validate_stream_setup(xport, src_node_addr, timeout, fc_enabled); UHD_LOG_DEBUG("RFNOC::MGMT", (boost::format("Setup a stream from EPID=%d to EPID=%d") % src_epid @@ -931,8 +934,10 @@ private: // Functions } // Make sure that stream setup is complete and successful, else throw exception - void _validate_stream_setup( - chdr_ctrl_xport& xport, const node_addr_t& node_addr, const double timeout) + void _validate_stream_setup(chdr_ctrl_xport& xport, + const node_addr_t& node_addr, + const double timeout, + const bool fc_enabled) { // Get the status of the output stream uint32_t ostrm_status = 0; @@ -954,7 +959,7 @@ private: // Functions if ((ostrm_status & STRM_STATUS_SETUP_ERR) != 0) { throw uhd::op_failed("config_stream: Setup failure"); } - if ((ostrm_status & STRM_STATUS_FC_ENABLED) == 0) { + if (fc_enabled != bool(ostrm_status & STRM_STATUS_FC_ENABLED)) { throw uhd::op_failed("config_stream: Flow control negotiation failed"); } } 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 d5be57cd9..6fc36bf72 100644 --- a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp +++ b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp @@ -12,6 +12,7 @@ #include <uhd/transport/udp_constants.hpp> #include <uhd/transport/udp_simple.hpp> #include <uhd/transport/udp_zero_copy.hpp> +#include <uhd/utils/cast.hpp> #include <uhdlib/rfnoc/rfnoc_common.hpp> #include <uhdlib/transport/udp_boost_asio_link.hpp> #include <uhdlib/transport/udp_common.hpp> @@ -283,6 +284,9 @@ uhd::transport::both_links_t mpmd_link_if_ctrl_udp::get_link(const size_t link_i const std::string udp_port = _udp_info.at(ip_addr).udp_port; const size_t link_rate = get_link_rate(link_idx); + const bool enable_fc = not link_args.has_key("enable_fc") + || uhd::cast::from_str<bool>(link_args.get("enable_fc")); + const bool lossy_xport = enable_fc; const bool use_dpdk = _mb_args.has_key("use_dpdk"); // FIXME use constrained device args link_params_t default_link_params; default_link_params.num_send_frames = MPMD_ETH_NUM_FRAMES; @@ -327,8 +331,9 @@ uhd::transport::both_links_t mpmd_link_if_ctrl_udp::get_link(const size_t link_i link_params.send_buff_size, link, link_params.recv_buff_size, + lossy_xport, true, - true); + enable_fc); #else UHD_LOG_WARNING("MPMD", "Cannot create DPDK transport, falling back to UDP"); #endif @@ -338,8 +343,13 @@ uhd::transport::both_links_t mpmd_link_if_ctrl_udp::get_link(const size_t link_i link_params, link_params.recv_buff_size, link_params.send_buff_size); - return std::make_tuple( - link, link_params.send_buff_size, link, link_params.recv_buff_size, true, false); + return std::make_tuple(link, + link_params.send_buff_size, + link, + link_params.recv_buff_size, + lossy_xport, + false, + enable_fc); } size_t mpmd_link_if_ctrl_udp::get_num_links() const diff --git a/host/lib/usrp/mpmd/mpmd_mb_iface.cpp b/host/lib/usrp/mpmd/mpmd_mb_iface.cpp index a24be5c57..70e982fc7 100644 --- a/host/lib/usrp/mpmd/mpmd_mb_iface.cpp +++ b/host/lib/usrp/mpmd/mpmd_mb_iface.cpp @@ -165,9 +165,15 @@ uhd::rfnoc::chdr_ctrl_xport::sptr mpmd_mboard_impl::mpmd_mb_iface::make_ctrl_tra const size_t link_idx = _local_device_id_map.at(local_device_id); uhd::transport::send_link_if::sptr send_link; uhd::transport::recv_link_if::sptr recv_link; - std::tie(send_link, std::ignore, recv_link, std::ignore, std::ignore, std::ignore) = - _link_if_mgr->get_link( - link_idx, uhd::transport::link_type_t::CTRL, uhd::device_addr_t()); + std::tie(send_link, + std::ignore, + recv_link, + std::ignore, + std::ignore, + std::ignore, + std::ignore) = _link_if_mgr->get_link(link_idx, + uhd::transport::link_type_t::CTRL, + uhd::device_addr_t()); /* Associate local device ID with the adapter */ _adapter_map[local_device_id] = send_link->get_send_adapter_id(); @@ -211,11 +217,17 @@ mpmd_mboard_impl::mpmd_mb_iface::make_rx_data_transport( uhd::transport::send_link_if::sptr send_link; uhd::transport::recv_link_if::sptr recv_link; - bool lossy_xport, packet_fc; + bool lossy_xport, packet_fc, enable_fc; size_t recv_buff_size; - std::tie(send_link, std::ignore, recv_link, recv_buff_size, lossy_xport, packet_fc) = - _link_if_mgr->get_link( - link_idx, uhd::transport::link_type_t::RX_DATA, xport_args); + std::tie(send_link, + std::ignore, + recv_link, + recv_buff_size, + lossy_xport, + packet_fc, + enable_fc) = _link_if_mgr->get_link(link_idx, + uhd::transport::link_type_t::RX_DATA, + xport_args); /* Associate local device ID with the adapter */ _adapter_map[local_sep_addr.first] = send_link->get_send_adapter_id(); @@ -226,14 +238,19 @@ mpmd_mboard_impl::mpmd_mb_iface::make_rx_data_transport( const double ratio = 1.0 / 32; - // Configure flow control frequency to use either bytes only or packets only uhd::rfnoc::stream_buff_params_t fc_freq; - if (packet_fc) { - fc_freq = {uhd::rfnoc::MAX_FC_FREQ_BYTES, - static_cast<uint32_t>(std::ceil(recv_link->get_num_recv_frames() * ratio))}; + if (enable_fc) { + // Configure flow control frequency to use either bytes only or packets only + if (packet_fc) { + fc_freq = {uhd::rfnoc::MAX_FC_FREQ_BYTES, + static_cast<uint32_t>( + std::ceil(recv_link->get_num_recv_frames() * ratio))}; + } else { + fc_freq = {static_cast<uint64_t>(std::ceil(double(recv_buff_size) * ratio)), + uhd::rfnoc::MAX_FC_FREQ_PKTS}; + } } else { - fc_freq = {static_cast<uint64_t>(std::ceil(double(recv_buff_size) * ratio)), - uhd::rfnoc::MAX_FC_FREQ_PKTS}; + fc_freq = {0, 0}; } stream_buff_params_t fc_headroom = {0, 0}; @@ -306,9 +323,15 @@ mpmd_mboard_impl::mpmd_mb_iface::make_tx_data_transport( uhd::transport::send_link_if::sptr send_link; uhd::transport::recv_link_if::sptr recv_link; bool lossy_xport; - std::tie(send_link, std::ignore, recv_link, std::ignore, lossy_xport, std::ignore) = - _link_if_mgr->get_link( - link_idx, uhd::transport::link_type_t::TX_DATA, xport_args); + std::tie(send_link, + std::ignore, + recv_link, + std::ignore, + lossy_xport, + std::ignore, + std::ignore) = _link_if_mgr->get_link(link_idx, + uhd::transport::link_type_t::TX_DATA, + xport_args); /* Associate local device ID with the adapter */ _adapter_map[local_sep_addr.first] = send_link->get_send_adapter_id(); diff --git a/host/lib/usrp/x300/x300_eth_mgr.cpp b/host/lib/usrp/x300/x300_eth_mgr.cpp index f428fc98e..dcc8195ae 100644 --- a/host/lib/usrp/x300/x300_eth_mgr.cpp +++ b/host/lib/usrp/x300/x300_eth_mgr.cpp @@ -20,6 +20,7 @@ #include <uhd/transport/udp_zero_copy.hpp> #include <uhd/utils/algorithm.hpp> #include <uhd/utils/byteswap.hpp> +#include <uhd/utils/cast.hpp> #include <uhdlib/rfnoc/device_id.hpp> #include <uhdlib/rfnoc/rfnoc_common.hpp> #include <uhdlib/transport/udp_boost_asio_link.hpp> @@ -227,6 +228,10 @@ both_links_t eth_manager::get_links(link_type_t link_type, x300_eth_conn_t conn = eth_conns[local_device_id]; zero_copy_xport_params default_buff_args; + const bool enable_fc = not link_args.has_key("enable_fc") + || uhd::cast::from_str<bool>(link_args.get("enable_fc")); + const bool lossy_xport = enable_fc; + const size_t send_mtu = get_mtu(uhd::TX_DIRECTION); const size_t recv_mtu = get_mtu(uhd::RX_DIRECTION); @@ -278,8 +283,9 @@ both_links_t eth_manager::get_links(link_type_t link_type, link_params.send_buff_size, link, link_params.recv_buff_size, + lossy_xport, true, - true); + enable_fc); #else UHD_LOG_WARNING("X300", "Cannot create DPDK transport, falling back to UDP"); #endif @@ -289,8 +295,13 @@ both_links_t eth_manager::get_links(link_type_t link_type, link_params, link_params.recv_buff_size, link_params.send_buff_size); - return std::make_tuple( - link, link_params.send_buff_size, link, link_params.recv_buff_size, true, false); + return std::make_tuple(link, + link_params.send_buff_size, + link, + link_params.recv_buff_size, + lossy_xport, + false, + enable_fc); } /****************************************************************************** diff --git a/host/lib/usrp/x300/x300_mb_iface.cpp b/host/lib/usrp/x300/x300_mb_iface.cpp index c89374f82..a351864df 100644 --- a/host/lib/usrp/x300/x300_mb_iface.cpp +++ b/host/lib/usrp/x300/x300_mb_iface.cpp @@ -98,12 +98,17 @@ uhd::rfnoc::chdr_ctrl_xport::sptr x300_impl::x300_mb_iface::make_ctrl_transport( send_link_if::sptr send_link; recv_link_if::sptr recv_link; bool lossy_xport; - std::tie(send_link, std::ignore, recv_link, std::ignore, lossy_xport, std::ignore) = - _conn_mgr->get_links(link_type_t::CTRL, - local_device_id, - local_epid, - uhd::rfnoc::sep_id_t(), - uhd::device_addr_t()); + std::tie(send_link, + std::ignore, + recv_link, + std::ignore, + lossy_xport, + std::ignore, + std::ignore) = _conn_mgr->get_links(link_type_t::CTRL, + local_device_id, + local_epid, + uhd::rfnoc::sep_id_t(), + uhd::device_addr_t()); /* Associate local device ID with the adapter */ _adapter_map[local_device_id] = send_link->get_send_adapter_id(); @@ -142,13 +147,18 @@ uhd::rfnoc::chdr_rx_data_xport::uptr x300_impl::x300_mb_iface::make_rx_data_tran send_link_if::sptr send_link; recv_link_if::sptr recv_link; size_t recv_buff_size; - bool lossy_xport, packet_fc; - std::tie(send_link, std::ignore, recv_link, recv_buff_size, lossy_xport, packet_fc) = - _conn_mgr->get_links(link_type_t::RX_DATA, - local_sep_addr.first, - local_epid, - remote_epid, - xport_args); + bool lossy_xport, packet_fc, enable_fc; + std::tie(send_link, + std::ignore, + recv_link, + recv_buff_size, + lossy_xport, + packet_fc, + enable_fc) = _conn_mgr->get_links(link_type_t::RX_DATA, + local_sep_addr.first, + local_epid, + remote_epid, + xport_args); /* Associate local device ID with the adapter */ _adapter_map[local_sep_addr.first] = send_link->get_send_adapter_id(); @@ -159,14 +169,19 @@ uhd::rfnoc::chdr_rx_data_xport::uptr x300_impl::x300_mb_iface::make_rx_data_tran const double ratio = 1.0 / 32; - // Configure flow control frequency to use either bytes only or packets only uhd::rfnoc::stream_buff_params_t fc_freq; - if (packet_fc) { - fc_freq = {uhd::rfnoc::MAX_FC_FREQ_BYTES, - static_cast<uint32_t>(std::ceil(recv_link->get_num_recv_frames() * ratio))}; + if (enable_fc) { + // Configure flow control frequency to use either bytes only or packets only + if (packet_fc) { + fc_freq = {uhd::rfnoc::MAX_FC_FREQ_BYTES, + static_cast<uint32_t>( + std::ceil(recv_link->get_num_recv_frames() * ratio))}; + } else { + fc_freq = {static_cast<uint64_t>(std::ceil(double(recv_buff_size) * ratio)), + uhd::rfnoc::MAX_FC_FREQ_PKTS}; + } } else { - fc_freq = {static_cast<uint64_t>(std::ceil(double(recv_buff_size) * ratio)), - uhd::rfnoc::MAX_FC_FREQ_PKTS}; + fc_freq = {0, 0}; } uhd::rfnoc::stream_buff_params_t fc_headroom = {0, 0}; @@ -235,12 +250,17 @@ uhd::rfnoc::chdr_tx_data_xport::uptr x300_impl::x300_mb_iface::make_tx_data_tran send_link_if::sptr send_link; recv_link_if::sptr recv_link; bool lossy_xport; - std::tie(send_link, std::ignore, recv_link, std::ignore, lossy_xport, std::ignore) = - _conn_mgr->get_links(link_type_t::TX_DATA, - local_sep_addr.first, - local_epid, - remote_epid, - xport_args); + std::tie(send_link, + std::ignore, + recv_link, + std::ignore, + lossy_xport, + std::ignore, + std::ignore) = _conn_mgr->get_links(link_type_t::TX_DATA, + local_sep_addr.first, + local_epid, + remote_epid, + xport_args); /* Associate local device ID with the adapter */ _adapter_map[local_sep_addr.first] = send_link->get_send_adapter_id(); diff --git a/host/lib/usrp/x300/x300_pcie_mgr.cpp b/host/lib/usrp/x300/x300_pcie_mgr.cpp index 0ca918e3c..64ce5df55 100644 --- a/host/lib/usrp/x300/x300_pcie_mgr.cpp +++ b/host/lib/usrp/x300/x300_pcie_mgr.cpp @@ -347,6 +347,9 @@ both_links_t pcie_manager::get_links(link_type_t link_type, + ", no such device associated with this motherboard!"); } + const bool enable_fc = not link_args.has_key("enable_fc") + || uhd::cast::from_str<bool>(link_args.get("enable_fc")); + const uint32_t dma_channel_num = allocate_pcie_dma_chan(remote_epid, link_type); // Note: The nirio_link object's factory has a lot of code for sanity // checking the link params, and merging the link_args with the default @@ -358,6 +361,11 @@ both_links_t pcie_manager::get_links(link_type_t link_type, auto link = nirio_link::make(_rio_fpga_interface, dma_channel_num, link_params, link_args, recv_buff_size, send_buff_size); - return std::make_tuple( - link, send_buff_size, link, recv_buff_size, false /*not lossy*/, false); + return std::make_tuple(link, + send_buff_size, + link, + recv_buff_size, + false /*not lossy*/, + false, + enable_fc); } |