USRP High-Bandwidth Streaming With DPDK

Updated Aug 28, 2026

Environment

Hardware

  • Ettus USRP X440
  • Ettus USRP X420
  • Ettus USRP X410
  • USRP X310
  • USRP X300
  • USRP N321
  • USRP N320
  • USRP N310
  • USRP N300
  • USRP E320

Operating System

  • Linux

Overview

Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to send() or recv() would cause a context switch and invite the kernel's scheduler to replace the streaming thread with another process. Because the Linux scheduler is optimized to distribute CPU time fairly across multiple workloads, timing-critical UHD streaming threads can experience scheduling delays or be migrated between CPU cores. The resulting overhead and latency variations can make it difficult to achieve reliable real-time streaming performance at higher data rates. 
The Data Plane Development Kit (DPDK) is a high-speed packet processing framework that enables a kernel bypass for supported network drivers. By running the packet processing path entirely in user space, avoiding unnecessary context switches, and pinning I/O processing threads to dedicated CPU cores, UHD and DPDK significantly reduce scheduler-induced latency spikes and lower packet-processing overhead. This approach improves determinism and enables more reliable high-rate streaming between host systems and supported USRP devices. 
This article provides an end-to-end guide for configuring a Linux host for high-bandwidth USRP streaming using DPDK. The guide covers supported hardware, UHD and DPDK compatibility, software installation, host operating system configuration, network adapter configuration, performance tuning, and streaming validation.
 

Recommended Host Specifications

The following host specifications are recommended for high-bandwidth UHD and DPDK streaming applications:
  • 32 CPU cores
  • 32 GB RAM
  • CPU frequency of 3 GHz to 4 GHz or higher
  • PCIe Gen3 x16 or higher expansion slots
For the minimum number of CPU cores required for a specific streaming configuration, refer to 6.7 Calculate the Required Core Range in the 6. GRUB Configuration section. In addition to the DPDK and UHD streaming cores, reserve at least five CPU cores for Linux operating system services and background processes.
Systems with fewer CPU cores, lower clock frequencies, less memory, or limited PCIe bandwidth may experience reduced streaming performance at higher sample rates.
 

Host Network Cards

DPDK is supported on many Intel and Mellanox 10 Gigabit Ethernet and 100 Gigabit Ethernet network adapters. The following host network cards have been tested by Getting Started with DPDK and UHD. For a complete list of supported adapters, refer to the official DPDK documentation. 
  • Intel X520-DA1 (1 × 10 GbE) 
  • Intel X520-DA2 (2 × 10 GbE) 
  • Intel X710-DA2 (2 × 10 GbE) 
  • Intel X710-DA4 (4 × 10 GbE)
  • Intel XL710-QDA2 (2 × 40 GbE breakout to 4 × 10 GbE) 
  • Intel E810-CQDA1 (1 × 100 GbE and 1 × 4 × 10 GbE) 
  • Intel E810-CQDA2 (1 × 100 GbE and 2 × 4 × 10 GbE; this adapter does not support 2 × 100 GbE operation) 
  • Intel E810-2CQDA2 (1 × 100 GbE and 2 × 4 × 10 GbE; 2 × 100 GbE configurations are possible with additional configuration) 
  • Intel E830-CQDA2 (2 × 100 GbE or 8 × 10 GbE) 
  • Mellanox ConnectX-4 Lx MCX4121A-ACAT (2 × 10 GbE) 
  • Mellanox ConnectX-5 EN MCX515A-CCAT (2 × 100 GbE or 2 × 10 GbE) 
  • Mellanox ConnectX-5 EN MCX516A-CCAT (2 × 100 GbE or 2 × 10 GbE) 
  • Mellanox ConnectX-5 Ex EN MCX516A-CDAT (2 × 100 GbE or 2 × 10 GbE) 
  • Mellanox ConnectX-6 Dx EN MCX623106AN-CDAT (2 × 100 GbE) 
  • NI Dual 100 Gigabit Ethernet PCIe Interface Kit (Part Number 788216-01)

 

UHD and DPDK Compatibility

The following UHD and DPDK version combinations are supported.
  • UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11
  • UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11
  • UHD 4.10 can use any version of DPDK from 19.11 to 25.11

 

Tested Ubuntu Versions

The procedures in this article have been validated using the following Ubuntu releases:
  • Ubuntu 22.04 LTS
  • Ubuntu 24.04 LTS
  • Ubuntu 26.04 LTS

 

Connectivity Requirements

Before starting the configuration process, connect the USRP management interface and at least one data interface to the host system.
The minimum required connections are:
  • One management connection between the host and the USRP management port.
  • At least one streaming connection using an SFP+, QSFP+, or QSFP28 interface, depending on the USRP model and network adapter.
