Hi All, I've been working on an application that requires two receive streams and two transmit streams, written using the C++ API. I have run into a problem when transmitting packets and I am hoping that someone has seen something similar and/or may be able to shed some light on this.
My application is streaming two receive and two transmit channels, each at 100 Msps over dual 10GigE interfaces (NIC is Intel X520-DA2). I have two receive threads, each calling recv() on separate receive streams, and two transmit threads each calling send(), also on separate transmit streams. Each receive thread copies samples into a large circular buffer. Each transmit thread reads samples from the buffer to be sent in the send() call. So, each receive thread is paired with a transmit thread through a shared circular buffer with some mutex locking to prevent simultaneous access to shared circular buffer memory. I did read in the UHD manual that recv() is not thread safe. I assumed that this meant that recv() is not thread safe when called on the same rx_streamer from two different threads but would be ok when called on different rx_streamers. If this is not the case, please let me know. On to my problem... After running for several minutes, one of the transmit threads will get stuck in the send() call. Using strace to monitor the system calls it appears that the thread is in a loop continuously calling the poll() and recvfrom() system calls from within the UHD API. Here's the output of strace attached to one of the transmit threads after this has occurred. These are the only two system calls that get logged for the transmit thread once this problem occurs. 11:19:04.564078 poll([{fd=62, events=POLLIN}], 1, 100) = 0 (Timeout) 11:19:04.664276 recvfrom(62, 0x5619724e90c0, 1472, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable) 11:19:04.664381 poll([{fd=62, events=POLLIN}], 1, 100) = 0 (Timeout) 11:19:04.764600 recvfrom(62, 0x5619724e90c0, 1472, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable) 11:19:04.764699 poll([{fd=62, events=POLLIN}], 1, 100) = 0 (Timeout) 11:19:04.864906 recvfrom(62, 0x5619724e90c0, 1472, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable) This partial stack trace shows that the transmit thread is stuck in the while loop in the tx_flow_ctrl() function. I think this is happening due to missed or missing TX flow control packets. #0 0x00007fdb8fe4fbf9 in __GI___poll (fds=fds@entry=0x7fdb167fb510, nfds=nfds@entry=1, timeout=timeout@entry=100) at ../sysdeps/unix/sysv/linux/poll.c:29 #1 0x00007fdb9186de45 in poll (__timeout=100, __nfds=1, __fds=0x7fdb167fb510) at /usr/include/x86_64-linux-gnu/bits/poll2.h:46 #2 uhd::transport::wait_for_recv_ready (timeout=0.10000000000000001, sock_fd=<optimized out>) at /home/aconrad/rfnoc/src/uhd/host/lib/transport/udp_common.hpp:59 #3 udp_zero_copy_asio_mrb::get_new (index=@0x55726266f6e8: 28, timeout=<optimized out>, this=<optimized out>) at /home/aconrad/rfnoc/src/uhd/host/lib/transport/udp_zero_copy.cpp:79 #4 udp_zero_copy_asio_impl::get_recv_buff (this=0x55726266f670, timeout=<optimized out>) at /home/aconrad/rfnoc/src/uhd/host/lib/transport/udp_zero_copy.cpp:226 #5 0x00007fdb915d48cc in tx_flow_ctrl (fc_cache=..., async_xport=..., endian_conv=0x7fdb915df600 <uhd::ntohx<unsigned int>(unsigned int)>, unpack=0x7fdb918b1090 <uhd::transport::vrt::chdr::if_hdr_unpack_be(unsigned int const*, uhd::transport::vrt::if_packet_info_t&)>) at /home/aconrad/rfnoc/src/uhd/host/lib/usrp/device3/device3_io_impl.cpp:345 The poll() and recvfrom() calls are in the udp_zero_copy_asio_mrb::get_new() function in udp_zero_copy.cpp. Has anyone seen this problem before or have any suggestions on what else to look at to further debug this problem? I have not yet used Wireshark to see what's happening on the wire, but I'm planning to do that. Also note that, if I run a single transmit/receive pair (instead of two) I don't see this problem and everything works as I expect. My hardware is an X310 with the XG firmware and dual SBX-120 daughterboards. Here are the software versions I'm using, as displayed by the UHD API when the application starts. [00:00:00.000049] Creating the usrp device with: addr=192.168.30.2,second_addr=192.168.40.2... [INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_4.0.0.rfnoc-devel-788-g1f8463cc The host is a Dell PowerEdge R420 with 24 CPU cores and 24 GB ram. I think the clock speed is a little lower than recommended at 2.7 GHz but thought that I could distribute the work load across the various cores to account for that. Also, I have followed the instructions to setup dual 10 GigE interfaces for the X310 here, https://kb.ettus.com/Using_Dual_10_Gigabit_Ethernet_on_the_USRP_X300/X310. Any help is appreciated. Thanks, Al
_______________________________________________ USRP-users mailing list USRP-users@lists.ettus.com http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com