aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/transport
diff options
context:
space:
mode:
authorMichael West <michael.west@ettus.com>2017-11-16 11:59:45 -0800
committerMartin Braun <martin.braun@ettus.com>2018-07-25 15:34:03 -0700
commitcb9c97d643ac51279e61439c4e7caae9b1212c7d (patch)
treec6f7ff98dae9b979a75a924aab3c843963d7fd0c /host/lib/transport
parent7ed7b207735fee5f7bd055472e591935b5f96cf5 (diff)
downloaduhd-cb9c97d643ac51279e61439c4e7caae9b1212c7d.tar.gz
uhd-cb9c97d643ac51279e61439c4e7caae9b1212c7d.tar.bz2
uhd-cb9c97d643ac51279e61439c4e7caae9b1212c7d.zip
X300: Change Ethernet buffering
Ethernet buffering is now done so that most of the buffering is done in the socket buffers and multiple frames are only used to support the receive side offload of the socket I/O. Eliminates dropped packets at high full duplex rates.
Diffstat (limited to 'host/lib/transport')
-rw-r--r--host/lib/transport/super_recv_packet_handler.hpp2
-rw-r--r--host/lib/transport/super_send_packet_handler.hpp8
-rw-r--r--host/lib/transport/udp_common.hpp9
-rw-r--r--host/lib/transport/udp_zero_copy.cpp54
4 files changed, 44 insertions, 29 deletions
diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp
index fcb333a04..ea02f367d 100644
--- a/host/lib/transport/super_recv_packet_handler.hpp
+++ b/host/lib/transport/super_recv_packet_handler.hpp
@@ -392,7 +392,7 @@ private:
#endif
//bounds check before extract
- size_t num_packet_words32 = buff->size()/sizeof(uint32_t);
+ const size_t num_packet_words32 = buff->size()/sizeof(uint32_t);
if (num_packet_words32 <= _header_offset_words32){
throw std::runtime_error("recv buffer smaller than vrt packet offset");
}
diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp
index 5cba570a7..b90ea8afd 100644
--- a/host/lib/transport/super_send_packet_handler.hpp
+++ b/host/lib/transport/super_send_packet_handler.hpp
@@ -47,11 +47,11 @@ namespace sph {
**********************************************************************/
class send_packet_handler{
public:
- typedef boost::function<managed_send_buffer::sptr(double)> get_buff_type;
- typedef boost::function<void(void)> post_send_cb_type;
- typedef boost::function<bool(uhd::async_metadata_t &, const double)> async_receiver_type;
+ typedef std::function<managed_send_buffer::sptr(double)> get_buff_type;
+ typedef std::function<void(void)> post_send_cb_type;
+ typedef std::function<bool(uhd::async_metadata_t &, const double)> async_receiver_type;
typedef void(*vrt_packer_type)(uint32_t *, vrt::if_packet_info_t &);
- //typedef boost::function<void(uint32_t *, vrt::if_packet_info_t &)> vrt_packer_type;
+ //typedef std::function<void(uint32_t *, vrt::if_packet_info_t &)> vrt_packer_type;
/*!
* Make a new packet handler for send
diff --git a/host/lib/transport/udp_common.hpp b/host/lib/transport/udp_common.hpp
index e21d1fcc8..19457903b 100644
--- a/host/lib/transport/udp_common.hpp
+++ b/host/lib/transport/udp_common.hpp
@@ -13,8 +13,13 @@
namespace uhd{ namespace transport{
- // Jumbo frames are limited to 9000;
- static const size_t MAX_ETHERNET_MTU = 9000;
+ // Jumbo frames can be up to 9600 bytes;
+ static const size_t MAX_ETHERNET_MTU = 9600;
+
+#if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD)
+ // MacOS limits socket buffer size to 1 Mib
+ static const size_t MAX_BUFF_SIZE_ETH_MACOS = 0x100000; //1Mib
+#endif
typedef boost::shared_ptr<boost::asio::ip::udp::socket> socket_sptr;
diff --git a/host/lib/transport/udp_zero_copy.cpp b/host/lib/transport/udp_zero_copy.cpp
index 29dbd6c1e..3b3760334 100644
--- a/host/lib/transport/udp_zero_copy.cpp
+++ b/host/lib/transport/udp_zero_copy.cpp
@@ -22,9 +22,6 @@ using namespace uhd;
using namespace uhd::transport;
namespace asio = boost::asio;
-//A reasonable number of frames for send/recv and async/sync
-//static const size_t DEFAULT_NUM_FRAMES = 32;
-
/***********************************************************************
* Check registry for correct fast-path setting (windows only)
**********************************************************************/
@@ -211,7 +208,12 @@ public:
}
//set size for internal socket buffer
- template <typename Opt> size_t resize_buff(size_t num_bytes){
+ template <typename Opt> size_t resize_buff(size_t num_bytes)
+ {
+ #if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD)
+ //limit buffer resize on macos or it will error
+ num_bytes = std::min(num_bytes, MAX_BUFF_SIZE_ETH_MACOS);
+ #endif
Opt option(num_bytes);
_socket->set_option(option);
return get_buff_size<Opt>();
@@ -316,26 +318,31 @@ udp_zero_copy::sptr udp_zero_copy::make(
xport_params.num_recv_frames = size_t(hints.cast<double>("num_recv_frames", default_buff_args.num_recv_frames));
xport_params.send_frame_size = size_t(hints.cast<double>("send_frame_size", default_buff_args.send_frame_size));
xport_params.num_send_frames = size_t(hints.cast<double>("num_send_frames", default_buff_args.num_send_frames));
+ xport_params.recv_buff_size = size_t(hints.cast<double>("recv_buff_size", default_buff_args.recv_buff_size));
+ xport_params.send_buff_size = size_t(hints.cast<double>("send_buff_size", default_buff_args.send_buff_size));
- //extract buffer size hints from the device addr
- size_t usr_recv_buff_size = size_t(hints.cast<double>("recv_buff_size", xport_params.num_recv_frames * MAX_ETHERNET_MTU));
- size_t usr_send_buff_size = size_t(hints.cast<double>("send_buff_size", xport_params.num_send_frames * MAX_ETHERNET_MTU));
-
- if (hints.has_key("recv_buff_size")) {
- if (usr_recv_buff_size < xport_params.num_recv_frames * MAX_ETHERNET_MTU) {
- throw uhd::value_error((boost::format(
- "recv_buff_size must be equal to or greater than %d")
- % (xport_params.num_recv_frames * MAX_ETHERNET_MTU)).str());
- }
+ // Preserve legacy defaults
+ if (xport_params.recv_buff_size == 0) {
+ xport_params.recv_buff_size = xport_params.num_recv_frames * xport_params.recv_frame_size;
+ }
+ if (xport_params.send_buff_size == 0) {
+ xport_params.send_buff_size = xport_params.num_recv_frames * xport_params.send_frame_size;
}
+
+ // Resize receive buffer due to known issue where Intel X710 uses full MTU for every packet regardless of actual size
+ xport_params.recv_buff_size = xport_params.recv_buff_size * MAX_ETHERNET_MTU / xport_params.recv_frame_size;
- if (hints.has_key("send_buff_size")) {
- if (usr_send_buff_size < xport_params.num_send_frames * MAX_ETHERNET_MTU) {
- throw uhd::value_error((boost::format(
- "send_buff_size must be equal to or greater than %d")
- % (xport_params.num_send_frames * MAX_ETHERNET_MTU)).str());
+ #if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD)
+ //limit default buffer size on macos to avoid the warning issued by resize_buff_helper
+ if (not hints.has_key("recv_buff_size") and xport_params.recv_buff_size > MAX_BUFF_SIZE_ETH_MACOS)
+ {
+ xport_params.recv_buff_size = MAX_BUFF_SIZE_ETH_MACOS;
}
- }
+ if (not hints.has_key("send_buff_size") and xport_params.send_buff_size > MAX_BUFF_SIZE_ETH_MACOS)
+ {
+ xport_params.send_buff_size = MAX_BUFF_SIZE_ETH_MACOS;
+ }
+ #endif
udp_zero_copy_asio_impl::sptr udp_trans(
new udp_zero_copy_asio_impl(addr, port, xport_params)
@@ -343,9 +350,12 @@ udp_zero_copy::sptr udp_zero_copy::make(
//call the helper to resize send and recv buffers
buff_params_out.recv_buff_size =
- resize_buff_helper<asio::socket_base::receive_buffer_size>(udp_trans, usr_recv_buff_size, "recv");
+ resize_buff_helper<asio::socket_base::receive_buffer_size>(udp_trans, xport_params.recv_buff_size, "recv");
buff_params_out.send_buff_size =
- resize_buff_helper<asio::socket_base::send_buffer_size> (udp_trans, usr_send_buff_size, "send");
+ resize_buff_helper<asio::socket_base::send_buffer_size> (udp_trans, xport_params.send_buff_size, "send");
+
+ // Resize usable amount of receive buffer due to known issue where Intel X710 uses full MTU for every packet regardless of actual size
+ buff_params_out.recv_buff_size = buff_params_out.recv_buff_size * xport_params.recv_frame_size / MAX_ETHERNET_MTU;
return udp_trans;
}