From 2f7f873b7f0299ec1f8ae7c752246cb2f1608c0a Mon Sep 17 00:00:00 2001 From: Michael West Date: Wed, 29 Mar 2017 13:24:32 -0700 Subject: X300: Dual channel TX performance improvements --- host/lib/usrp/x300/x300_impl.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'host/lib/usrp/x300/x300_impl.cpp') diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index 4f3870357..934e2eaa5 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -511,6 +511,8 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) eth_addrs.push_back(eth0_addr); mb.next_src_addr = 0; //Host source address for blocks + mb.next_tx_src_addr = 0; + mb.next_rx_src_addr = 0; if (dev_addr.has_key("second_addr")) { std::string eth1_addr = dev_addr["second_addr"]; @@ -1136,12 +1138,16 @@ uhd::both_xports_t x300_impl::make_transport( } else if (mb.xport_path == "eth") { // Decide on the IP/Interface pair based on the endpoint index - std::string interface_addr = mb.eth_conns[mb.next_src_addr].addr; + size_t &next_src_addr = + xport_type == TX_DATA ? mb.next_tx_src_addr : + xport_type == RX_DATA ? mb.next_rx_src_addr : + mb.next_src_addr; + std::string interface_addr = mb.eth_conns[next_src_addr].addr; const uint32_t xbar_src_addr = - mb.next_src_addr==0 ? X300_SRC_ADDR0 : X300_SRC_ADDR1; + next_src_addr==0 ? X300_SRC_ADDR0 : X300_SRC_ADDR1; const uint32_t xbar_src_dst = - mb.eth_conns[mb.next_src_addr].type==X300_IFACE_ETH0 ? X300_XB_DST_E0 : X300_XB_DST_E1; - mb.next_src_addr = (mb.next_src_addr + 1) % mb.eth_conns.size(); + mb.eth_conns[next_src_addr].type==X300_IFACE_ETH0 ? X300_XB_DST_E0 : X300_XB_DST_E1; + next_src_addr = (next_src_addr + 1) % mb.eth_conns.size(); xports.send_sid = this->allocate_sid(mb, address, xbar_src_addr, xbar_src_dst); xports.recv_sid = xports.send_sid.reversed(); -- cgit v1.2.3 From 0b403340c3e924b642ba72679a8a1bfa23bbfd4c Mon Sep 17 00:00:00 2001 From: Michael West Date: Wed, 14 Jun 2017 10:22:25 -0700 Subject: X300: Implement single DMA channel for all async messages --- host/lib/usrp/device3/device3_impl.hpp | 4 +-- host/lib/usrp/device3/device3_io_impl.cpp | 2 +- host/lib/usrp/x300/x300_impl.cpp | 49 ++++++++++++++++++++++++------- host/lib/usrp/x300/x300_impl.hpp | 5 +++- 4 files changed, 45 insertions(+), 15 deletions(-) (limited to 'host/lib/usrp/x300/x300_impl.cpp') diff --git a/host/lib/usrp/device3/device3_impl.hpp b/host/lib/usrp/device3/device3_impl.hpp index 22c93f25f..043379108 100644 --- a/host/lib/usrp/device3/device3_impl.hpp +++ b/host/lib/usrp/device3/device3_impl.hpp @@ -56,9 +56,9 @@ public: //! The purpose of a transport enum xport_type_t { CTRL = 0, + ASYNC_MSG, TX_DATA, - RX_DATA, - ASYNC_TX_MSG + RX_DATA }; enum xport_t {AXI, ETH, PCIE}; diff --git a/host/lib/usrp/device3/device3_io_impl.cpp b/host/lib/usrp/device3/device3_io_impl.cpp index dc4aacff8..198ee4022 100644 --- a/host/lib/usrp/device3/device3_io_impl.cpp +++ b/host/lib/usrp/device3/device3_io_impl.cpp @@ -773,7 +773,7 @@ tx_streamer::sptr device3_impl::get_tx_stream(const uhd::stream_args_t &args_) uhd::sid_t stream_address = blk_ctrl->get_address(block_port); UHD_STREAMER_LOG() << "[TX Streamer] creating tx stream " << tx_hints.to_string() << std::endl; both_xports_t xport = make_transport(stream_address, TX_DATA, tx_hints); - both_xports_t async_xport = make_transport(stream_address, ASYNC_TX_MSG, device_addr_t("")); + both_xports_t async_xport = make_transport(stream_address, ASYNC_MSG, device_addr_t("")); UHD_STREAMER_LOG() << std::hex << "[TX Streamer] data_sid = " << xport.send_sid << std::dec << std::endl; // To calculate the max number of samples per packet, we assume the maximum header length diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index 934e2eaa5..71cb7f341 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -1039,9 +1039,12 @@ x300_impl::~x300_impl(void) uint32_t x300_impl::mboard_members_t::allocate_pcie_dma_chan(const uhd::sid_t &tx_sid, const xport_type_t xport_type) { static const uint32_t CTRL_CHANNEL = 0; - static const uint32_t FIRST_DATA_CHANNEL = 1; + static const uint32_t ASYNC_MSG_CHANNEL = 1; + static const uint32_t FIRST_DATA_CHANNEL = 2; if (xport_type == CTRL) { return CTRL_CHANNEL; + } else if (xport_type == ASYNC_MSG) { + return ASYNC_MSG_CHANNEL; } else { // sid_t has no comparison defined, so we need to convert it uint32_t uint32_t raw_sid = tx_sid.get(); @@ -1063,6 +1066,24 @@ static uint32_t extract_sid_from_pkt(void* pkt, size_t) { return uhd::sid_t(uhd::wtohx(static_cast(pkt)[1])).get_dst(); } +static uhd::transport::muxed_zero_copy_if::sptr make_muxed_pcie_msg_xport +( + uhd::niusrprio::niusrprio_session::sptr rio_fpga_interface, + uint32_t dma_channel_num, + size_t max_muxed_ports +) { + zero_copy_xport_params buff_args; + buff_args.send_frame_size = X300_PCIE_MSG_FRAME_SIZE; + buff_args.recv_frame_size = X300_PCIE_MSG_FRAME_SIZE; + buff_args.num_send_frames = X300_PCIE_MSG_NUM_FRAMES * max_muxed_ports; + buff_args.num_recv_frames = X300_PCIE_MSG_NUM_FRAMES * max_muxed_ports; + + zero_copy_if::sptr base_xport = nirio_zero_copy::make( + rio_fpga_interface, dma_channel_num, + buff_args, uhd::device_addr_t()); + return muxed_zero_copy_if::make(base_xport, extract_sid_from_pkt, max_muxed_ports); +} + uhd::both_xports_t x300_impl::make_transport( const uhd::sid_t &address, const xport_type_t xport_type, @@ -1084,19 +1105,25 @@ uhd::both_xports_t x300_impl::make_transport( if (not mb.ctrl_dma_xport) { //One underlying DMA channel will handle //all control traffic - zero_copy_xport_params ctrl_buff_args; - ctrl_buff_args.send_frame_size = X300_PCIE_MSG_FRAME_SIZE; - ctrl_buff_args.recv_frame_size = X300_PCIE_MSG_FRAME_SIZE; - ctrl_buff_args.num_send_frames = X300_PCIE_MSG_NUM_FRAMES * X300_PCIE_MAX_MUXED_XPORTS; - ctrl_buff_args.num_recv_frames = X300_PCIE_MSG_NUM_FRAMES * X300_PCIE_MAX_MUXED_XPORTS; - - zero_copy_if::sptr base_xport = nirio_zero_copy::make( - mb.rio_fpga_interface, dma_channel_num, - ctrl_buff_args, uhd::device_addr_t()); - mb.ctrl_dma_xport = muxed_zero_copy_if::make(base_xport, extract_sid_from_pkt, X300_PCIE_MAX_MUXED_XPORTS); + mb.ctrl_dma_xport = make_muxed_pcie_msg_xport( + mb.rio_fpga_interface, + dma_channel_num, + X300_PCIE_MAX_MUXED_CTRL_XPORTS); } //Create a virtual control transport xports.recv = mb.ctrl_dma_xport->make_stream(xports.recv_sid.get_dst()); + } else if (xport_type == ASYNC_MSG) { + //Transport for async message stream + if (not mb.async_msg_dma_xport) { + //One underlying DMA channel will handle + //all async message traffic + mb.async_msg_dma_xport = make_muxed_pcie_msg_xport( + mb.rio_fpga_interface, + dma_channel_num, + X300_PCIE_MAX_MUXED_ASYNC_XPORTS); + } + //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 = diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp index 8f4f81156..982369396 100644 --- a/host/lib/usrp/x300/x300_impl.hpp +++ b/host/lib/usrp/x300/x300_impl.hpp @@ -62,7 +62,8 @@ static const size_t X300_PCIE_TX_DATA_NUM_FRAMES = 4096; static const size_t X300_PCIE_MSG_FRAME_SIZE = 256; //bytes static const size_t X300_PCIE_MSG_NUM_FRAMES = 64; static const size_t X300_PCIE_MAX_CHANNELS = 6; -static const size_t X300_PCIE_MAX_MUXED_XPORTS = 32; +static const size_t X300_PCIE_MAX_MUXED_CTRL_XPORTS = 32; +static const size_t X300_PCIE_MAX_MUXED_ASYNC_XPORTS = 4; static const size_t X300_10GE_DATA_FRAME_MAX_SIZE = 8000; // CHDR packet size in bytes static const size_t X300_1GE_DATA_FRAME_MAX_SIZE = 1472; // CHDR packet size in bytes @@ -205,6 +206,8 @@ private: std::map _dma_chan_pool; //! Control transport for one PCIe connection uhd::transport::muxed_zero_copy_if::sptr ctrl_dma_xport; + //! Async message transport + uhd::transport::muxed_zero_copy_if::sptr async_msg_dma_xport; /*! Allocate or return a previously allocated PCIe channel pair * -- cgit v1.2.3