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 | |
| 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>
| -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);  } | 