The management interface is used for device discovery, image updates, FPGA image loading, and device management operations. The data interfaces are used for UHD and DPDK streaming traffic.
For maximum streaming performance, use all available streaming interfaces supported by the USRP and host network adapter.
 

1. Install Required Dependencies

Before installing DPDK and UHD, update the package repository on the host system:
$ sudo apt-get update

Ubuntu 22.04 LTS

Install the required packages:

$ sudo apt-get -y install \
  autoconf automake build-essential ccache cmake cpufreq-set cpufrequtils doxygen ethtool fort77 g++ \
  gir1.2-gtk-3.0 git gobject-introspection gpsd gpsd-clients inetutils-tools \
  libasound2-dev libboost-all-dev libcomedi-dev libcppunit-dev libfftw3-bin libfftw3-dev libfftw3-doc \
  libfontconfig1-dev libgmp-dev libgps-dev libgsl-dev liblog4cpp5-dev libncurses5 libncurses5-dev \
  libpulse-dev libqt5opengl5-dev libqwt-qt5-dev libsdl1.2-dev libtool libudev-dev \
  libusb-1.0-0 libusb-1.0-0-dev libusb-dev libxi-dev libxrender-dev \
  libzmq3-dev libzmq5 ncurses-bin python3-cheetah python3-click python3-click-plugins \
  python3-click-threading python3-dev python3-docutils python3-gi python3-gi-cairo python3-gps \
  python3-lxml python3-mako python3-numpy python3-opengl python3-pyqt5 python3-requests \
  python3-scipy python3-setuptools python3-six python3-sphinx python3-yaml python3-zmq \
  python3-ruamel.yaml swig wget python3-pyelftools \
  rdma-core ibverbs-providers libibverbs-dev librdmacm-dev libibumad-dev meson

Ubuntu 24.04 LTS and Ubuntu 26.04 LTS

Install the required packages:

sudo apt-get -y install \
  meson libnuma-dev python3-pip autoconf automake build-essential ccache cmake cpufreq-set cpufrequtils \
  doxygen ethtool fort77 g++ gir1.2-gtk-3.0 git gobject-introspection gpsd gpsd-clients inetutils-tools \
  libasound2-dev libboost-all-dev libcomedi-dev libcppunit-dev libfftw3-bin libfftw3-dev libfftw3-doc \
  libfontconfig1-dev libgmp-dev libgps-dev libgsl-dev liblog4cpp5-dev libncurses6 libncurses-dev \
  libpulse-dev libqt5opengl5-dev libqwt-qt5-dev libsdl1.2-dev libtool libudev-dev \
  libusb-1.0-0 libusb-1.0-0-dev libusb-dev libxi-dev libxrender-dev libzmq3-dev libzmq5 ncurses-bin \
  python3-cheetah python3-click python3-click-plugins python3-click-threading python3-dev \
  python3-docutils python3-gi python3-gi-cairo python3-gps python3-lxml python3-mako python3-numpy \
  python3-opengl python3-pyqt5 python3-requests python3-scipy python3-setuptools python3-six \
  python3-sphinx python3-yaml python3-zmq python3-ruamel.yaml swig wget \
  python3-pygccxml libjs-mathjax python3-pyqtgraph python3-pyelftools \
  rdma-core ibverbs-providers libibverbs-dev librdmacm-dev libibumad-dev

2. Install DPDK

This section describes how to install DPDK from source on Ubuntu Linux.

  1. Download your desired DPDK release package from https://core.dpdk.org/download/.
  2. Create a working directory for the DPDK and UHD source code:
    $ mkdir workarea
    $ cd workarea
  3. Copy the DPDK package to workarea folder and after extract it:
    $ tar -xvf dpdk-23.11.4.tar.xz
    $ cd dpdk-stable-23.11.4
  4. Build and Install DPDK:
    $ meson setup build
    $ cd build
    $ ninja
    $ sudo meson install
    $ sudo ldconfig

 After successfully completing these steps, DPDK is installed and ready for use with UHD.

3. Install UHD

DPDK support is detected during the UHD build process. To build UHD with DPDK support, install DPDK before building UHD and build UHD from source.

  1. Clone the UHD repository:
    $ cd ~/workarea
    $ git clone https://github.com/EttusResearch/uhd
    $ cd uhd
  2. Checkout to the desired UHD release:
    $ git checkout <version>
    Example:
    $ git checkout v4.10.0.0
  3. Build and Install UHD:
    $ cd host
    $ mkdir build
    $ cd build
    $ cmake ..
    $ make -j $(nproc)
    $ make test
    $ sudo make install
    $ sudo ldconfig
  4. Download the UHD image packages:
    $ sudo uhd_images_downloader

After completing these steps, UHD 4.10 is installed and ready for DPDK configuration.

4. Update MPM-Based USRP Filesystems

Some USRP devices require filesystem or FPGA image updates to match the installed UHD version. Updating the device images helps ensure software compatibility and access to the latest device features.
  1. For embedded USRP platforms, download the device-specific images:
    $ sudo uhd_images_downloader -t mender -t <usrp> --yes
  2. Verify communication with the device:
    $ uhd_find_devices
  3. Locate the downloaded image files:
    $ cd /usr/local/share/uhd/images
  4. Transfer the appropriate image package to the USRP management interface:
    $ scp <image-file> root@<management-ip>:~/
  5. Connect to the device and install the image:
    $ ssh root@<management-ip>
    $ mender install <image-file>
    $ reboot
  6. Reconnect to the device and commit the update:
    $ ssh root@<management-ip>
    $ mender commit
  7. If required, load the FPGA image corresponding to the target USRP configuration:
    $ uhd_image_loader --args="addr=127.0.0.1,type=<usrp-type>,fpga=<fpga>"
    Example:
    $ uhd_image_loader --args="addr=127.0.0.1,type=x4xx,fpga=CG_400"

Refer to the UHD documentation for the appropriate image package names and FPGA configuration arguments for the target device family.

5. Host Performance Tuning

Host performance tuning can significantly improve DPDK streaming performance and help achieve reliable operation at high sample rates. The following recommendations are based on validated DPDK streaming deployments and are intended to reduce scheduling latency, improve CPU determinism, and maximize network throughput.

5.1 Configure the CPU Performance Governor

To prevent the operating system from dynamically scaling CPU frequencies, configure all CPU cores to use the performance governor:
$ for ((i=0;i<$(nproc --all);i++)); do sudo cpufreq-set -c $i -r -g performance; done

Note: This setting is not persistent across reboots and must be reapplied after every host power cycle or restart. Consider implementing the command as part of a startup service if the system is frequently rebooted.

 

5.2 Verify PCIe Link Width and Speed

High-bandwidth streaming performance can be limited by the PCIe connection between the NIC and the host system. Before performing streaming tests, verify that the network adapter is operating at the expected PCIe link width and speed.
First, identify the PCI address of the network adapter:
$ lspci | grep Ethernet

Output Example:

b3:00.0 Ethernet controller: Intel Corporation Ethernet Controller E810-CQDA2
or
02:00.0 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5]
Display detailed PCIe information for the adapter:
$ sudo lspci -s b3:00.0 -vv | grep -E "LnkCap|LnkSta"

Output Example:

LnkCap: Port #0, Speed 8GT/s, Width x16
LnkSta: Speed 8GT/s, Width x16
For optimal UHD and DPDK streaming performance, NI recommends installing the network adapter in a PCIe Gen3 x16 or higher slot whenever possible.
 

5.3 Increase Network Socket Buffer Sizes

Increasing the Linux network socket buffer sizes can help reduce packet loss and improve streaming stability when operating at high sample rates.
  1. Create a dedicated sysctl configuration file:
    $ sudo nano /etc/sysctl.d/99-usrp.conf
  2. Add the following parameters:
    net.core.wmem_max=625000000
    net.core.rmem_max=625000000
    net.core.wmem_default=625000000
    net.core.rmem_default=625000000
  3. Apply the configuration:
    $ sudo sysctl --system
  4. You can verify the configured values using:
    $ sysctl net.core.wmem_max
    $ sysctl net.core.rmem_max

5.4 Enable Real-Time Runtime Sharing

Enabling real-time runtime sharing can improve the behavior of real-time streaming applications by allowing real-time tasks to share unused runtime resources.
  1. Switch to the root user:
    $ sudo -s
  2. Navigate to the scheduler debug interface:
    $ cd /sys/kernel/debug/sched
  3. Verify the current setting:
    $ cat features | tr ' ' '\n' | grep RUNTIME_SHARE
    Example output before enabling the feature:
    NO_RT_RUNTIME_SHARE
  4. Enable real-time runtime sharing:
    $ echo RT_RUNTIME_SHARE > features
  5. Verify the configuration:
    $ cat features | tr ' ' '\n' | grep RUNTIME_SHARE
    Expected output:
    RT_RUNTIME_SHARE

Note: This setting is not persistent across system reboots and must be reapplied after every host power cycle unless it is configured through an automated startup mechanism.

5.5 Increase Process Priority

Beyond elevating streaming thread priority, one can also increase the nice priority level to maximum to increase the amount of CPU time for the process and its thread by prepending the following to the command being issued:

$ sudo nice -n -20 <application>

5.6 Limit Execution CPUs/Cores

With Linux one can limit the cores being used by the threads in a process via a taskset prepended to a command being executed. When combining with the other techniques listed here, one can fairly well constrain a process and its thread to specific cores and give them maximum CPU time.

$ taskset -c "<core-numbers>"

5.7 Streaming on Multiple Channels using 1 Thread Per Stream

If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. This can be accomplished with the benchmark_rate example by using the parameter --multi_streamer

5.8 Elevated Streaming Thread Priority

In UHD 4, streaming thread priorities can be elevated with the uhd::set_thread_priority_safe() function call. This can be accomplished with the benchmark_rate example by using parameter --priority high

5.9 Full Rate on X3xx

If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:

enable_tx_dual_eth=1

5.10 Increase Frame Size and Number of Frames

If you experience overflows or underflows at higher streaming rates, increase the UHD transport frame size and number of transport frames by adding the following device arguments:
send_frame_size=<value>,recv_frame_size=<value>,num_send_frames=<value>,num_recv_frames=<value>

Recommended values:

  • 10 GbE (SFP+) - 4096
  • 100 GbE (QSFP) - 8192

5.11 Disable Hyper-threading

In some applications which require the highest possible CPU performance per core, disabling hyper-threading can provide roughly a 10% increase in core performance, at the cost of having fewer core threads. Hyper-threading is disabled within the BIOS and how to do this varies by motherboard manufacturer. With other techniques listed here, disabling hyper-threading should only be done as a last resort to eek absolute maximum performance from the CPU.

5.12 Verify NUMA Configuration

For multi-CPU systems, ensure that all isolated DPDK and UHD cores belong to the same NUMA node. Using cores from multiple NUMA nodes may result in periodic overflows, underruns, or reduced streaming performance.
Verify the system NUMA topology:
$ numactl --hardware
For best performance, use CPU cores from a single NUMA node for streaming.

5.13 Configure Streaming Warmup Delays

When starting high-bandwidth streaming applications, the host, NIC, DPDK transport, and USRP device may require a short amount of time to initialize before streaming begins. In some configurations, this can result in overruns, underruns, or dropped samples during the first few seconds of a streaming test.
To provide additional startup time, configure receive and transmit delays using the following parameters:
--rx_delay <seconds>
--tx_delay <seconds>
NI recommends using timed RX and TX streaming and configuring a one to two second warmup delay when observing streaming issues immediately after application startup. This allows the host and USRP streaming pipelines to stabilize before high-rate data transfers begin.

6. Grub Configuration

DPDK requires huge pages to be enabled and enough memory to be reserved for DPDK packet buffers. In addition, dedicating CPU resources to DPDK and UHD can improve streaming performance by reducing operating system interference, minimizing latency spikes, and improving determinism.

6.1 Huge Pages

DPDK allocates packet buffers from huge page memory. If huge pages are not available, DPDK cannot initialize properly. There are multiple ways to configure huge pages in Linux; however, reserving them during boot through GRUB is one of the simplest and most reliable methods.
The following parameters reserve eight 1 GB huge pages and enable the IOMMU features required by DPDK:
iommu=pt intel_iommu=on default_hugepagesz=1G hugepagesz=1G hugepages=8

6.2 Isolate Streaming Cores

The isolcpus parameter can improve streaming performance by preventing the Linux scheduler from assigning normal operating system tasks to the selected CPU cores. This allows those cores to be dedicated to DPDK packet processing and UHD streaming threads.

isolcpus=<cores>

6.3 Disable Scheduler Ticks

The Linux scheduler periodically interrupts running processes to perform housekeeping activities. The nohz_full parameter suppresses these periodic scheduler ticks on selected cores, reducing interruptions and improving real-time performance.
nohz_full=<cores>

6.4 Move RCU Processing

Linux uses Read-Copy-Update (RCU) callbacks for various kernel operations. By default, these callbacks can execute on any CPU core. The rcu_nocbs parameter moves this work away from the selected streaming cores, further reducing operating system activity on those CPUs.
rcu_nocbs=<cores>

6.5 Enable Tick Skewing

The skew_tick parameter offsets periodic timer interrupts across CPU cores instead of triggering them simultaneously. This can reduce contention between CPU cores and improve overall system responsiveness during high-bandwidth streaming workloads.
skew_tick=1

6.6 Disable CPU Security Mitigations (Optional)

Modern Linux kernels enable several security mitigations to protect against vulnerabilities such as Spectre, Meltdown, L1TF, and related side-channel attacks. While these protections improve system security, they can introduce additional overhead and increase context-switch latency.
On dedicated USRP streaming systems, disabling these mitigations can improve overall streaming performance. Depending on the processor architecture and workload, performance improvements of 10-15% may be observed.
 

Important: Disabling these protections reduces system security and is only recommended for dedicated test systems that require maximum performance and are not connected to untrusted networks.

 
The recommended approach is to disable all mitigations with:
mitigations=off
Alternatively, individual mitigations can be disabled with:
pti=off spectre_v2=off l1tf=off nospec_store_bypass_disable no_stf_barrier
These parameters disable several CPU vulnerability mitigations that can impact system performance.

6.7 Calculate the Required Core Range

Before configuring the GRUB parameters, determine how many CPU cores are required for DPDK and UHD.
Allocate:
  • One core for the DPDK management thread.
  • One core for each DPDK network connection.
  • One core for each RX stream.
  • One core for each TX stream.
Determine the available CPU cores on the host:
$ lscpu | grep On-line
When selecting streaming cores, start from the highest-numbered CPU cores available on the system.
For example, a 4 × 4 USRP streaming application using two DPDK network connections requires:
1 DPDK core
2 NIC cores
4 RX stream cores
4 TX stream cores
for a total of 11 dedicated cores.
Note: start allocating cores on your CPU starting from the last core.

6.8 Apply the GRUB Configuration

After calculating the streaming core range, open the GRUB configuration file:

$ sudo nano /etc/default/grub
Update GRUB_CMDLINE_LINUX_DEFAULT:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash iommu=pt intel_iommu=on isolcpus=<cores> nohz_full=<cores> rcu_nocbs=<cores> default_hugepagesz=1G hugepagesz=1G hugepages=8 mitigations=off skew_tick=1"
Apply the changes and reboot the system:
$ sudo update-grub
$ sudo reboot

7. Prepare the UHD Configuration File

Before configuring UHD for DPDK operation, identify the MAC addresses of the network interfaces that will be used for USRP streaming.
Display the installed network interfaces:
$ ip a
Record the MAC address of each interface that will be assigned to DPDK.
Create the UHD configuration file:
$ sudo su
$ mkdir -p /root/.config
$ nano /root/.config/uhd.conf
The uhd.conf file defines the DPDK transport configuration used by UHD. An example configuration is shown below:
[use_dpdk=1]
dpdk_mtu=9000
dpdk_driver=/usr/local/lib/x86_64-linux-gnu/dpdk/pmds-<version>
dpdk_corelist=2,3,4
dpdk_num_mbufs=131072
dpdk_mbuf_cache_size=315
dpdk_link_timeout=10000
dpdk_num_desc=8192

[dpdk_mac=<mac-address-1>]
dpdk_lcore=3
dpdk_ipv4=192.168.10.1/24

[dpdk_mac=<mac-address-2>]
dpdk_lcore=4
dpdk_ipv4=192.168.20.1/24
Note: For USRP X420 and USRP X440 100 GbE deployments, NI recommends reserving at least 16 GB of huge page memory and configuring dpdk_num_mbufs to a value greater than 262144.
 
Verify and update the following fields according to your system configuration:
  • dpdk_mac
    The dpdk_mac entries must match the MAC addresses of the NIC ports used for DPDK streaming.
    Important: MAC addresses must be entered in lowercase.
  • dpdk_driver
    The dpdk_driver field specifies the location of the DPDK PMD drivers.
    When DPDK is built and installed from source, the default location is:
    /usr/local/lib/x86_64-linux-gnu/dpdk/pmds-<version>
    Update this path if the PMD drivers were installed to a different location on your system.
  • dpdk_corelist and dpdk_lcore
    The dpdk_corelist parameter defines the CPU cores that DPDK can use.
    The dpdk_lcore parameter assigns a dedicated CPU core to a specific NIC connection.
    There must be:
    • One core for the main DPDK thread.
    • One dedicated core for each DPDK network connection.
    The cores assigned in dpdk_corelist should be part of the isolated CPU range configured in the GRUB configuration.
  • dpdk_ipv4
    The dpdk_ipv4 parameter defines the IP address assigned to each DPDK interface.
    Configure these addresses to match the network configuration of the connected USRP device.
    Typical default USRP data port addresses include:
    • X3xx: 192.168.30.2, 192.168.40.2
    • N3xx: 192.168.10.2, 192.168.20.2
    • E320: 192.168.10.2
    • X4xx: 192.168.10.2, 192.168.20.2
    The host-side DPDK interfaces should be configured within the same subnet as the corresponding USRP data interfaces.

Additional DPDK Parameters

The following parameters are commonly adjusted when tuning streaming performance:

  • dpdk_mtu specifies the interface MTU. The MTU should typically match the jumbo frame configuration used by the host NIC.
  • dpdk_num_mbufs controls the number of packet buffers allocated by DPDK.
  • dpdk_mbuf_cache_size defines the per-core packet buffer cache size.
  • dpdk_link_timeout specifies the link initialization timeout in milliseconds.
  • dpdk_num_desc configures the number of descriptors used for packet processing (4096 for 10GbE SFP and 8192 for 100GbE QSFP).
For high-bandwidth streaming applications, increasing dpdk_num_desc and dpdk_num_mbufs may help reduce packet loss and improve sustained throughput.

Additional config information: UHD DPDK configuration file is in the UHD manual 

8. Configure Network Interface Cards for DPDK

The procedure for configuring a network adapter for DPDK depends on the NIC vendor and the DPDK driver being used.

8.1 Intel Network Adapters

8.1.1 Update NIC Drivers

For best UHD and DPDK performance, NI recommends installing the latest vendor-provided network adapter drivers before configuring DPDK.

For Intel X520, X540, and X550 adapters, download the latest Intel 500 Series driver package from: Intel® Network Adapter Driver for PCIe* Intel® 10 Gigabit Ethernet Network Connections under Linux* 
For Intel X710, XL710, and X722 adapters, download the latest Intel 700 Series driver package from: Intel® Network Adapter Driver for PCIe* 40 Gigabit Ethernet Network Connections under Linux* 
For Intel E810 and E830 adapters, download the latest Intel 800 Series driver package from: Intel® Network Adapter Driver for 800 Series Devices under Linux* 

After downloading the driver package, extract and install it:

$ tar -xzvf <driver-package>.tar.gz
$ cd <driver-package>/src
$ make -j $(nproc)
$ sudo make install
$ sudo ldconfig
Verify the Driver Version with command:
$ ethtool -i <interface>
Example output:
Intel X520
driver: ixgbe
version: <version>

Intel X710
driver: i40e
version: <version>

Intel E810
driver: ice
version: <version>

8.1.2 DPDK Driver Binding

Intel Ethernet adapters typically use the vfio-pci driver for DPDK operation. Before UHD can access the NIC through DPDK, the network interface must be detached from the Linux kernel driver and rebound to vfio-pci.

Load the VFIO driver:
$ sudo modprobe vfio-pci

Next, you will need to manually rebind the NIC to the vfio-pci drivers.

First, identify the PCI address your NIC is at via the following command, noting that for older DPDK the command does not contain the trailing .py

$ sudo dpdk-devbind.py -s

Example Output:

Network devices using kernel driver
===================================
0000:00:1f.6 'Ethernet Connection (2) I219-V' if=eno1 drv=e1000e unused=vfio-pci Active
0000:b3:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection' if=enp179s0f0 drv=ixgbe unused=vfio-pci Active
0000:b3:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection' if=enp179s0f1 drv=ixgbe unused=vfio-pci Active
Identify the PCI address of the network interface that will be used for DPDK. In the example above, the second port uses PCI address:
b3:00.0
Bind the interface to vfio-pci:
$ sudo dpdk-devbind.py --bind=vfio-pci b3:00.0
If the interface is currently in use by Linux, the following message may be displayed:
Warning: routing table indicates that interface 0000:b3:00.0 is active. Not modifying
This message indicates that the interface is currently active and managed by the Linux networking stack. Before the interface can be bound to vfio-pci, it must be disconnected from the operating system.
Disable the interface and bind one more time:
$ sudo ip link set dev <interface> down
Verify the driver assignment:
$ sudo dpdk-devbind.py --status
The interface should now appear under Network devices using DPDK-compatible driver.
Example Output:
Network devices using DPDK-compatible driver
============================================
0000:b3:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection' drv=vfio-pci unused=ixgbe
Network devices using kernel driver
===================================
0000:00:1f.6 'Ethernet Connection (2) I219-V 15b8' if=eno1 drv=e1000e unused=vfio-pci *Active*
0000:b3:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' if=enp179s0f1 drv=ixgbe unused=vfio-pci *Active*
Once the interface is bound to vfio-pci, it can be assigned to DPDK through the UHD configuration file.

8.2 Mellanox Network Adapters

8.2.1 Update NIC Drivers

For best UHD and DPDK performance, NI recommends installing the latest Mellanox OFED driver package before configuring DPDK.
Download the appropriate Mellanox OFED package for your Linux distribution from this link Linux InfiniBand Drivers.
Extract and install the package:

$ tar -xzf MLNX_OFED_LINUX-<version>.tgz
$ cd MLNX_OFED_LINUX-<version>
$ sudo ./mlnxofedinstall --add-kernel-support --without-fw-update
$ sudo reboot
Verify the driver version after the system reboots:
$ ethtool -i <interface>
You should see output similar to:
driver: mlx5_core
version: <version>

8.2.2 DPDK Driver Binding

Unlike Intel network adapters, Mellanox network adapters do not require manual binding to the vfio-pci driver.
Mellanox adapters use the mlx5 DPDK Poll Mode Driver (PMD), which works directly with the Mellanox kernel drivers. As a result, no additional DPDK driver binding steps are typically required before using UHD with DPDK. 

8.2.3 Configure Ring Buffer Size

For high-bandwidth streaming applications, increase the NIC transmit and receive ring buffer sizes.
$ sudo ethtool -G <interface> tx 8192 rx 8192
Verify the configured values:
$ sudo ethtool -g <interface>

8.2.4 Configure Jumbo Frames

Configure jumbo frames on the host network interface:
$ sudo ip link set dev <interface> mtu 9000
Verify the MTU configuration:
$ ip link show <interface>

8.2.5 Enable Pause Frames on Supported USRP Devices

When using Mellanox network adapters, enabling Ethernet pause frames on the USRP may improve streaming stability during sustained high-bandwidth transfers.
 
Note: Pause frame configuration is recommended only when using Mellanox network adapters. This configuration is applicable only to USRP devices running the MPM (Management, Peripheral, and Monitoring) framework, such as the N3xx, E320, and X4xx families. Pause frame settings are not persistent and are reset after the USRP is rebooted or power-cycled. After each device restart, reapply the pause frame configuration if required.
 
Connect to the USRP using SSH:
$ ssh root@<management-ip>
Enable pause frames on the first interface:
$ ethtool -A sfp0 tx on
Enable pause frames on the second interface:
$ ethtool -A sfp1 tx on
Verify the configuration:
$ ethtool -a sfp0
$ ethtool -a sfp1

Results

The following results were achieved after applying the recommendations described in this article, including DPDK configuration, host tuning, CPU isolation, huge page allocation, and NIC optimization. Actual performance may vary depending on the host CPU, memory configuration, network adapter, firmware version, FPGA image, and operating system configuration.

USRP N300/N310 Series

Dual-Port 10 GbE DPDK

  • 2 RX @ 150 MS/s
  • 2 TX @ 150 MS/s
  • 2 RX + 2 TX @ 150 MS/s

 

USRP N320/N321 Series

Dual-Port 10 GbE DPDK

  • 2 RX @ 250 MS/s
  • 2 TX @ 250 MS/s
  • 2 RX + 2 TX @ 250 MS/s

 

USRP X300/X310 Series

Dual-Port 10 GbE DPDK

  • 2 RX @ 200 MS/s
  • 2 TX @ 200 MS/s
  • 2 RX + 2 TX @ 200 MS/s

 

USRP X410

Dual-Port DPDK

  • 4 RX + 4 TX @ 491.52 MS/s
  • 4 RX @ 491.52 MS/s
  • 4 TX @ 491.52 MS/s

 

USRP X420

Dual-Port 100 GbE DPDK (CG_1000 FPGA Image)

  • 2 RX @ 1250 MS/s
  • 2 TX @ 1250 MS/s
  • 2 RX + 2 TX @ 1250 MS/s

Single-Port 100 GbE DPDK (CG_1000 FPGA Image)

  • 1 RX @ 1250 MS/s
  • 1 TX @ 1250 MS/s
  • 1 RX + 1 TX @ 1250 MS/s

10 GbE DPDK (X4_1000 FPGA Image)

  • 2 RX @ 250 MS/s
  • 2 TX @ 250 MS/s
  • 2 RX + 2 TX @ 250 MS/s

 

USRP X440

CG_400 FPGA Image

Dual-Port DPDK
  • 6 RX @ 500 MS/s
  • 8 RX @ 400 MS/s
  • 6 TX @ 500 MS/s
  • 8 TX @ 450 MS/s
  • 4 RX + 4 TX @ 500 MS/s
  • 8 RX + 8 TX @ 250 MS/s

CG_1600 FPGA Image

Dual-Port DPDK
  • 2 RX @ 1000 MS/s
  • 2 TX @ 1800 MS/s
  • 2 RX + 2 TX @ 1000 MS/s

Running UHD Applications with DPDK

UHD applications, including GNU Radio flowgraphs, can use DPDK by adding the following device argument:
use_dpdk=1

Important: UHD applications must be run as the root user when using DPDK. Use sudo to launch the application or switch to the root user using sudo su.

The following example demonstrates benchmark_rate using DPDK transport:

$ cd /usr/local/lib/uhd/examples

$ sudo nice -n -20 taskset -c 13-20 ./benchmark_rate \
  --args="addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=192.168.30.2,\
  use_dpdk=1,type=x4xx,send_frame_size=8192,recv_frame_size=8192,\
  num_send_frames=8192,num_recv_frames=8192,master_clock_rate=500e6" \
  --rx_rate 500e6 \
  --tx_rate 500e6 \
  --rx_channels 0,1,2,3 \
  --tx_channels 0,1,2,3 \
  --rx_delay 1 \ 
  --tx_delay 1 \
  --priority high \
  --multi_streamer

[INFO] [UHD] linux; GNU C++ version 13.3.0; Boost_108300; DPDK_23.11; UHD_4.10.0.HEAD-0-g2af4ddb9
EAL: Detected CPU lcores: 24
EAL: Detected NUMA nodes: 1
EAL: Detected shared linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'VA'
EAL: Probe PCI driver: mlx5_pci (15b3:1017) device: 0000:a2:00.0 (socket 0)
EAL: Probe PCI driver: mlx5_pci (15b3:1017) device: 0000:a2:00.1 (socket 0)
TELEMETRY: No legacy callbacks, legacy socket not created
[00:00:00.000132] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=192.168.30.2,use_dpdk=1,type=x4xx,send_frame_size=8192,recv_frame_size=8192,num_send_frames=8192,num_recv_frames=8192,master_clock_rate=500e6...
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=192.168.30.2,type=x4xx,product=x410,serial=3246861,name=ni-x4xx-3246861,fpga=CG_400,rpc_version=1,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,use_dpdk=1,send_frame_size=8192,recv_frame_size=8192,num_send_frames=8192,num_recv_frames=8192,master_clock_rate=500e6
[INFO] [MPM.PeriphManager] init() called with device args `fpga=CG_400,master_clock_rate=(500000000.0,),mgmt_addr=192.168.30.2,name=ni-x4xx-3246861,num_recv_frames=8192,num_send_frames=8192,product=x410,recv_frame_size=8192,rpc_version=1,second_addr=192.168.20.2,send_frame_size=8192,use_dpdk=1,clock_source=internal,time_source=internal,initializing=True'.
Using Device: Single USRP:
  Device: X400-Series Device
  Mboard 0: x410
  RX Channel: 0
    RX DSP: n/a
    RX Dboard: A
    RX Subdev: 0
  RX Channel: 1
    RX DSP: n/a
    RX Dboard: A
    RX Subdev: 1
  RX Channel: 2
    RX DSP: n/a
    RX Dboard: B
    RX Subdev: 0
  RX Channel: 3
    RX DSP: n/a
    RX Dboard: B
    RX Subdev: 1
  TX Channel: 0
    TX DSP: n/a
    TX Dboard: A
    TX Subdev: 0
  TX Channel: 1
    TX DSP: n/a
    TX Dboard: A
    TX Subdev: 1
  TX Channel: 2
    TX DSP: n/a
    TX Dboard: B
    TX Subdev: 0
  TX Channel: 3
    TX DSP: n/a
    TX Dboard: B
    TX Subdev: 1

[00:00:03.697105621] Setting device timestamp to 0...
[INFO] [MULTI_USRP]     1) catch time transition at pps edge
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)
[00:00:04.813216119] Testing receive rate 500.000000 Msps on 1 channels
[00:00:04.813856225] Testing receive rate 500.000000 Msps on 1 channels
[00:00:04.814491729] Testing receive rate 500.000000 Msps on 1 channels
Setting TX samples per packet (spp) to 1984
Setting TX samples per burst (spb) to 1984
[00:00:04.815134443] Testing receive rate 500.000000 Msps on 1 channels
Setting TX samples per packet (spp) to 1984
Setting TX samples per burst (spb) to 1984
[00:00:04.817057879] Testing transmit rate 500.000000 Msps on 1 channels
[00:00:04.818885744] Testing transmit rate 500.000000 Msps on 1 channels
Setting TX samples per packet (spp) to 1984
Setting TX samples per burst (spb) to 1984
Setting TX samples per packet (spp) to 1984
Setting TX samples per burst (spb) to 1984
[00:00:04.821423291] Testing transmit rate 500.000000 Msps on 1 channels
[00:00:04.824170578] Testing transmit rate 500.000000 Msps on 1 channels
[00:00:15.108870012] Benchmark complete.


Benchmark rate summary:
  Num received samples:     20518086644
  Num dropped samples:      0
  Num overruns detected:    0
  Num transmitted samples:  20070632064
  Num sequence errors (Tx): 0
  Num sequence errors (Rx): 0
  Num underruns detected:   0
  Num late commands:        0
  Num timeouts (Tx):        0
  Num timeouts (Rx):        0


Done!