<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://kb.ettus.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=MichaelDickens</id>
		<title>Ettus Knowledge Base - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://kb.ettus.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=MichaelDickens"/>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/Special:Contributions/MichaelDickens"/>
		<updated>2026-09-16T18:20:32Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.26.2</generator>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7240</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7240"/>
				<updated>2026-09-08T12:18:54Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* UHD DPDK Version Dependencies */ add 4.11&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2026-08-30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots more Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
UHD's original support for networked devices used the Linux kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace the UHD thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple cores, the timing-critical threads might sporadically be hit with sleeping time and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes caused by these make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables kernel bypass for network drivers. By putting the entire driver in user-space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the Linux thread scheduler. In addition, DPDK lowers the overall overhead for packet processing.&lt;br /&gt;
&lt;br /&gt;
DPDK utilizes dedicated resources -- CPU cores and memory -- to increase data throughput. This tradeoff may be acceptable for some hardware and some use-cases. DPDK is intended for use-cases where standard networking is not performant enough; the dedicated resources are otherwise wasted if not required. In other words, UHD + DPDK is generally for high-aggregate throughput use-cases, for example the X440 USRP running 8xTX or 8xRX at 500 MSps per channel or 2xTX or 2xRX at 2 GSps per channel. That said, &amp;quot;high aggregate&amp;quot; depends on the CPU and NIC; hence older CPUs may (and often does) require DPDK for the equivalent performance provided by modern CPUs without DPDK.&lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices, which are those providing 10 GbE (SFP+) and 100 GbE (QSFP28) links, whether physical or virtual:&lt;br /&gt;
&lt;br /&gt;
    E320, N300 / N310, N320 / N321, X300 / X310, X410, X420, X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 and 4.11 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. The following is an easy way to enable this feature and allocate enough &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; For UHD's DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system with Intel CPU, this entry may read like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
    ifconfig&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed ''should'' be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Data Transport Issues on multi-CPU Systems using NUMA nodes ===&lt;br /&gt;
&lt;br /&gt;
On multi-CPU systems, each CPU is a NUMA node. Even on a single CPU system one can intentionally allocate multiple NUMA nodes. A NUMA node contains specific CPU cores along with specific components such NICs and GPUs. For best performance with UHD, use the [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] to keep the UHD-based application within a given NUMA node's set of cores and make sure the NUMA node includes all NICs in use by UHD. Adding core isolation is ''not'' required when keeping execution within a specific NUMA node; it may be required for performance reasons.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7238</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7238"/>
				<updated>2026-08-30T20:47:23Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Abstract */ a little more depth&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2026-08-30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots more Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
UHD's original support for networked devices used the Linux kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace the UHD thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple cores, the timing-critical threads might sporadically be hit with sleeping time and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes caused by these make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables kernel bypass for network drivers. By putting the entire driver in user-space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the Linux thread scheduler. In addition, DPDK lowers the overall overhead for packet processing.&lt;br /&gt;
&lt;br /&gt;
DPDK utilizes dedicated resources -- CPU cores and memory -- to increase data throughput. This tradeoff may be acceptable for some hardware and some use-cases. DPDK is intended for use-cases where standard networking is not performant enough; the dedicated resources are otherwise wasted if not required. In other words, UHD + DPDK is generally for high-aggregate throughput use-cases, for example the X440 USRP running 8xTX or 8xRX at 500 MSps per channel or 2xTX or 2xRX at 2 GSps per channel. That said, &amp;quot;high aggregate&amp;quot; depends on the CPU and NIC; hence older CPUs may (and often does) require DPDK for the equivalent performance provided by modern CPUs without DPDK.&lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices, which are those providing 10 GbE (SFP+) and 100 GbE (QSFP28) links, whether physical or virtual:&lt;br /&gt;
&lt;br /&gt;
    E320, N300 / N310, N320 / N321, X300 / X310, X410, X420, X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. The following is an easy way to enable this feature and allocate enough &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; For UHD's DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system with Intel CPU, this entry may read like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
    ifconfig&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed ''should'' be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Data Transport Issues on multi-CPU Systems using NUMA nodes ===&lt;br /&gt;
&lt;br /&gt;
On multi-CPU systems, each CPU is a NUMA node. Even on a single CPU system one can intentionally allocate multiple NUMA nodes. A NUMA node contains specific CPU cores along with specific components such NICs and GPUs. For best performance with UHD, use the [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] to keep the UHD-based application within a given NUMA node's set of cores and make sure the NUMA node includes all NICs in use by UHD. Adding core isolation is ''not'' required when keeping execution within a specific NUMA node; it may be required for performance reasons.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7237</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7237"/>
				<updated>2026-08-30T20:41:46Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Regular Data Transport Issues on multi-CPU Systems using NUMA nodes */ link taskset to that section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2026-08-30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots more Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
UHD's original support for networked devices used the Linux kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace the UHD thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple cores, the timing-critical threads might sporadically be hit with sleeping time and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes caused by these make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user-space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the Linux thread scheduler. In addition, DPDK lowers the overall overhead for packet processing.&lt;br /&gt;
&lt;br /&gt;
DPDK utilizes dedicated resources -- CPU cores and memory -- to increase data throughput. This tradeoff may be acceptable for some hardware and some use-cases. DPDK is intended for use-cases where standard networking is not performant enough; the dedicated resources are otherwise wasted if not required.&lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices, which are those providing 10 GbE (SFP+) and 100 GbE (QSFP28) links, whether physical or virtual:&lt;br /&gt;
&lt;br /&gt;
    E320, N300 / N310, N320 / N321, X300 / X310, X410, X420, X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. The following is an easy way to enable this feature and allocate enough &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; For UHD's DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system with Intel CPU, this entry may read like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
    ifconfig&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed ''should'' be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Data Transport Issues on multi-CPU Systems using NUMA nodes ===&lt;br /&gt;
&lt;br /&gt;
On multi-CPU systems, each CPU is a NUMA node. Even on a single CPU system one can intentionally allocate multiple NUMA nodes. A NUMA node contains specific CPU cores along with specific components such NICs and GPUs. For best performance with UHD, use the [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] to keep the UHD-based application within a given NUMA node's set of cores and make sure the NUMA node includes all NICs in use by UHD. Adding core isolation is ''not'' required when keeping execution within a specific NUMA node; it may be required for performance reasons.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7236</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7236"/>
				<updated>2026-08-30T20:40:53Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Regular Data Transport Issue on multi-CPU Systems */ clarifying&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2026-08-30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots more Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
UHD's original support for networked devices used the Linux kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace the UHD thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple cores, the timing-critical threads might sporadically be hit with sleeping time and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes caused by these make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user-space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the Linux thread scheduler. In addition, DPDK lowers the overall overhead for packet processing.&lt;br /&gt;
&lt;br /&gt;
DPDK utilizes dedicated resources -- CPU cores and memory -- to increase data throughput. This tradeoff may be acceptable for some hardware and some use-cases. DPDK is intended for use-cases where standard networking is not performant enough; the dedicated resources are otherwise wasted if not required.&lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices, which are those providing 10 GbE (SFP+) and 100 GbE (QSFP28) links, whether physical or virtual:&lt;br /&gt;
&lt;br /&gt;
    E320, N300 / N310, N320 / N321, X300 / X310, X410, X420, X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. The following is an easy way to enable this feature and allocate enough &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; For UHD's DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system with Intel CPU, this entry may read like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
    ifconfig&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed ''should'' be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Data Transport Issues on multi-CPU Systems using NUMA nodes ===&lt;br /&gt;
&lt;br /&gt;
On multi-CPU systems, each CPU is a NUMA node. Even on a single CPU system one can intentionally allocate multiple NUMA nodes. A NUMA node contains specific CPU cores along with specific components such NICs and GPUs. For best performance with UHD, use the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; to keep the UHD-based application within a given NUMA node's set of cores and make sure the NUMA node includes all NICs in use by UHD. Adding core isolation is ''not'' required when keeping execution within a specific NUMA node; it may be required for performance reasons.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7235</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7235"/>
				<updated>2026-08-30T20:37:59Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Regular Overflows on multi-CPU Systems */ clarifying&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2026-08-30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots more Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
UHD's original support for networked devices used the Linux kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace the UHD thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple cores, the timing-critical threads might sporadically be hit with sleeping time and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes caused by these make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user-space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the Linux thread scheduler. In addition, DPDK lowers the overall overhead for packet processing.&lt;br /&gt;
&lt;br /&gt;
DPDK utilizes dedicated resources -- CPU cores and memory -- to increase data throughput. This tradeoff may be acceptable for some hardware and some use-cases. DPDK is intended for use-cases where standard networking is not performant enough; the dedicated resources are otherwise wasted if not required.&lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices, which are those providing 10 GbE (SFP+) and 100 GbE (QSFP28) links, whether physical or virtual:&lt;br /&gt;
&lt;br /&gt;
    E320, N300 / N310, N320 / N321, X300 / X310, X410, X420, X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. The following is an easy way to enable this feature and allocate enough &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; For UHD's DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system with Intel CPU, this entry may read like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
    ifconfig&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed ''should'' be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Data Transport Issue on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU, optimally along with PCIe devices such NICs. For best performance with UHD and NUMA nodes, use the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; to keep the UHD-based application within a given NUMA node set of cores and make sure the NUMA node includes all NICs in use by UHD. Adding core isolation is not required when keeping execution within a specific NUMA node; it may be required for performance reasons.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7234</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7234"/>
				<updated>2026-08-30T20:24:22Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* UHD 4.x */ remove redundant note&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2026-08-30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots more Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
UHD's original support for networked devices used the Linux kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace the UHD thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple cores, the timing-critical threads might sporadically be hit with sleeping time and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes caused by these make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user-space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the Linux thread scheduler. In addition, DPDK lowers the overall overhead for packet processing.&lt;br /&gt;
&lt;br /&gt;
DPDK utilizes dedicated resources -- CPU cores and memory -- to increase data throughput. This tradeoff may be acceptable for some hardware and some use-cases. DPDK is intended for use-cases where standard networking is not performant enough; the dedicated resources are otherwise wasted if not required.&lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices, which are those providing 10 GbE (SFP+) and 100 GbE (QSFP28) links, whether physical or virtual:&lt;br /&gt;
&lt;br /&gt;
    E320, N300 / N310, N320 / N321, X300 / X310, X410, X420, X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. The following is an easy way to enable this feature and allocate enough &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; For UHD's DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system with Intel CPU, this entry may read like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
    ifconfig&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed ''should'' be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7233</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7233"/>
				<updated>2026-08-30T20:22:49Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Preparing your UHD Configuration File */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2026-08-30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots more Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
UHD's original support for networked devices used the Linux kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace the UHD thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple cores, the timing-critical threads might sporadically be hit with sleeping time and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes caused by these make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user-space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the Linux thread scheduler. In addition, DPDK lowers the overall overhead for packet processing.&lt;br /&gt;
&lt;br /&gt;
DPDK utilizes dedicated resources -- CPU cores and memory -- to increase data throughput. This tradeoff may be acceptable for some hardware and some use-cases. DPDK is intended for use-cases where standard networking is not performant enough; the dedicated resources are otherwise wasted if not required.&lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices, which are those providing 10 GbE (SFP+) and 100 GbE (QSFP28) links, whether physical or virtual:&lt;br /&gt;
&lt;br /&gt;
    E320, N300 / N310, N320 / N321, X300 / X310, X410, X420, X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. The following is an easy way to enable this feature and allocate enough &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; For UHD's DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system with Intel CPU, this entry may read like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
    ifconfig&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7232</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7232"/>
				<updated>2026-08-30T20:22:11Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Enable hugepages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2026-08-30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots more Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
UHD's original support for networked devices used the Linux kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace the UHD thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple cores, the timing-critical threads might sporadically be hit with sleeping time and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes caused by these make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user-space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the Linux thread scheduler. In addition, DPDK lowers the overall overhead for packet processing.&lt;br /&gt;
&lt;br /&gt;
DPDK utilizes dedicated resources -- CPU cores and memory -- to increase data throughput. This tradeoff may be acceptable for some hardware and some use-cases. DPDK is intended for use-cases where standard networking is not performant enough; the dedicated resources are otherwise wasted if not required.&lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices, which are those providing 10 GbE (SFP+) and 100 GbE (QSFP28) links, whether physical or virtual:&lt;br /&gt;
&lt;br /&gt;
    E320, N300 / N310, N320 / N321, X300 / X310, X410, X420, X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. The following is an easy way to enable this feature and allocate enough &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; For UHD's DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system with Intel CPU, this entry may read like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7231</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7231"/>
				<updated>2026-08-30T20:21:48Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Enable hugepages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2026-08-30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots more Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
UHD's original support for networked devices used the Linux kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace the UHD thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple cores, the timing-critical threads might sporadically be hit with sleeping time and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes caused by these make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user-space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the Linux thread scheduler. In addition, DPDK lowers the overall overhead for packet processing.&lt;br /&gt;
&lt;br /&gt;
DPDK utilizes dedicated resources -- CPU cores and memory -- to increase data throughput. This tradeoff may be acceptable for some hardware and some use-cases. DPDK is intended for use-cases where standard networking is not performant enough; the dedicated resources are otherwise wasted if not required.&lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices, which are those providing 10 GbE (SFP+) and 100 GbE (QSFP28) links, whether physical or virtual:&lt;br /&gt;
&lt;br /&gt;
    E320, N300 / N310, N320 / N321, X300 / X310, X410, X420, X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. The following is an easy way to enable this feature and allocate enough &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; For UHD's DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system this entry may read like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7230</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7230"/>
				<updated>2026-08-30T20:18:36Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* USRPs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2026-08-30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots more Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
UHD's original support for networked devices used the Linux kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace the UHD thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple cores, the timing-critical threads might sporadically be hit with sleeping time and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes caused by these make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user-space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the Linux thread scheduler. In addition, DPDK lowers the overall overhead for packet processing.&lt;br /&gt;
&lt;br /&gt;
DPDK utilizes dedicated resources -- CPU cores and memory -- to increase data throughput. This tradeoff may be acceptable for some hardware and some use-cases. DPDK is intended for use-cases where standard networking is not performant enough; the dedicated resources are otherwise wasted if not required.&lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices, which are those providing 10 GbE (SFP+) and 100 GbE (QSFP28) links, whether physical or virtual:&lt;br /&gt;
&lt;br /&gt;
    E320, N300 / N310, N320 / N321, X300 / X310, X410, X420, X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7229</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7229"/>
				<updated>2026-08-30T20:17:43Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Abstract */ rewording&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2026-08-30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots more Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
UHD's original support for networked devices used the Linux kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace the UHD thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple cores, the timing-critical threads might sporadically be hit with sleeping time and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes caused by these make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user-space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the Linux thread scheduler. In addition, DPDK lowers the overall overhead for packet processing.&lt;br /&gt;
&lt;br /&gt;
DPDK utilizes dedicated resources -- CPU cores and memory -- to increase data throughput. This tradeoff may be acceptable for some hardware and some use-cases. DPDK is intended for use-cases where standard networking is not performant enough; the dedicated resources are otherwise wasted if not required.&lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices, which are those providing 10 GbE (SFP+) and 100 GbE (QSFP28) links:&lt;br /&gt;
&lt;br /&gt;
    E320, N300 / N310, N320 / N321, X300 / X310, X410, X420, X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7228</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7228"/>
				<updated>2026-08-30T20:15:53Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Abstract */ general tweaks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2026-08-30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots more Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
UHD's original support for networked devices used the Linux kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace the UHD thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple cores, the timing-critical threads might sporadically be hit with sleeping time and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes caused by these make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user-space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the Linux thread scheduler. In addition, DPDK lowers the overall overhead for packet processing.&lt;br /&gt;
&lt;br /&gt;
DPDK utilizes dedicated resources -- CPU cores and memory -- to increase data throughput. This tradeoff may be acceptable for some hardware and some use-cases. Using DPDK should generally be limited to cases where standard networking is not performant enough.&lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices, which are those providing 10 GbE (SFP+) and 100 GbE (QSFP28) links:&lt;br /&gt;
&lt;br /&gt;
    E320, N300 / N310, N320 / N321, X300 / X310, X410, X420, X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7227</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7227"/>
				<updated>2026-08-30T19:54:17Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: update history&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2026-08-30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots more Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices, which are those providing 10 GbE (SFP+) and 100 GbE (QSFP28) links:&lt;br /&gt;
&lt;br /&gt;
    E320, N300 / N310, N320 / N321, X300 / X310, X410, X420, X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7226</id>
		<title>USRP Host Performance Tuning Tips and Tricks</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7226"/>
				<updated>2026-08-30T19:31:23Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: whitespace&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number ==&lt;br /&gt;
'''AN-088'''&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2026-08-30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens &lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| various tweaks&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This application note provides various tips and tricks for tuning your host computer for best performance when working with USRP devices.&lt;br /&gt;
&lt;br /&gt;
== CPU Governor ==&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' use of &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; noted below ''should'' be limited to Linux kernel 5. The utility &amp;lt;code&amp;gt;cpupower&amp;lt;/code&amp;gt; should be used in Linux kernel 6 and newer.&lt;br /&gt;
&lt;br /&gt;
Ensure your CPU governor is set to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt;. This can be done with the Linux utility &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Install &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; with the command below:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install cpufrequtils&lt;br /&gt;
&lt;br /&gt;
You can then set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; per core by issuing the command:&lt;br /&gt;
&lt;br /&gt;
    sudo cpufreq-set -c $core_number -g performance&lt;br /&gt;
&lt;br /&gt;
To set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; for all cores:&lt;br /&gt;
&lt;br /&gt;
    for ((i=0;i&amp;lt;$(nproc --all);i++)); do sudo cpufreq-set -c $i -r -g performance; done&lt;br /&gt;
&lt;br /&gt;
You can then verify that the CPU governor has been set by running the command:&lt;br /&gt;
&lt;br /&gt;
    cpufreq-info&lt;br /&gt;
&lt;br /&gt;
==Thread Priority Scheduling==&lt;br /&gt;
&lt;br /&gt;
When UHD spawns a new thread, it may try to boost the thread's scheduling priority. If setting the new priority fails, the UHD software prints a warning to the console, as shown below. This warning is harmless; it simply means that the thread will retain a normal or default scheduling priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UHD Warning:&lt;br /&gt;
    Unable to set the thread priority. Performance may be negatively affected.&lt;br /&gt;
    Please see the general application notes in the manual for instructions.&lt;br /&gt;
    EnvironmentError: OSError: error in pthread_setschedparam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To address this issue, non-privileged (non-root) users need to be given special permission to change the scheduling priority. This can be enabled by creating a group &amp;lt;code&amp;gt;usrp&amp;lt;/code&amp;gt;, adding your user to it, and then appending the line &amp;lt;code&amp;gt;@usrp - rtprio  99&amp;lt;/code&amp;gt; to the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo groupadd usrp&lt;br /&gt;
    sudo usermod -aG usrp $USER&lt;br /&gt;
&lt;br /&gt;
Then add the line below to end of the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    @usrp - rtprio  99&lt;br /&gt;
&lt;br /&gt;
You must log out and log back into the account for the settings to take effect. In most Linux distributions, a list of groups and group members can be found in the &amp;lt;code&amp;gt;/etc/group&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
There is further documentation about this in the User Manual at the link below.&lt;br /&gt;
&lt;br /&gt;
* [http://files.ettus.com/manual/page_general.html#general_threading_prio Threading Notes section of the User Manual]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adjust Network Buffers==&lt;br /&gt;
&lt;br /&gt;
This applies to USRP devices connected via 10 GbE or 100 GbE Ethernet: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Note that these settings will not persist across a reboot.&lt;br /&gt;
&lt;br /&gt;
    sudo sysctl -w net.core.wmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.wmem_default=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
To make these settings persistent, set or add the following in &amp;lt;code&amp;gt;/etc/sysctl.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    net.core.wmem_max=33554432&lt;br /&gt;
    net.core.rmem_max=33554432&lt;br /&gt;
    net.core.wmem_default=33554432&lt;br /&gt;
    net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' You may choose to use a larger setting such as 250000000 to guarantee these settings work for ''any'' USRP. Larger numbers require memory allocation but with modern hardware this memory is generally available with plenty of spare.&lt;br /&gt;
&lt;br /&gt;
== Adjust Ethernet MTU ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs: N2xx, N3xx, X3xx, E31x, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
For 1 GbE links, the MTU should be set to &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For 10 GbE and 100 GbE links, the MTU should be set to &amp;lt;code&amp;gt;9000&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is important to ''set'' the value and ''not'' leave it in the default: &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Increasing Ring Buffers ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs using a 10 GbE or 100 GbE interface: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Increasing the Ring Buffers on the NIC may help prevent flow control errors at higher rates. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -G &amp;lt;interface&amp;gt; tx 4096 rx 4096&lt;br /&gt;
&lt;br /&gt;
To see the NIC limits, use&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -g &amp;lt;interface&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DPDK == &lt;br /&gt;
&lt;br /&gt;
DPDK is supported on USRPs with 10 Gbe (SFP+) and 100 GbE (QSFP28) links. DPDK replaces the traditional Linux networking stack and NIC driver with a low overhead user-land based driver. See the [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD DPDK AppNote] for specifics.&lt;br /&gt;
&lt;br /&gt;
== Disable Hyper-threading ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Disable KPTI Protections for Spectre/Meltdown ==&lt;br /&gt;
&lt;br /&gt;
In some cases, disabling the KPTI protections for the Linux Kernel can increase performance by 10-15%. It is important to note the ramification making this modification can have. This modification is only recommended for systems that absolutely require the best performance and are not connected to the internet.&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)&lt;br /&gt;
* https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&lt;br /&gt;
&lt;br /&gt;
Disabling KPTI protections can be done by adding the lines below to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file at &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For Linux kernel 5:&lt;br /&gt;
&lt;br /&gt;
    pti=off spectre_v2=off l1tf=off nospec_store_bypass_disable no_stf_barrier&lt;br /&gt;
&lt;br /&gt;
For Linux kernel 6 or higher:&lt;br /&gt;
&lt;br /&gt;
    mitigations=off&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7225</id>
		<title>USRP Host Performance Tuning Tips and Tricks</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7225"/>
				<updated>2026-08-30T19:30:57Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Application Note Number */ add history comment&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-088'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2026-08-30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens &lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| various tweaks&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This application note provides various tips and tricks for tuning your host computer for best performance when working with USRP devices.&lt;br /&gt;
&lt;br /&gt;
== CPU Governor ==&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' use of &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; noted below ''should'' be limited to Linux kernel 5. The utility &amp;lt;code&amp;gt;cpupower&amp;lt;/code&amp;gt; should be used in Linux kernel 6 and newer.&lt;br /&gt;
&lt;br /&gt;
Ensure your CPU governor is set to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt;. This can be done with the Linux utility &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Install &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; with the command below:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install cpufrequtils&lt;br /&gt;
&lt;br /&gt;
You can then set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; per core by issuing the command:&lt;br /&gt;
&lt;br /&gt;
    sudo cpufreq-set -c $core_number -g performance&lt;br /&gt;
&lt;br /&gt;
To set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; for all cores:&lt;br /&gt;
&lt;br /&gt;
    for ((i=0;i&amp;lt;$(nproc --all);i++)); do sudo cpufreq-set -c $i -r -g performance; done&lt;br /&gt;
&lt;br /&gt;
You can then verify that the CPU governor has been set by running the command:&lt;br /&gt;
&lt;br /&gt;
    cpufreq-info&lt;br /&gt;
&lt;br /&gt;
==Thread Priority Scheduling==&lt;br /&gt;
&lt;br /&gt;
When UHD spawns a new thread, it may try to boost the thread's scheduling priority. If setting the new priority fails, the UHD software prints a warning to the console, as shown below. This warning is harmless; it simply means that the thread will retain a normal or default scheduling priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UHD Warning:&lt;br /&gt;
    Unable to set the thread priority. Performance may be negatively affected.&lt;br /&gt;
    Please see the general application notes in the manual for instructions.&lt;br /&gt;
    EnvironmentError: OSError: error in pthread_setschedparam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To address this issue, non-privileged (non-root) users need to be given special permission to change the scheduling priority. This can be enabled by creating a group &amp;lt;code&amp;gt;usrp&amp;lt;/code&amp;gt;, adding your user to it, and then appending the line &amp;lt;code&amp;gt;@usrp - rtprio  99&amp;lt;/code&amp;gt; to the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo groupadd usrp&lt;br /&gt;
    sudo usermod -aG usrp $USER&lt;br /&gt;
&lt;br /&gt;
Then add the line below to end of the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    @usrp - rtprio  99&lt;br /&gt;
&lt;br /&gt;
You must log out and log back into the account for the settings to take effect. In most Linux distributions, a list of groups and group members can be found in the &amp;lt;code&amp;gt;/etc/group&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
There is further documentation about this in the User Manual at the link below.&lt;br /&gt;
&lt;br /&gt;
* [http://files.ettus.com/manual/page_general.html#general_threading_prio Threading Notes section of the User Manual]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adjust Network Buffers==&lt;br /&gt;
&lt;br /&gt;
This applies to USRP devices connected via 10 GbE or 100 GbE Ethernet: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Note that these settings will not persist across a reboot.&lt;br /&gt;
&lt;br /&gt;
    sudo sysctl -w net.core.wmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.wmem_default=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
To make these settings persistent, set or add the following in &amp;lt;code&amp;gt;/etc/sysctl.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    net.core.wmem_max=33554432&lt;br /&gt;
    net.core.rmem_max=33554432&lt;br /&gt;
    net.core.wmem_default=33554432&lt;br /&gt;
    net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' You may choose to use a larger setting such as 250000000 to guarantee these settings work for ''any'' USRP. Larger numbers require memory allocation but with modern hardware this memory is generally available with plenty of spare.&lt;br /&gt;
&lt;br /&gt;
== Adjust Ethernet MTU ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs: N2xx, N3xx, X3xx, E31x, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
For 1 GbE links, the MTU should be set to &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For 10 GbE and 100 GbE links, the MTU should be set to &amp;lt;code&amp;gt;9000&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is important to ''set'' the value and ''not'' leave it in the default: &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Increasing Ring Buffers ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs using a 10 GbE or 100 GbE interface: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Increasing the Ring Buffers on the NIC may help prevent flow control errors at higher rates. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -G &amp;lt;interface&amp;gt; tx 4096 rx 4096&lt;br /&gt;
&lt;br /&gt;
To see the NIC limits, use&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -g &amp;lt;interface&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DPDK == &lt;br /&gt;
&lt;br /&gt;
DPDK is supported on USRPs with 10 Gbe (SFP+) and 100 GbE (QSFP28) links. DPDK replaces the traditional Linux networking stack and NIC driver with a low overhead user-land based driver. See the [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD DPDK AppNote] for specifics.&lt;br /&gt;
&lt;br /&gt;
== Disable Hyper-threading ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Disable KPTI Protections for Spectre/Meltdown ==&lt;br /&gt;
&lt;br /&gt;
In some cases, disabling the KPTI protections for the Linux Kernel can increase performance by 10-15%. It is important to note the ramification making this modification can have. This modification is only recommended for systems that absolutely require the best performance and are not connected to the internet.&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)&lt;br /&gt;
* https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&lt;br /&gt;
&lt;br /&gt;
Disabling KPTI protections can be done by adding the lines below to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file at &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For Linux kernel 5:&lt;br /&gt;
&lt;br /&gt;
    pti=off spectre_v2=off l1tf=off nospec_store_bypass_disable no_stf_barrier&lt;br /&gt;
&lt;br /&gt;
For Linux kernel 6 or higher:&lt;br /&gt;
&lt;br /&gt;
    mitigations=off&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7224</id>
		<title>USRP Host Performance Tuning Tips and Tricks</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7224"/>
				<updated>2026-08-30T19:05:34Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* DPDK */ change link to KB AN&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-088'''&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This application note provides various tips and tricks for tuning your host computer for best performance when working with USRP devices.&lt;br /&gt;
&lt;br /&gt;
== CPU Governor ==&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' use of &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; noted below ''should'' be limited to Linux kernel 5. The utility &amp;lt;code&amp;gt;cpupower&amp;lt;/code&amp;gt; should be used in Linux kernel 6 and newer.&lt;br /&gt;
&lt;br /&gt;
Ensure your CPU governor is set to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt;. This can be done with the Linux utility &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Install &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; with the command below:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install cpufrequtils&lt;br /&gt;
&lt;br /&gt;
You can then set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; per core by issuing the command:&lt;br /&gt;
&lt;br /&gt;
    sudo cpufreq-set -c $core_number -g performance&lt;br /&gt;
&lt;br /&gt;
To set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; for all cores:&lt;br /&gt;
&lt;br /&gt;
    for ((i=0;i&amp;lt;$(nproc --all);i++)); do sudo cpufreq-set -c $i -r -g performance; done&lt;br /&gt;
&lt;br /&gt;
You can then verify that the CPU governor has been set by running the command:&lt;br /&gt;
&lt;br /&gt;
    cpufreq-info&lt;br /&gt;
&lt;br /&gt;
==Thread Priority Scheduling==&lt;br /&gt;
&lt;br /&gt;
When UHD spawns a new thread, it may try to boost the thread's scheduling priority. If setting the new priority fails, the UHD software prints a warning to the console, as shown below. This warning is harmless; it simply means that the thread will retain a normal or default scheduling priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UHD Warning:&lt;br /&gt;
    Unable to set the thread priority. Performance may be negatively affected.&lt;br /&gt;
    Please see the general application notes in the manual for instructions.&lt;br /&gt;
    EnvironmentError: OSError: error in pthread_setschedparam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To address this issue, non-privileged (non-root) users need to be given special permission to change the scheduling priority. This can be enabled by creating a group &amp;lt;code&amp;gt;usrp&amp;lt;/code&amp;gt;, adding your user to it, and then appending the line &amp;lt;code&amp;gt;@usrp - rtprio  99&amp;lt;/code&amp;gt; to the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo groupadd usrp&lt;br /&gt;
    sudo usermod -aG usrp $USER&lt;br /&gt;
&lt;br /&gt;
Then add the line below to end of the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    @usrp - rtprio  99&lt;br /&gt;
&lt;br /&gt;
You must log out and log back into the account for the settings to take effect. In most Linux distributions, a list of groups and group members can be found in the &amp;lt;code&amp;gt;/etc/group&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
There is further documentation about this in the User Manual at the link below.&lt;br /&gt;
&lt;br /&gt;
* [http://files.ettus.com/manual/page_general.html#general_threading_prio Threading Notes section of the User Manual]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adjust Network Buffers==&lt;br /&gt;
&lt;br /&gt;
This applies to USRP devices connected via 10 GbE or 100 GbE Ethernet: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Note that these settings will not persist across a reboot.&lt;br /&gt;
&lt;br /&gt;
    sudo sysctl -w net.core.wmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.wmem_default=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
To make these settings persistent, set or add the following in &amp;lt;code&amp;gt;/etc/sysctl.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    net.core.wmem_max=33554432&lt;br /&gt;
    net.core.rmem_max=33554432&lt;br /&gt;
    net.core.wmem_default=33554432&lt;br /&gt;
    net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' You may choose to use a larger setting such as 250000000 to guarantee these settings work for ''any'' USRP. Larger numbers require memory allocation but with modern hardware this memory is generally available with plenty of spare.&lt;br /&gt;
&lt;br /&gt;
== Adjust Ethernet MTU ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs: N2xx, N3xx, X3xx, E31x, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
For 1 GbE links, the MTU should be set to &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For 10 GbE and 100 GbE links, the MTU should be set to &amp;lt;code&amp;gt;9000&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is important to ''set'' the value and ''not'' leave it in the default: &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Increasing Ring Buffers ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs using a 10 GbE or 100 GbE interface: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Increasing the Ring Buffers on the NIC may help prevent flow control errors at higher rates. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -G &amp;lt;interface&amp;gt; tx 4096 rx 4096&lt;br /&gt;
&lt;br /&gt;
To see the NIC limits, use&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -g &amp;lt;interface&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DPDK == &lt;br /&gt;
&lt;br /&gt;
DPDK is supported on USRPs with 10 Gbe (SFP+) and 100 GbE (QSFP28) links. DPDK replaces the traditional Linux networking stack and NIC driver with a low overhead user-land based driver. See the [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD DPDK AppNote] for specifics.&lt;br /&gt;
&lt;br /&gt;
== Disable Hyper-threading ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Disable KPTI Protections for Spectre/Meltdown ==&lt;br /&gt;
&lt;br /&gt;
In some cases, disabling the KPTI protections for the Linux Kernel can increase performance by 10-15%. It is important to note the ramification making this modification can have. This modification is only recommended for systems that absolutely require the best performance and are not connected to the internet.&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)&lt;br /&gt;
* https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&lt;br /&gt;
&lt;br /&gt;
Disabling KPTI protections can be done by adding the lines below to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file at &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For Linux kernel 5:&lt;br /&gt;
&lt;br /&gt;
    pti=off spectre_v2=off l1tf=off nospec_store_bypass_disable no_stf_barrier&lt;br /&gt;
&lt;br /&gt;
For Linux kernel 6 or higher:&lt;br /&gt;
&lt;br /&gt;
    mitigations=off&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7223</id>
		<title>USRP Host Performance Tuning Tips and Tricks</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7223"/>
				<updated>2026-08-30T19:04:17Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* DPDK */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-088'''&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This application note provides various tips and tricks for tuning your host computer for best performance when working with USRP devices.&lt;br /&gt;
&lt;br /&gt;
== CPU Governor ==&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' use of &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; noted below ''should'' be limited to Linux kernel 5. The utility &amp;lt;code&amp;gt;cpupower&amp;lt;/code&amp;gt; should be used in Linux kernel 6 and newer.&lt;br /&gt;
&lt;br /&gt;
Ensure your CPU governor is set to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt;. This can be done with the Linux utility &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Install &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; with the command below:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install cpufrequtils&lt;br /&gt;
&lt;br /&gt;
You can then set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; per core by issuing the command:&lt;br /&gt;
&lt;br /&gt;
    sudo cpufreq-set -c $core_number -g performance&lt;br /&gt;
&lt;br /&gt;
To set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; for all cores:&lt;br /&gt;
&lt;br /&gt;
    for ((i=0;i&amp;lt;$(nproc --all);i++)); do sudo cpufreq-set -c $i -r -g performance; done&lt;br /&gt;
&lt;br /&gt;
You can then verify that the CPU governor has been set by running the command:&lt;br /&gt;
&lt;br /&gt;
    cpufreq-info&lt;br /&gt;
&lt;br /&gt;
==Thread Priority Scheduling==&lt;br /&gt;
&lt;br /&gt;
When UHD spawns a new thread, it may try to boost the thread's scheduling priority. If setting the new priority fails, the UHD software prints a warning to the console, as shown below. This warning is harmless; it simply means that the thread will retain a normal or default scheduling priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UHD Warning:&lt;br /&gt;
    Unable to set the thread priority. Performance may be negatively affected.&lt;br /&gt;
    Please see the general application notes in the manual for instructions.&lt;br /&gt;
    EnvironmentError: OSError: error in pthread_setschedparam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To address this issue, non-privileged (non-root) users need to be given special permission to change the scheduling priority. This can be enabled by creating a group &amp;lt;code&amp;gt;usrp&amp;lt;/code&amp;gt;, adding your user to it, and then appending the line &amp;lt;code&amp;gt;@usrp - rtprio  99&amp;lt;/code&amp;gt; to the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo groupadd usrp&lt;br /&gt;
    sudo usermod -aG usrp $USER&lt;br /&gt;
&lt;br /&gt;
Then add the line below to end of the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    @usrp - rtprio  99&lt;br /&gt;
&lt;br /&gt;
You must log out and log back into the account for the settings to take effect. In most Linux distributions, a list of groups and group members can be found in the &amp;lt;code&amp;gt;/etc/group&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
There is further documentation about this in the User Manual at the link below.&lt;br /&gt;
&lt;br /&gt;
* [http://files.ettus.com/manual/page_general.html#general_threading_prio Threading Notes section of the User Manual]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adjust Network Buffers==&lt;br /&gt;
&lt;br /&gt;
This applies to USRP devices connected via 10 GbE or 100 GbE Ethernet: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Note that these settings will not persist across a reboot.&lt;br /&gt;
&lt;br /&gt;
    sudo sysctl -w net.core.wmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.wmem_default=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
To make these settings persistent, set or add the following in &amp;lt;code&amp;gt;/etc/sysctl.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    net.core.wmem_max=33554432&lt;br /&gt;
    net.core.rmem_max=33554432&lt;br /&gt;
    net.core.wmem_default=33554432&lt;br /&gt;
    net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' You may choose to use a larger setting such as 250000000 to guarantee these settings work for ''any'' USRP. Larger numbers require memory allocation but with modern hardware this memory is generally available with plenty of spare.&lt;br /&gt;
&lt;br /&gt;
== Adjust Ethernet MTU ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs: N2xx, N3xx, X3xx, E31x, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
For 1 GbE links, the MTU should be set to &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For 10 GbE and 100 GbE links, the MTU should be set to &amp;lt;code&amp;gt;9000&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is important to ''set'' the value and ''not'' leave it in the default: &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Increasing Ring Buffers ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs using a 10 GbE or 100 GbE interface: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Increasing the Ring Buffers on the NIC may help prevent flow control errors at higher rates. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -G &amp;lt;interface&amp;gt; tx 4096 rx 4096&lt;br /&gt;
&lt;br /&gt;
To see the NIC limits, use&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -g &amp;lt;interface&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DPDK == &lt;br /&gt;
&lt;br /&gt;
DPDK is supported on USRPs with 10 Gbe (SFP+) and 100 GbE (QSFP28) links. DPDK replaces the traditional Linux networking stack and NIC driver with a low overhead user-land based driver. Additional details of using DPDK can be found in the UHD Manual located at the following link: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Disable Hyper-threading ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Disable KPTI Protections for Spectre/Meltdown ==&lt;br /&gt;
&lt;br /&gt;
In some cases, disabling the KPTI protections for the Linux Kernel can increase performance by 10-15%. It is important to note the ramification making this modification can have. This modification is only recommended for systems that absolutely require the best performance and are not connected to the internet.&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)&lt;br /&gt;
* https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&lt;br /&gt;
&lt;br /&gt;
Disabling KPTI protections can be done by adding the lines below to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file at &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For Linux kernel 5:&lt;br /&gt;
&lt;br /&gt;
    pti=off spectre_v2=off l1tf=off nospec_store_bypass_disable no_stf_barrier&lt;br /&gt;
&lt;br /&gt;
For Linux kernel 6 or higher:&lt;br /&gt;
&lt;br /&gt;
    mitigations=off&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7222</id>
		<title>USRP Host Performance Tuning Tips and Tricks</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7222"/>
				<updated>2026-08-30T19:03:19Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Adjust Ethernet MTU */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-088'''&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This application note provides various tips and tricks for tuning your host computer for best performance when working with USRP devices.&lt;br /&gt;
&lt;br /&gt;
== CPU Governor ==&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' use of &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; noted below ''should'' be limited to Linux kernel 5. The utility &amp;lt;code&amp;gt;cpupower&amp;lt;/code&amp;gt; should be used in Linux kernel 6 and newer.&lt;br /&gt;
&lt;br /&gt;
Ensure your CPU governor is set to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt;. This can be done with the Linux utility &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Install &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; with the command below:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install cpufrequtils&lt;br /&gt;
&lt;br /&gt;
You can then set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; per core by issuing the command:&lt;br /&gt;
&lt;br /&gt;
    sudo cpufreq-set -c $core_number -g performance&lt;br /&gt;
&lt;br /&gt;
To set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; for all cores:&lt;br /&gt;
&lt;br /&gt;
    for ((i=0;i&amp;lt;$(nproc --all);i++)); do sudo cpufreq-set -c $i -r -g performance; done&lt;br /&gt;
&lt;br /&gt;
You can then verify that the CPU governor has been set by running the command:&lt;br /&gt;
&lt;br /&gt;
    cpufreq-info&lt;br /&gt;
&lt;br /&gt;
==Thread Priority Scheduling==&lt;br /&gt;
&lt;br /&gt;
When UHD spawns a new thread, it may try to boost the thread's scheduling priority. If setting the new priority fails, the UHD software prints a warning to the console, as shown below. This warning is harmless; it simply means that the thread will retain a normal or default scheduling priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UHD Warning:&lt;br /&gt;
    Unable to set the thread priority. Performance may be negatively affected.&lt;br /&gt;
    Please see the general application notes in the manual for instructions.&lt;br /&gt;
    EnvironmentError: OSError: error in pthread_setschedparam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To address this issue, non-privileged (non-root) users need to be given special permission to change the scheduling priority. This can be enabled by creating a group &amp;lt;code&amp;gt;usrp&amp;lt;/code&amp;gt;, adding your user to it, and then appending the line &amp;lt;code&amp;gt;@usrp - rtprio  99&amp;lt;/code&amp;gt; to the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo groupadd usrp&lt;br /&gt;
    sudo usermod -aG usrp $USER&lt;br /&gt;
&lt;br /&gt;
Then add the line below to end of the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    @usrp - rtprio  99&lt;br /&gt;
&lt;br /&gt;
You must log out and log back into the account for the settings to take effect. In most Linux distributions, a list of groups and group members can be found in the &amp;lt;code&amp;gt;/etc/group&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
There is further documentation about this in the User Manual at the link below.&lt;br /&gt;
&lt;br /&gt;
* [http://files.ettus.com/manual/page_general.html#general_threading_prio Threading Notes section of the User Manual]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adjust Network Buffers==&lt;br /&gt;
&lt;br /&gt;
This applies to USRP devices connected via 10 GbE or 100 GbE Ethernet: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Note that these settings will not persist across a reboot.&lt;br /&gt;
&lt;br /&gt;
    sudo sysctl -w net.core.wmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.wmem_default=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
To make these settings persistent, set or add the following in &amp;lt;code&amp;gt;/etc/sysctl.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    net.core.wmem_max=33554432&lt;br /&gt;
    net.core.rmem_max=33554432&lt;br /&gt;
    net.core.wmem_default=33554432&lt;br /&gt;
    net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' You may choose to use a larger setting such as 250000000 to guarantee these settings work for ''any'' USRP. Larger numbers require memory allocation but with modern hardware this memory is generally available with plenty of spare.&lt;br /&gt;
&lt;br /&gt;
== Adjust Ethernet MTU ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs: N2xx, N3xx, X3xx, E31x, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
For 1 GbE links, the MTU should be set to &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For 10 GbE and 100 GbE links, the MTU should be set to &amp;lt;code&amp;gt;9000&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is important to ''set'' the value and ''not'' leave it in the default: &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Increasing Ring Buffers ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs using a 10 GbE or 100 GbE interface: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Increasing the Ring Buffers on the NIC may help prevent flow control errors at higher rates. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -G &amp;lt;interface&amp;gt; tx 4096 rx 4096&lt;br /&gt;
&lt;br /&gt;
To see the NIC limits, use&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -g &amp;lt;interface&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DPDK == &lt;br /&gt;
DPDK is supported on N3xx, X3xx and E320 USRPs. DPDK replaces the traditional Linux networking stack with a low overhead user-land based driver. Additional details of using DPDK can be found in the UHD Manual located at the following link: https://files.ettus.com/manual/page_dpdk.html &lt;br /&gt;
&lt;br /&gt;
== Disable Hyper-threading ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Disable KPTI Protections for Spectre/Meltdown ==&lt;br /&gt;
&lt;br /&gt;
In some cases, disabling the KPTI protections for the Linux Kernel can increase performance by 10-15%. It is important to note the ramification making this modification can have. This modification is only recommended for systems that absolutely require the best performance and are not connected to the internet.&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)&lt;br /&gt;
* https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&lt;br /&gt;
&lt;br /&gt;
Disabling KPTI protections can be done by adding the lines below to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file at &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For Linux kernel 5:&lt;br /&gt;
&lt;br /&gt;
    pti=off spectre_v2=off l1tf=off nospec_store_bypass_disable no_stf_barrier&lt;br /&gt;
&lt;br /&gt;
For Linux kernel 6 or higher:&lt;br /&gt;
&lt;br /&gt;
    mitigations=off&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7221</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7221"/>
				<updated>2026-08-30T19:01:01Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* USRPs */ more concise pagination&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices, which are those providing 10 GbE (SFP+) and 100 GbE (QSFP28) links:&lt;br /&gt;
&lt;br /&gt;
    E320, N300 / N310, N320 / N321, X300 / X310, X410, X420, X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7220</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7220"/>
				<updated>2026-08-30T18:59:14Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* UHD DPDK Version Dependencies */ remove NOTE because it's the next section anyway&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7219</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7219"/>
				<updated>2026-08-30T18:58:51Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* UHD DPDK Version Dependencies */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 and 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' DPDK 19 and newer is easy to download and install from source. If doing so, UHD ''must'' also be built from source. In this case, we ''strongly'' recommend using the latest DPDK version supported by the UHD version being built from source.&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7218</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7218"/>
				<updated>2026-08-30T18:58:20Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* References */ reduce and make generic ... fewer updates in the future!&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
* DPDK Docs by Version: https://core.dpdk.org/doc/archives/&lt;br /&gt;
* DPDK Quick Install Guide: https://core.dpdk.org/doc/quick-start/&lt;br /&gt;
* UHD Manual on DPDK: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' DPDK 19 and newer is easy to download and install from source. If doing so, UHD ''must'' also be built from source. In this case, we ''strongly'' recommend using the latest DPDK version supported by the UHD version being built from source.&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7217</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7217"/>
				<updated>2026-08-30T18:55:18Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Dependencies */ tweak title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== UHD DPDK Version Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' DPDK 19 and newer is easy to download and install from source. If doing so, UHD ''must'' also be built from source. In this case, we ''strongly'' recommend using the latest DPDK version supported by the UHD version being built from source.&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7216</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7216"/>
				<updated>2026-08-30T18:54:32Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Installing DPDK */ elaborate on UHD + DPDK for updated NIC drivers&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' DPDK 19 and newer is easy to download and install from source. If doing so, UHD ''must'' also be built from source. In this case, we ''strongly'' recommend using the latest DPDK version supported by the UHD version being built from source.&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work (e.g., the system provided NIC drivers are too old). In this case, to use DPDK one ''must'' build DPDK and UHD from source. Follow these steps in the order noted to guarantee that DPDK is built with the updated NIC drivers and that UHD is built with the noted DPDK:&lt;br /&gt;
&lt;br /&gt;
# Remove the system provided DPDK and DPDK-DEV and all UHD install(s)&lt;br /&gt;
# Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed&lt;br /&gt;
# Download and install DPDK from source&lt;br /&gt;
# Download and install UHD from source&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7215</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7215"/>
				<updated>2026-08-30T18:51:02Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Installing DPDK */ tweaks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' DPDK 19 and newer is easy to download and install from source. If doing so, UHD ''must'' also be built from source. In this case, we ''strongly'' recommend using the latest DPDK version supported by the UHD version being built from source.&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK version 18 and older can be challenging to ''correctly'' build from source. DPDK version 19 and newer use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal  release (&amp;quot;long term service&amp;quot; or LTS). While any ''can'' be used with UHD, we ''strongly'' recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to manually install NIC device drivers because of improved feature sets or just getting a NIC to work, or sometimes the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7214</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7214"/>
				<updated>2026-08-30T18:48:00Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Dependencies */ add NOTE&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' DPDK 19 and newer is easy to download and install from source. If doing so, UHD ''must'' also be built from source. In this case, we ''strongly'' recommend using the latest DPDK version supported by the UHD version being built from source.&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7213</id>
		<title>USRP Host Performance Tuning Tips and Tricks</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7213"/>
				<updated>2026-08-30T18:45:40Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Disable KPTI Protections for Spectre/Meltdown */ tweak note to be consistent with other same notes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-088'''&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This application note provides various tips and tricks for tuning your host computer for best performance when working with USRP devices.&lt;br /&gt;
&lt;br /&gt;
== CPU Governor ==&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' use of &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; noted below ''should'' be limited to Linux kernel 5. The utility &amp;lt;code&amp;gt;cpupower&amp;lt;/code&amp;gt; should be used in Linux kernel 6 and newer.&lt;br /&gt;
&lt;br /&gt;
Ensure your CPU governor is set to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt;. This can be done with the Linux utility &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Install &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; with the command below:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install cpufrequtils&lt;br /&gt;
&lt;br /&gt;
You can then set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; per core by issuing the command:&lt;br /&gt;
&lt;br /&gt;
    sudo cpufreq-set -c $core_number -g performance&lt;br /&gt;
&lt;br /&gt;
To set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; for all cores:&lt;br /&gt;
&lt;br /&gt;
    for ((i=0;i&amp;lt;$(nproc --all);i++)); do sudo cpufreq-set -c $i -r -g performance; done&lt;br /&gt;
&lt;br /&gt;
You can then verify that the CPU governor has been set by running the command:&lt;br /&gt;
&lt;br /&gt;
    cpufreq-info&lt;br /&gt;
&lt;br /&gt;
==Thread Priority Scheduling==&lt;br /&gt;
&lt;br /&gt;
When UHD spawns a new thread, it may try to boost the thread's scheduling priority. If setting the new priority fails, the UHD software prints a warning to the console, as shown below. This warning is harmless; it simply means that the thread will retain a normal or default scheduling priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UHD Warning:&lt;br /&gt;
    Unable to set the thread priority. Performance may be negatively affected.&lt;br /&gt;
    Please see the general application notes in the manual for instructions.&lt;br /&gt;
    EnvironmentError: OSError: error in pthread_setschedparam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To address this issue, non-privileged (non-root) users need to be given special permission to change the scheduling priority. This can be enabled by creating a group &amp;lt;code&amp;gt;usrp&amp;lt;/code&amp;gt;, adding your user to it, and then appending the line &amp;lt;code&amp;gt;@usrp - rtprio  99&amp;lt;/code&amp;gt; to the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo groupadd usrp&lt;br /&gt;
    sudo usermod -aG usrp $USER&lt;br /&gt;
&lt;br /&gt;
Then add the line below to end of the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    @usrp - rtprio  99&lt;br /&gt;
&lt;br /&gt;
You must log out and log back into the account for the settings to take effect. In most Linux distributions, a list of groups and group members can be found in the &amp;lt;code&amp;gt;/etc/group&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
There is further documentation about this in the User Manual at the link below.&lt;br /&gt;
&lt;br /&gt;
* [http://files.ettus.com/manual/page_general.html#general_threading_prio Threading Notes section of the User Manual]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adjust Network Buffers==&lt;br /&gt;
&lt;br /&gt;
This applies to USRP devices connected via 10 GbE or 100 GbE Ethernet: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Note that these settings will not persist across a reboot.&lt;br /&gt;
&lt;br /&gt;
    sudo sysctl -w net.core.wmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.wmem_default=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
To make these settings persistent, set or add the following in &amp;lt;code&amp;gt;/etc/sysctl.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    net.core.wmem_max=33554432&lt;br /&gt;
    net.core.rmem_max=33554432&lt;br /&gt;
    net.core.wmem_default=33554432&lt;br /&gt;
    net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' You may choose to use a larger setting such as 250000000 to guarantee these settings work for ''any'' USRP. Larger numbers require memory allocation but with modern hardware this memory is generally available with plenty of spare.&lt;br /&gt;
&lt;br /&gt;
== Adjust Ethernet MTU ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs: N2xx, N3xx, X3xx, E31x, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
For 1 Gigabit connections, the MTU should be set to &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For 10 Gigabit connections, the MTU should be set to &amp;lt;code&amp;gt;9000&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is important to set the value and '''not''' leave it is &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Increasing Ring Buffers ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs using a 10 GbE or 100 GbE interface: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Increasing the Ring Buffers on the NIC may help prevent flow control errors at higher rates. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -G &amp;lt;interface&amp;gt; tx 4096 rx 4096&lt;br /&gt;
&lt;br /&gt;
To see the NIC limits, use&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -g &amp;lt;interface&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DPDK == &lt;br /&gt;
DPDK is supported on N3xx, X3xx and E320 USRPs. DPDK replaces the traditional Linux networking stack with a low overhead user-land based driver. Additional details of using DPDK can be found in the UHD Manual located at the following link: https://files.ettus.com/manual/page_dpdk.html &lt;br /&gt;
&lt;br /&gt;
== Disable Hyper-threading ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Disable KPTI Protections for Spectre/Meltdown ==&lt;br /&gt;
&lt;br /&gt;
In some cases, disabling the KPTI protections for the Linux Kernel can increase performance by 10-15%. It is important to note the ramification making this modification can have. This modification is only recommended for systems that absolutely require the best performance and are not connected to the internet.&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)&lt;br /&gt;
* https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&lt;br /&gt;
&lt;br /&gt;
Disabling KPTI protections can be done by adding the lines below to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file at &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For Linux kernel 5:&lt;br /&gt;
&lt;br /&gt;
    pti=off spectre_v2=off l1tf=off nospec_store_bypass_disable no_stf_barrier&lt;br /&gt;
&lt;br /&gt;
For Linux kernel 6 or higher:&lt;br /&gt;
&lt;br /&gt;
    mitigations=off&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7212</id>
		<title>USRP Host Performance Tuning Tips and Tricks</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7212"/>
				<updated>2026-08-30T18:44:49Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Disable KPTI Protections for Spectre/Meltdown */ kernel 5 versus 6&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-088'''&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This application note provides various tips and tricks for tuning your host computer for best performance when working with USRP devices.&lt;br /&gt;
&lt;br /&gt;
== CPU Governor ==&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' use of &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; noted below ''should'' be limited to Linux kernel 5. The utility &amp;lt;code&amp;gt;cpupower&amp;lt;/code&amp;gt; should be used in Linux kernel 6 and newer.&lt;br /&gt;
&lt;br /&gt;
Ensure your CPU governor is set to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt;. This can be done with the Linux utility &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Install &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; with the command below:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install cpufrequtils&lt;br /&gt;
&lt;br /&gt;
You can then set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; per core by issuing the command:&lt;br /&gt;
&lt;br /&gt;
    sudo cpufreq-set -c $core_number -g performance&lt;br /&gt;
&lt;br /&gt;
To set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; for all cores:&lt;br /&gt;
&lt;br /&gt;
    for ((i=0;i&amp;lt;$(nproc --all);i++)); do sudo cpufreq-set -c $i -r -g performance; done&lt;br /&gt;
&lt;br /&gt;
You can then verify that the CPU governor has been set by running the command:&lt;br /&gt;
&lt;br /&gt;
    cpufreq-info&lt;br /&gt;
&lt;br /&gt;
==Thread Priority Scheduling==&lt;br /&gt;
&lt;br /&gt;
When UHD spawns a new thread, it may try to boost the thread's scheduling priority. If setting the new priority fails, the UHD software prints a warning to the console, as shown below. This warning is harmless; it simply means that the thread will retain a normal or default scheduling priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UHD Warning:&lt;br /&gt;
    Unable to set the thread priority. Performance may be negatively affected.&lt;br /&gt;
    Please see the general application notes in the manual for instructions.&lt;br /&gt;
    EnvironmentError: OSError: error in pthread_setschedparam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To address this issue, non-privileged (non-root) users need to be given special permission to change the scheduling priority. This can be enabled by creating a group &amp;lt;code&amp;gt;usrp&amp;lt;/code&amp;gt;, adding your user to it, and then appending the line &amp;lt;code&amp;gt;@usrp - rtprio  99&amp;lt;/code&amp;gt; to the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo groupadd usrp&lt;br /&gt;
    sudo usermod -aG usrp $USER&lt;br /&gt;
&lt;br /&gt;
Then add the line below to end of the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    @usrp - rtprio  99&lt;br /&gt;
&lt;br /&gt;
You must log out and log back into the account for the settings to take effect. In most Linux distributions, a list of groups and group members can be found in the &amp;lt;code&amp;gt;/etc/group&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
There is further documentation about this in the User Manual at the link below.&lt;br /&gt;
&lt;br /&gt;
* [http://files.ettus.com/manual/page_general.html#general_threading_prio Threading Notes section of the User Manual]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adjust Network Buffers==&lt;br /&gt;
&lt;br /&gt;
This applies to USRP devices connected via 10 GbE or 100 GbE Ethernet: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Note that these settings will not persist across a reboot.&lt;br /&gt;
&lt;br /&gt;
    sudo sysctl -w net.core.wmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.wmem_default=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
To make these settings persistent, set or add the following in &amp;lt;code&amp;gt;/etc/sysctl.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    net.core.wmem_max=33554432&lt;br /&gt;
    net.core.rmem_max=33554432&lt;br /&gt;
    net.core.wmem_default=33554432&lt;br /&gt;
    net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' You may choose to use a larger setting such as 250000000 to guarantee these settings work for ''any'' USRP. Larger numbers require memory allocation but with modern hardware this memory is generally available with plenty of spare.&lt;br /&gt;
&lt;br /&gt;
== Adjust Ethernet MTU ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs: N2xx, N3xx, X3xx, E31x, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
For 1 Gigabit connections, the MTU should be set to &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For 10 Gigabit connections, the MTU should be set to &amp;lt;code&amp;gt;9000&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is important to set the value and '''not''' leave it is &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Increasing Ring Buffers ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs using a 10 GbE or 100 GbE interface: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Increasing the Ring Buffers on the NIC may help prevent flow control errors at higher rates. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -G &amp;lt;interface&amp;gt; tx 4096 rx 4096&lt;br /&gt;
&lt;br /&gt;
To see the NIC limits, use&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -g &amp;lt;interface&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DPDK == &lt;br /&gt;
DPDK is supported on N3xx, X3xx and E320 USRPs. DPDK replaces the traditional Linux networking stack with a low overhead user-land based driver. Additional details of using DPDK can be found in the UHD Manual located at the following link: https://files.ettus.com/manual/page_dpdk.html &lt;br /&gt;
&lt;br /&gt;
== Disable Hyper-threading ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Disable KPTI Protections for Spectre/Meltdown ==&lt;br /&gt;
&lt;br /&gt;
In some cases, disabling the KPTI protections for the Linux Kernel can increase performance by 10-15%. It is important to note the ramification making this modification can have. This modification is only recommended for systems that absolutely require the best performance and are not connected to the internet.&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)&lt;br /&gt;
* https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&lt;br /&gt;
&lt;br /&gt;
Disabling KPTI protections can be done by adding the lines below to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file at &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For Linux kernel 5:&lt;br /&gt;
&lt;br /&gt;
    pti=off spectre_v2=off l1tf=off nospec_store_bypass_disable no_stf_barrier&lt;br /&gt;
&lt;br /&gt;
For Linux kernel 6 or higher:&lt;br /&gt;
&lt;br /&gt;
    mitigations=off&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After modifying the &amp;lt;code&amp;gt;grub&amp;lt;/code&amp;gt; file, run the following command to update your configuration and reboot:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7211</id>
		<title>USRP Host Performance Tuning Tips and Tricks</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7211"/>
				<updated>2026-08-30T18:43:30Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Increasing Ring Buffers */ NIC limits &amp;amp; exhaustive compressed USRP list&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-088'''&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This application note provides various tips and tricks for tuning your host computer for best performance when working with USRP devices.&lt;br /&gt;
&lt;br /&gt;
== CPU Governor ==&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' use of &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; noted below ''should'' be limited to Linux kernel 5. The utility &amp;lt;code&amp;gt;cpupower&amp;lt;/code&amp;gt; should be used in Linux kernel 6 and newer.&lt;br /&gt;
&lt;br /&gt;
Ensure your CPU governor is set to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt;. This can be done with the Linux utility &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Install &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; with the command below:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install cpufrequtils&lt;br /&gt;
&lt;br /&gt;
You can then set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; per core by issuing the command:&lt;br /&gt;
&lt;br /&gt;
    sudo cpufreq-set -c $core_number -g performance&lt;br /&gt;
&lt;br /&gt;
To set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; for all cores:&lt;br /&gt;
&lt;br /&gt;
    for ((i=0;i&amp;lt;$(nproc --all);i++)); do sudo cpufreq-set -c $i -r -g performance; done&lt;br /&gt;
&lt;br /&gt;
You can then verify that the CPU governor has been set by running the command:&lt;br /&gt;
&lt;br /&gt;
    cpufreq-info&lt;br /&gt;
&lt;br /&gt;
==Thread Priority Scheduling==&lt;br /&gt;
&lt;br /&gt;
When UHD spawns a new thread, it may try to boost the thread's scheduling priority. If setting the new priority fails, the UHD software prints a warning to the console, as shown below. This warning is harmless; it simply means that the thread will retain a normal or default scheduling priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UHD Warning:&lt;br /&gt;
    Unable to set the thread priority. Performance may be negatively affected.&lt;br /&gt;
    Please see the general application notes in the manual for instructions.&lt;br /&gt;
    EnvironmentError: OSError: error in pthread_setschedparam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To address this issue, non-privileged (non-root) users need to be given special permission to change the scheduling priority. This can be enabled by creating a group &amp;lt;code&amp;gt;usrp&amp;lt;/code&amp;gt;, adding your user to it, and then appending the line &amp;lt;code&amp;gt;@usrp - rtprio  99&amp;lt;/code&amp;gt; to the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo groupadd usrp&lt;br /&gt;
    sudo usermod -aG usrp $USER&lt;br /&gt;
&lt;br /&gt;
Then add the line below to end of the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    @usrp - rtprio  99&lt;br /&gt;
&lt;br /&gt;
You must log out and log back into the account for the settings to take effect. In most Linux distributions, a list of groups and group members can be found in the &amp;lt;code&amp;gt;/etc/group&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
There is further documentation about this in the User Manual at the link below.&lt;br /&gt;
&lt;br /&gt;
* [http://files.ettus.com/manual/page_general.html#general_threading_prio Threading Notes section of the User Manual]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adjust Network Buffers==&lt;br /&gt;
&lt;br /&gt;
This applies to USRP devices connected via 10 GbE or 100 GbE Ethernet: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Note that these settings will not persist across a reboot.&lt;br /&gt;
&lt;br /&gt;
    sudo sysctl -w net.core.wmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.wmem_default=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
To make these settings persistent, set or add the following in &amp;lt;code&amp;gt;/etc/sysctl.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    net.core.wmem_max=33554432&lt;br /&gt;
    net.core.rmem_max=33554432&lt;br /&gt;
    net.core.wmem_default=33554432&lt;br /&gt;
    net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' You may choose to use a larger setting such as 250000000 to guarantee these settings work for ''any'' USRP. Larger numbers require memory allocation but with modern hardware this memory is generally available with plenty of spare.&lt;br /&gt;
&lt;br /&gt;
== Adjust Ethernet MTU ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs: N2xx, N3xx, X3xx, E31x, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
For 1 Gigabit connections, the MTU should be set to &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For 10 Gigabit connections, the MTU should be set to &amp;lt;code&amp;gt;9000&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is important to set the value and '''not''' leave it is &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Increasing Ring Buffers ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs using a 10 GbE or 100 GbE interface: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Increasing the Ring Buffers on the NIC may help prevent flow control errors at higher rates. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -G &amp;lt;interface&amp;gt; tx 4096 rx 4096&lt;br /&gt;
&lt;br /&gt;
To see the NIC limits, use&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -g &amp;lt;interface&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DPDK == &lt;br /&gt;
DPDK is supported on N3xx, X3xx and E320 USRPs. DPDK replaces the traditional Linux networking stack with a low overhead user-land based driver. Additional details of using DPDK can be found in the UHD Manual located at the following link: https://files.ettus.com/manual/page_dpdk.html &lt;br /&gt;
&lt;br /&gt;
== Disable Hyper-threading ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Disable KPTI Protections for Spectre/Meltdown==&lt;br /&gt;
In some cases, disabling the KPTI protections for the Linux Kernel can increase performance by 10-15%. It is important to note the ramification making this modification can have. This modification is only recommended for systems that absolutely require the best performance and are not connected to the internet.&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)&lt;br /&gt;
* https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&lt;br /&gt;
&lt;br /&gt;
Disabling KPTI protections can be done by adding the lines below to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file at &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    pti=off spectre_v2=off l1tf=off nospec_store_bypass_disable no_stf_barrier&lt;br /&gt;
&lt;br /&gt;
After modifying the &amp;lt;code&amp;gt;grub&amp;lt;/code&amp;gt; file, run the following command to update your configuration and reboot:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7210</id>
		<title>USRP Host Performance Tuning Tips and Tricks</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7210"/>
				<updated>2026-08-30T18:41:36Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Adjust Network Buffers */ compressed exhaustive list&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-088'''&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This application note provides various tips and tricks for tuning your host computer for best performance when working with USRP devices.&lt;br /&gt;
&lt;br /&gt;
== CPU Governor ==&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' use of &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; noted below ''should'' be limited to Linux kernel 5. The utility &amp;lt;code&amp;gt;cpupower&amp;lt;/code&amp;gt; should be used in Linux kernel 6 and newer.&lt;br /&gt;
&lt;br /&gt;
Ensure your CPU governor is set to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt;. This can be done with the Linux utility &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Install &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; with the command below:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install cpufrequtils&lt;br /&gt;
&lt;br /&gt;
You can then set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; per core by issuing the command:&lt;br /&gt;
&lt;br /&gt;
    sudo cpufreq-set -c $core_number -g performance&lt;br /&gt;
&lt;br /&gt;
To set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; for all cores:&lt;br /&gt;
&lt;br /&gt;
    for ((i=0;i&amp;lt;$(nproc --all);i++)); do sudo cpufreq-set -c $i -r -g performance; done&lt;br /&gt;
&lt;br /&gt;
You can then verify that the CPU governor has been set by running the command:&lt;br /&gt;
&lt;br /&gt;
    cpufreq-info&lt;br /&gt;
&lt;br /&gt;
==Thread Priority Scheduling==&lt;br /&gt;
&lt;br /&gt;
When UHD spawns a new thread, it may try to boost the thread's scheduling priority. If setting the new priority fails, the UHD software prints a warning to the console, as shown below. This warning is harmless; it simply means that the thread will retain a normal or default scheduling priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UHD Warning:&lt;br /&gt;
    Unable to set the thread priority. Performance may be negatively affected.&lt;br /&gt;
    Please see the general application notes in the manual for instructions.&lt;br /&gt;
    EnvironmentError: OSError: error in pthread_setschedparam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To address this issue, non-privileged (non-root) users need to be given special permission to change the scheduling priority. This can be enabled by creating a group &amp;lt;code&amp;gt;usrp&amp;lt;/code&amp;gt;, adding your user to it, and then appending the line &amp;lt;code&amp;gt;@usrp - rtprio  99&amp;lt;/code&amp;gt; to the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo groupadd usrp&lt;br /&gt;
    sudo usermod -aG usrp $USER&lt;br /&gt;
&lt;br /&gt;
Then add the line below to end of the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    @usrp - rtprio  99&lt;br /&gt;
&lt;br /&gt;
You must log out and log back into the account for the settings to take effect. In most Linux distributions, a list of groups and group members can be found in the &amp;lt;code&amp;gt;/etc/group&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
There is further documentation about this in the User Manual at the link below.&lt;br /&gt;
&lt;br /&gt;
* [http://files.ettus.com/manual/page_general.html#general_threading_prio Threading Notes section of the User Manual]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adjust Network Buffers==&lt;br /&gt;
&lt;br /&gt;
This applies to USRP devices connected via 10 GbE or 100 GbE Ethernet: N2xx, N3xx, X3xx, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
Note that these settings will not persist across a reboot.&lt;br /&gt;
&lt;br /&gt;
    sudo sysctl -w net.core.wmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.wmem_default=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
To make these settings persistent, set or add the following in &amp;lt;code&amp;gt;/etc/sysctl.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    net.core.wmem_max=33554432&lt;br /&gt;
    net.core.rmem_max=33554432&lt;br /&gt;
    net.core.wmem_default=33554432&lt;br /&gt;
    net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' You may choose to use a larger setting such as 250000000 to guarantee these settings work for ''any'' USRP. Larger numbers require memory allocation but with modern hardware this memory is generally available with plenty of spare.&lt;br /&gt;
&lt;br /&gt;
== Adjust Ethernet MTU ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs: N2xx, N3xx, X3xx, E31x, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
For 1 Gigabit connections, the MTU should be set to &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For 10 Gigabit connections, the MTU should be set to &amp;lt;code&amp;gt;9000&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is important to set the value and '''not''' leave it is &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Increasing Ring Buffers==&lt;br /&gt;
This applies to Ethernet connected USRPs using a 10 Gb interface (X3xx, N3xx, E320).&lt;br /&gt;
&lt;br /&gt;
Increasing the Ring Buffers on the NIC may help prevent flow control errors at higher rates.&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -G &amp;lt;interface&amp;gt; tx 4096 rx 4096&lt;br /&gt;
&lt;br /&gt;
== DPDK == &lt;br /&gt;
DPDK is supported on N3xx, X3xx and E320 USRPs. DPDK replaces the traditional Linux networking stack with a low overhead user-land based driver. Additional details of using DPDK can be found in the UHD Manual located at the following link: https://files.ettus.com/manual/page_dpdk.html &lt;br /&gt;
&lt;br /&gt;
== Disable Hyper-threading ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Disable KPTI Protections for Spectre/Meltdown==&lt;br /&gt;
In some cases, disabling the KPTI protections for the Linux Kernel can increase performance by 10-15%. It is important to note the ramification making this modification can have. This modification is only recommended for systems that absolutely require the best performance and are not connected to the internet.&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)&lt;br /&gt;
* https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&lt;br /&gt;
&lt;br /&gt;
Disabling KPTI protections can be done by adding the lines below to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file at &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    pti=off spectre_v2=off l1tf=off nospec_store_bypass_disable no_stf_barrier&lt;br /&gt;
&lt;br /&gt;
After modifying the &amp;lt;code&amp;gt;grub&amp;lt;/code&amp;gt; file, run the following command to update your configuration and reboot:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7209</id>
		<title>USRP Host Performance Tuning Tips and Tricks</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7209"/>
				<updated>2026-08-30T18:41:10Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Adjust Ethernet MTU */  exhaustive USRP list&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-088'''&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This application note provides various tips and tricks for tuning your host computer for best performance when working with USRP devices.&lt;br /&gt;
&lt;br /&gt;
== CPU Governor ==&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' use of &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; noted below ''should'' be limited to Linux kernel 5. The utility &amp;lt;code&amp;gt;cpupower&amp;lt;/code&amp;gt; should be used in Linux kernel 6 and newer.&lt;br /&gt;
&lt;br /&gt;
Ensure your CPU governor is set to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt;. This can be done with the Linux utility &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Install &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; with the command below:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install cpufrequtils&lt;br /&gt;
&lt;br /&gt;
You can then set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; per core by issuing the command:&lt;br /&gt;
&lt;br /&gt;
    sudo cpufreq-set -c $core_number -g performance&lt;br /&gt;
&lt;br /&gt;
To set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; for all cores:&lt;br /&gt;
&lt;br /&gt;
    for ((i=0;i&amp;lt;$(nproc --all);i++)); do sudo cpufreq-set -c $i -r -g performance; done&lt;br /&gt;
&lt;br /&gt;
You can then verify that the CPU governor has been set by running the command:&lt;br /&gt;
&lt;br /&gt;
    cpufreq-info&lt;br /&gt;
&lt;br /&gt;
==Thread Priority Scheduling==&lt;br /&gt;
&lt;br /&gt;
When UHD spawns a new thread, it may try to boost the thread's scheduling priority. If setting the new priority fails, the UHD software prints a warning to the console, as shown below. This warning is harmless; it simply means that the thread will retain a normal or default scheduling priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UHD Warning:&lt;br /&gt;
    Unable to set the thread priority. Performance may be negatively affected.&lt;br /&gt;
    Please see the general application notes in the manual for instructions.&lt;br /&gt;
    EnvironmentError: OSError: error in pthread_setschedparam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To address this issue, non-privileged (non-root) users need to be given special permission to change the scheduling priority. This can be enabled by creating a group &amp;lt;code&amp;gt;usrp&amp;lt;/code&amp;gt;, adding your user to it, and then appending the line &amp;lt;code&amp;gt;@usrp - rtprio  99&amp;lt;/code&amp;gt; to the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo groupadd usrp&lt;br /&gt;
    sudo usermod -aG usrp $USER&lt;br /&gt;
&lt;br /&gt;
Then add the line below to end of the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    @usrp - rtprio  99&lt;br /&gt;
&lt;br /&gt;
You must log out and log back into the account for the settings to take effect. In most Linux distributions, a list of groups and group members can be found in the &amp;lt;code&amp;gt;/etc/group&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
There is further documentation about this in the User Manual at the link below.&lt;br /&gt;
&lt;br /&gt;
* [http://files.ettus.com/manual/page_general.html#general_threading_prio Threading Notes section of the User Manual]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adjust Network Buffers==&lt;br /&gt;
&lt;br /&gt;
This applies to USRP devices connected via 10 GbE or 100 GbE Ethernet: N200, N210, N300, N310, N320, N321, X300, X310, E320, X410, X420, and X440&lt;br /&gt;
&lt;br /&gt;
Note that these settings will not persist across a reboot.&lt;br /&gt;
&lt;br /&gt;
    sudo sysctl -w net.core.wmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.wmem_default=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
To make these settings persistent, set or add the following in &amp;lt;code&amp;gt;/etc/sysctl.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    net.core.wmem_max=33554432&lt;br /&gt;
    net.core.rmem_max=33554432&lt;br /&gt;
    net.core.wmem_default=33554432&lt;br /&gt;
    net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' You may choose to use a larger setting such as 250000000 to guarantee these settings work for ''any'' USRP. Larger numbers require memory allocation but with modern hardware this memory is generally available with plenty of spare.&lt;br /&gt;
&lt;br /&gt;
== Adjust Ethernet MTU ==&lt;br /&gt;
&lt;br /&gt;
This applies to Ethernet connected USRPs: N2xx, N3xx, X3xx, E31x, E320, X4xx&lt;br /&gt;
&lt;br /&gt;
For 1 Gigabit connections, the MTU should be set to &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For 10 Gigabit connections, the MTU should be set to &amp;lt;code&amp;gt;9000&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is important to set the value and '''not''' leave it is &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Increasing Ring Buffers==&lt;br /&gt;
This applies to Ethernet connected USRPs using a 10 Gb interface (X3xx, N3xx, E320).&lt;br /&gt;
&lt;br /&gt;
Increasing the Ring Buffers on the NIC may help prevent flow control errors at higher rates.&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -G &amp;lt;interface&amp;gt; tx 4096 rx 4096&lt;br /&gt;
&lt;br /&gt;
== DPDK == &lt;br /&gt;
DPDK is supported on N3xx, X3xx and E320 USRPs. DPDK replaces the traditional Linux networking stack with a low overhead user-land based driver. Additional details of using DPDK can be found in the UHD Manual located at the following link: https://files.ettus.com/manual/page_dpdk.html &lt;br /&gt;
&lt;br /&gt;
== Disable Hyper-threading ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Disable KPTI Protections for Spectre/Meltdown==&lt;br /&gt;
In some cases, disabling the KPTI protections for the Linux Kernel can increase performance by 10-15%. It is important to note the ramification making this modification can have. This modification is only recommended for systems that absolutely require the best performance and are not connected to the internet.&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)&lt;br /&gt;
* https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&lt;br /&gt;
&lt;br /&gt;
Disabling KPTI protections can be done by adding the lines below to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file at &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    pti=off spectre_v2=off l1tf=off nospec_store_bypass_disable no_stf_barrier&lt;br /&gt;
&lt;br /&gt;
After modifying the &amp;lt;code&amp;gt;grub&amp;lt;/code&amp;gt; file, run the following command to update your configuration and reboot:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7208</id>
		<title>USRP Host Performance Tuning Tips and Tricks</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7208"/>
				<updated>2026-08-30T18:40:08Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Adjust Network Buffers */ exhaustive list of ENET based USRPs. Add larger setting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-088'''&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This application note provides various tips and tricks for tuning your host computer for best performance when working with USRP devices.&lt;br /&gt;
&lt;br /&gt;
== CPU Governor ==&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' use of &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; noted below ''should'' be limited to Linux kernel 5. The utility &amp;lt;code&amp;gt;cpupower&amp;lt;/code&amp;gt; should be used in Linux kernel 6 and newer.&lt;br /&gt;
&lt;br /&gt;
Ensure your CPU governor is set to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt;. This can be done with the Linux utility &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Install &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; with the command below:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install cpufrequtils&lt;br /&gt;
&lt;br /&gt;
You can then set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; per core by issuing the command:&lt;br /&gt;
&lt;br /&gt;
    sudo cpufreq-set -c $core_number -g performance&lt;br /&gt;
&lt;br /&gt;
To set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; for all cores:&lt;br /&gt;
&lt;br /&gt;
    for ((i=0;i&amp;lt;$(nproc --all);i++)); do sudo cpufreq-set -c $i -r -g performance; done&lt;br /&gt;
&lt;br /&gt;
You can then verify that the CPU governor has been set by running the command:&lt;br /&gt;
&lt;br /&gt;
    cpufreq-info&lt;br /&gt;
&lt;br /&gt;
==Thread Priority Scheduling==&lt;br /&gt;
&lt;br /&gt;
When UHD spawns a new thread, it may try to boost the thread's scheduling priority. If setting the new priority fails, the UHD software prints a warning to the console, as shown below. This warning is harmless; it simply means that the thread will retain a normal or default scheduling priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UHD Warning:&lt;br /&gt;
    Unable to set the thread priority. Performance may be negatively affected.&lt;br /&gt;
    Please see the general application notes in the manual for instructions.&lt;br /&gt;
    EnvironmentError: OSError: error in pthread_setschedparam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To address this issue, non-privileged (non-root) users need to be given special permission to change the scheduling priority. This can be enabled by creating a group &amp;lt;code&amp;gt;usrp&amp;lt;/code&amp;gt;, adding your user to it, and then appending the line &amp;lt;code&amp;gt;@usrp - rtprio  99&amp;lt;/code&amp;gt; to the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo groupadd usrp&lt;br /&gt;
    sudo usermod -aG usrp $USER&lt;br /&gt;
&lt;br /&gt;
Then add the line below to end of the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    @usrp - rtprio  99&lt;br /&gt;
&lt;br /&gt;
You must log out and log back into the account for the settings to take effect. In most Linux distributions, a list of groups and group members can be found in the &amp;lt;code&amp;gt;/etc/group&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
There is further documentation about this in the User Manual at the link below.&lt;br /&gt;
&lt;br /&gt;
* [http://files.ettus.com/manual/page_general.html#general_threading_prio Threading Notes section of the User Manual]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adjust Network Buffers==&lt;br /&gt;
&lt;br /&gt;
This applies to USRP devices connected via 10 GbE or 100 GbE Ethernet: N200, N210, N300, N310, N320, N321, X300, X310, E320, X410, X420, and X440&lt;br /&gt;
&lt;br /&gt;
Note that these settings will not persist across a reboot.&lt;br /&gt;
&lt;br /&gt;
    sudo sysctl -w net.core.wmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.wmem_default=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
To make these settings persistent, set or add the following in &amp;lt;code&amp;gt;/etc/sysctl.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    net.core.wmem_max=33554432&lt;br /&gt;
    net.core.rmem_max=33554432&lt;br /&gt;
    net.core.wmem_default=33554432&lt;br /&gt;
    net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' You may choose to use a larger setting such as 250000000 to guarantee these settings work for ''any'' USRP. Larger numbers require memory allocation but with modern hardware this memory is generally available with plenty of spare.&lt;br /&gt;
&lt;br /&gt;
==Adjust Ethernet MTU==&lt;br /&gt;
This applies to Ethernet connected USRPs (N2xx, N3xx, X3xx, E320).&lt;br /&gt;
&lt;br /&gt;
For 1 Gigabit connections, the MTU should be set to &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For 10 Gigabit connections, the MTU should be set to &amp;lt;code&amp;gt;9000&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is important to set the value and '''not''' leave it is &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Increasing Ring Buffers==&lt;br /&gt;
This applies to Ethernet connected USRPs using a 10 Gb interface (X3xx, N3xx, E320).&lt;br /&gt;
&lt;br /&gt;
Increasing the Ring Buffers on the NIC may help prevent flow control errors at higher rates.&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -G &amp;lt;interface&amp;gt; tx 4096 rx 4096&lt;br /&gt;
&lt;br /&gt;
== DPDK == &lt;br /&gt;
DPDK is supported on N3xx, X3xx and E320 USRPs. DPDK replaces the traditional Linux networking stack with a low overhead user-land based driver. Additional details of using DPDK can be found in the UHD Manual located at the following link: https://files.ettus.com/manual/page_dpdk.html &lt;br /&gt;
&lt;br /&gt;
== Disable Hyper-threading ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Disable KPTI Protections for Spectre/Meltdown==&lt;br /&gt;
In some cases, disabling the KPTI protections for the Linux Kernel can increase performance by 10-15%. It is important to note the ramification making this modification can have. This modification is only recommended for systems that absolutely require the best performance and are not connected to the internet.&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)&lt;br /&gt;
* https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&lt;br /&gt;
&lt;br /&gt;
Disabling KPTI protections can be done by adding the lines below to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file at &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    pti=off spectre_v2=off l1tf=off nospec_store_bypass_disable no_stf_barrier&lt;br /&gt;
&lt;br /&gt;
After modifying the &amp;lt;code&amp;gt;grub&amp;lt;/code&amp;gt; file, run the following command to update your configuration and reboot:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7207</id>
		<title>USRP Host Performance Tuning Tips and Tricks</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_Host_Performance_Tuning_Tips_and_Tricks&amp;diff=7207"/>
				<updated>2026-08-30T18:36:10Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* CPU Governor */ add note about cpupower&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-088'''&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This application note provides various tips and tricks for tuning your host computer for best performance when working with USRP devices.&lt;br /&gt;
&lt;br /&gt;
== CPU Governor ==&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' use of &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; noted below ''should'' be limited to Linux kernel 5. The utility &amp;lt;code&amp;gt;cpupower&amp;lt;/code&amp;gt; should be used in Linux kernel 6 and newer.&lt;br /&gt;
&lt;br /&gt;
Ensure your CPU governor is set to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt;. This can be done with the Linux utility &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Install &amp;lt;code&amp;gt;cpufrequtils&amp;lt;/code&amp;gt; with the command below:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install cpufrequtils&lt;br /&gt;
&lt;br /&gt;
You can then set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; per core by issuing the command:&lt;br /&gt;
&lt;br /&gt;
    sudo cpufreq-set -c $core_number -g performance&lt;br /&gt;
&lt;br /&gt;
To set the CPU governor to &amp;lt;code&amp;gt;performance&amp;lt;/code&amp;gt; for all cores:&lt;br /&gt;
&lt;br /&gt;
    for ((i=0;i&amp;lt;$(nproc --all);i++)); do sudo cpufreq-set -c $i -r -g performance; done&lt;br /&gt;
&lt;br /&gt;
You can then verify that the CPU governor has been set by running the command:&lt;br /&gt;
&lt;br /&gt;
    cpufreq-info&lt;br /&gt;
&lt;br /&gt;
==Thread Priority Scheduling==&lt;br /&gt;
&lt;br /&gt;
When UHD spawns a new thread, it may try to boost the thread's scheduling priority. If setting the new priority fails, the UHD software prints a warning to the console, as shown below. This warning is harmless; it simply means that the thread will retain a normal or default scheduling priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UHD Warning:&lt;br /&gt;
    Unable to set the thread priority. Performance may be negatively affected.&lt;br /&gt;
    Please see the general application notes in the manual for instructions.&lt;br /&gt;
    EnvironmentError: OSError: error in pthread_setschedparam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To address this issue, non-privileged (non-root) users need to be given special permission to change the scheduling priority. This can be enabled by creating a group &amp;lt;code&amp;gt;usrp&amp;lt;/code&amp;gt;, adding your user to it, and then appending the line &amp;lt;code&amp;gt;@usrp - rtprio  99&amp;lt;/code&amp;gt; to the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo groupadd usrp&lt;br /&gt;
    sudo usermod -aG usrp $USER&lt;br /&gt;
&lt;br /&gt;
Then add the line below to end of the file &amp;lt;code&amp;gt;/etc/security/limits.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    @usrp - rtprio  99&lt;br /&gt;
&lt;br /&gt;
You must log out and log back into the account for the settings to take effect. In most Linux distributions, a list of groups and group members can be found in the &amp;lt;code&amp;gt;/etc/group&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
There is further documentation about this in the User Manual at the link below.&lt;br /&gt;
&lt;br /&gt;
* [http://files.ettus.com/manual/page_general.html#general_threading_prio Threading Notes section of the User Manual]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adjust Network Buffers==&lt;br /&gt;
This applies to USRP devices connected via Ethernet, such as the N200, N210, N300, N310, N320, N321, X300, X310, E320, X410, X440.&lt;br /&gt;
&lt;br /&gt;
Note that these settings will not persist across a reboot.&lt;br /&gt;
&lt;br /&gt;
    sudo sysctl -w net.core.wmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_max=33554432&lt;br /&gt;
    sudo sysctl -w net.core.wmem_default=33554432&lt;br /&gt;
    sudo sysctl -w net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
To make these settings persistent, set or add the following in &amp;lt;code&amp;gt;/etc/sysctl.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    net.core.wmem_max=33554432&lt;br /&gt;
    net.core.rmem_max=33554432&lt;br /&gt;
    net.core.wmem_default=33554432&lt;br /&gt;
    net.core.rmem_default=33554432&lt;br /&gt;
&lt;br /&gt;
==Adjust Ethernet MTU==&lt;br /&gt;
This applies to Ethernet connected USRPs (N2xx, N3xx, X3xx, E320).&lt;br /&gt;
&lt;br /&gt;
For 1 Gigabit connections, the MTU should be set to &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For 10 Gigabit connections, the MTU should be set to &amp;lt;code&amp;gt;9000&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is important to set the value and '''not''' leave it is &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Increasing Ring Buffers==&lt;br /&gt;
This applies to Ethernet connected USRPs using a 10 Gb interface (X3xx, N3xx, E320).&lt;br /&gt;
&lt;br /&gt;
Increasing the Ring Buffers on the NIC may help prevent flow control errors at higher rates.&lt;br /&gt;
&lt;br /&gt;
    sudo ethtool -G &amp;lt;interface&amp;gt; tx 4096 rx 4096&lt;br /&gt;
&lt;br /&gt;
== DPDK == &lt;br /&gt;
DPDK is supported on N3xx, X3xx and E320 USRPs. DPDK replaces the traditional Linux networking stack with a low overhead user-land based driver. Additional details of using DPDK can be found in the UHD Manual located at the following link: https://files.ettus.com/manual/page_dpdk.html &lt;br /&gt;
&lt;br /&gt;
== Disable Hyper-threading ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Disable KPTI Protections for Spectre/Meltdown==&lt;br /&gt;
In some cases, disabling the KPTI protections for the Linux Kernel can increase performance by 10-15%. It is important to note the ramification making this modification can have. This modification is only recommended for systems that absolutely require the best performance and are not connected to the internet.&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)&lt;br /&gt;
* https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&lt;br /&gt;
&lt;br /&gt;
Disabling KPTI protections can be done by adding the lines below to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file at &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    pti=off spectre_v2=off l1tf=off nospec_store_bypass_disable no_stf_barrier&lt;br /&gt;
&lt;br /&gt;
After modifying the &amp;lt;code&amp;gt;grub&amp;lt;/code&amp;gt; file, run the following command to update your configuration and reboot:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7206</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7206"/>
				<updated>2026-08-30T18:33:47Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Increasing num_recv_frames */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for expected link data throughput of 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7205</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7205"/>
				<updated>2026-08-30T18:33:11Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Increasing num_recv_frames */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7204</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7204"/>
				<updated>2026-08-30T18:32:33Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Stopping Extraneous Processes */ add NOTE&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/.code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Stopping extraneous process, like disabling hyperthreading, should be a last resort. Using thoughtful core isolation and core process assignments (e.g., &amp;quot;taskset&amp;quot;) should work the vast majority of the time.&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7203</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7203"/>
				<updated>2026-08-30T18:29:41Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Limit Execution CPUs/Cores */ add DPDK control core&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/.code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; nor the hyperthreaded cores. The &amp;quot;DPDK control&amp;quot; core ''may'' be included in the taskset because it is not dedicated by DPDK for its sole use.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7202</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7202"/>
				<updated>2026-08-30T18:28:34Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Streaming on Multiple Channels using 1 Thread Per Stream */ add throughput note&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/.code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best ratio of throughput to number of threads or cores in use.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7201</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7201"/>
				<updated>2026-08-30T18:27:32Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Disable System Interrupts on Cores/CPUs */ add not about context switching&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/.code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable the vast majority of system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Adding these entries hugely reduces the interrupts being handled by the noted cores but do not prevent forced context switching to handle multiple threads per core.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best throughput.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7200</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7200"/>
				<updated>2026-08-30T18:25:28Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Disable System Interrupts on Cores/CPUs */ add note about core isolation and taskset&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/.code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Disabling system interrupts ''should'' be used in conjunction with core isolation, which ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance generally. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best throughput.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7199</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7199"/>
				<updated>2026-08-30T18:24:08Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Isolate Cores/CPUs */ add NOTE about using isolated cores&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/.code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Isolation cores ''must'' be used along with a [https://kb.ettus.com/Getting_Started_with_DPDK_and_UHD#Limit_Execution_CPUs.2FCores taskset] or other method such that the UHD-based application uses the isolated cores.&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance generally by 1-3%. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best throughput.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7198</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7198"/>
				<updated>2026-08-30T18:21:00Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Streaming on Multiple Channels using 1 Thread Per Stream */ add info about UHD-based application&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/.code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance generally by 1-3%. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. For example, this can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt; -- which assigns 1 channel per thread, whether TX or RX.&lt;br /&gt;
&lt;br /&gt;
With your own UHD-based application, you will need to determine how many channels to assign to a given thread / stream. It is not necessarily true that 1 channel per thread will provide the best throughput.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7197</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7197"/>
				<updated>2026-08-30T18:17:18Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Disable System Interrupts on Cores/CPUs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/.code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance generally by 1-3%. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable system interrupts on cores 2 through and including 4 and their hyperthreaded relations, add this entry:&lt;br /&gt;
&lt;br /&gt;
     nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7196</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7196"/>
				<updated>2026-08-30T18:16:39Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Isolate Cores/CPUs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/.code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance generally by 1-3%. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable system interrupts on cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    nohz_full=2-4 rcu_nocbs=2-4&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7195</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7195"/>
				<updated>2026-08-30T18:16:00Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Isolate Cores/CPUs */ much deeper info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/.code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot; file). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
If hyperthreading is enabled for the cores being isolated, also isolate the hyperthreaded cores. Note that some CPUs -- such as the Intel i7 and i9 -- have both performance and efficiency cores, and generally only the performance cores can be hyperthreaded. Thus, for example for an 8 physical core CPU with all cores hyperthreaded -- cores 0-7 as the physical cores and 8-15 are the hyperthreaded virtual cores with core 0 paired with hyperthreaded core 8, 1 paired with 9, and so forth -- this entry would be:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4,10-12&lt;br /&gt;
&lt;br /&gt;
DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
With whatever cores are listed as isolated in GRUB, the Linux thread scheduler will ''generally'' not schedule threads or interrupts to run on them. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent forced context switching on threads running on those cores; these are handled by other GRUB parameters and/or system settings. In Linux kernel 6, better -- but still not full -- isolation would include these entries (for the same cores noted above):&lt;br /&gt;
&lt;br /&gt;
    isolcpus=nohz,domain,managed_irq,2-4,10-12 nohz_full=2-4,10-12 rcu_nocbs=2-4,10-12 rcu_nocb_poll&lt;br /&gt;
&lt;br /&gt;
When determining the number of cores to isolate for UHD, take into account the number dedicated for DPDK: 1 core per DPDK link as of UHD 4.11. Thus for the possible 8-core CPU, if using 2 DPDK links there are just 6 cores remaining and one (core 0) must be dedicated for the Linux kernel -- and it's wise to dedicate 2 cores for Linux (cores 0 and 1) so that the system does not lock. In this 8-core CPU scenario if using 2 DPDK links, only 4 cores would be available for UHD. This may be enough cores for your UHD-based application; only you know the use-case and can thus determine how many cores the CPU should have to support it.&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb for UHD-based applications is 1 core for the general application, 1 core per RX link, and 2 core per TX link. While not 1:1 thread:core, the actual aggregate thread CPU% used maps well.&lt;br /&gt;
&lt;br /&gt;
If the CPU has enough cores to support 1 thread per core and your application allows for this level of core isolation, then both isolating and assigning these cores will truly utilize the CPU for maximum UHD benefit.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance generally by 1-3%. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable system interrupts on cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    nohz_full=2-4 rcu_nocbs=2-4&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7194</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7194"/>
				<updated>2026-08-30T17:50:49Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Increasing num_recv_frames */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/.code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;dpdk_num_mbufs&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;dpdk_mbuf_cache_size&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;dpdk_num_desc&amp;lt;/code&amp;gt;, in the UHD DPDK configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot;). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent context switching; these are handled by other GRUB parameters and/or system settings.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance generally by 1-3%. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable system interrupts on cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    nohz_full=2-4 rcu_nocbs=2-4&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7193</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7193"/>
				<updated>2026-08-30T17:49:11Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Increasing num_recv_frames */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where &amp;lt;code&amp;gt;###&amp;lt;/.code&amp;gt; might be &amp;lt;code&amp;gt;500&amp;lt;/code&amp;gt; for 10-20 Gbps and &amp;lt;code&amp;gt;3000&amp;lt;/code&amp;gt; for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory allocation, which for DPDK means higher &amp;lt;code&amp;gt;num_buf&amp;lt;/code&amp;gt; and sometimes &amp;lt;code&amp;gt;asd&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot;). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent context switching; these are handled by other GRUB parameters and/or system settings.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance generally by 1-3%. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable system interrupts on cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    nohz_full=2-4 rcu_nocbs=2-4&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7192</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7192"/>
				<updated>2026-08-30T17:45:05Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Increasing num_recv_frames */ Correct value info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=###&amp;lt;/code&amp;gt; can help, where ### might be 500 for 10-20 Gbps and 3000 for 80 Gbps. There is no &amp;quot;correct&amp;quot; value, unlike, for example, the number samples-per-packet which is bound by the Ethernet packet size: 1500 Bytes for 1 GbE links and 9000 Bytes (&amp;quot;jumbo packet size&amp;quot;) for 10 GbE and 100 GbE links. Higher values require more memory.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot;). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent context switching; these are handled by other GRUB parameters and/or system settings.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance generally by 1-3%. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable system interrupts on cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    nohz_full=2-4 rcu_nocbs=2-4&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7191</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7191"/>
				<updated>2026-08-30T17:38:55Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Running UHD Applications with DPDK */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference is in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=512&amp;lt;/code&amp;gt; can help.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot;). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent context switching; these are handled by other GRUB parameters and/or system settings.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance generally by 1-3%. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable system interrupts on cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    nohz_full=2-4 rcu_nocbs=2-4&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7190</id>
		<title>Getting Started with DPDK and UHD</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_DPDK_and_UHD&amp;diff=7190"/>
				<updated>2026-08-29T20:16:06Z</updated>
		
		<summary type="html">&lt;p&gt;MichaelDickens: /* Additional Host Configuration for NIC Vendors */ update VFIO-PCI info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Application Note Number and Authors ==&lt;br /&gt;
&lt;br /&gt;
'''AN-500''' by Nate Temple, Alex Williams, Wade Fife, Matt Prost, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-01-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Nate Temple &amp;amp; Alex Williams&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-25&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added corrections specific to UHD 4.0 and Mellanox card use.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2022-02-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Matt Prost (via Michael Dickens)&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Tweak Tuning Notes and add Known Issues&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2023-11-20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Lots of Updates&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
Up until now, UHD's only support for networked devices was backed by the kernel's sockets implementation. Every call to &amp;lt;code&amp;gt;send()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;recv()&amp;lt;/code&amp;gt; would cause a context switch and invite the kernel's scheduler to replace our thread with something else. Because the typical scheduler is optimized to distribute CPU time fairly across multiple loads, the timing-critical threads might sporadically be hit with sleeping time, and the thread might be migrated off its current CPU and forced to run on another. The overhead and random latency spikes make it difficult to enable reliable real-time streaming at higher rates.&lt;br /&gt;
&lt;br /&gt;
DPDK is a high-speed packet processing framework that enables a kernel bypass for network drivers. By putting the entire driver in user space, avoiding context switches, and pinning I/O threads to cores, UHD and DPDK combine to largely prevent the latency spikes induced by the scheduler. In addition, the overall overhead for packet processing lowers. &lt;br /&gt;
&lt;br /&gt;
== Supported Devices ==&lt;br /&gt;
&lt;br /&gt;
=== USRPs ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on the following USRP devices:&lt;br /&gt;
&lt;br /&gt;
* E320&lt;br /&gt;
* N300 / N310&lt;br /&gt;
* N320 / N321&lt;br /&gt;
* X300 / X310&lt;br /&gt;
* X410&lt;br /&gt;
* X420&lt;br /&gt;
* X440&lt;br /&gt;
&lt;br /&gt;
=== Host Network Cards ===&lt;br /&gt;
&lt;br /&gt;
DPDK is supported on many Intel and Mellanox based 10Gb and 100Gb NICs and lots of other NICs. Below is a list of NICs Ettus Research has tested. For a full list of NICs supported by DPDK, please see the DPDK manual.&lt;br /&gt;
&lt;br /&gt;
* Intel X520-DA1 (1x10Gb)&lt;br /&gt;
* Intel X520-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA2 (2x10Gb)&lt;br /&gt;
* Intel X710-DA4 (4x10Gb)&lt;br /&gt;
* Intel XL710-QDA2 (2x40Gb breakout to 4x10Gb)&lt;br /&gt;
* Intel E810-CQDA1 (1x100Gb and 1x4x10Gb)&lt;br /&gt;
* Intel E810-CQDA2 (1x100Gb and 2x4x10Gb; [https://edc.intel.com/content/www/us/en/design/products/ethernet/perf-tuning-guide-800-series-linux/%E2%80%8Bcheck-system-hardware-capabilities/ note that this NIC ''does not'' support 2x100Gb])&lt;br /&gt;
* Intel E810-2CQDA2 (1x100Gb and 2x4x10Gb; 2x100Gb with some work)&lt;br /&gt;
* Intel E830-CQDA2 (2x100Gb or 8x10Gb)&lt;br /&gt;
* Mellanox MCX4121A-ACAT ConnectX-4 Lx (2x10Gb)&lt;br /&gt;
* Mellanox MCX515A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CCAT ConnectX-5 EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX516A-CDAT ConnectX-5 Ex EN (2x100Gb or 2x10Gb)&lt;br /&gt;
* Mellanox MCX623106AN-CDAT ConnectX-6 Dx EN (2x100Gb)&lt;br /&gt;
* [https://www.ni.com/en-us/support/model.100-gb-ethernet-connectivity-kit.html NI Dual 100 Gigabit Ethernet PCIe Interface Kit (PN 788216-01)]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* DPDK: https://www.dpdk.org/&lt;br /&gt;
** https://doc.dpdk.org/guides-17.11&lt;br /&gt;
** https://doc.dpdk.org/guides-18.11&lt;br /&gt;
** https://doc.dpdk.org/guides-19.11&lt;br /&gt;
** https://doc.dpdk.org/guides-20.11&lt;br /&gt;
** https://doc.dpdk.org/guides-21.11&lt;br /&gt;
** https://doc.dpdk.org/guides-22.11&lt;br /&gt;
** https://doc.dpdk.org/guides-23.11&lt;br /&gt;
** https://doc.dpdk.org/guides-24.11&lt;br /&gt;
** https://doc.dpdk.org/guides-25.11&lt;br /&gt;
* UHD Manual: https://files.ettus.com/manual/page_dpdk.html&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
* UHD 3.x requires DPDK 17.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.0 and 4.1 require DPDK 18.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.2 to 4.7 can use any version of DPDK from 18.11 to 21.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.8 to 4.9 can use any version of DPDK from 18.11 to 24.11&lt;br /&gt;
&lt;br /&gt;
* UHD 4.10 can use any version of DPDK from 19.11 to 25.11&lt;br /&gt;
&lt;br /&gt;
== Installing DPDK == &lt;br /&gt;
&lt;br /&gt;
We recommend installing DPDK via the system-provided installer; for example with Ubuntu:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install dpdk dpdk-dev&lt;br /&gt;
&lt;br /&gt;
While it is possible to install DPDK from source, we recommend using the system-provided install unless there is a very good reason to not do so. DPDK can be challenging to ''correctly'' build from source though more recent versions use meson and ninja along with default settings needed by UHD and hence are relatively simple to build and install. If you require installing DPDK from source, the install guide for various versions is noted below:&lt;br /&gt;
&lt;br /&gt;
* [https://doc.dpdk.org/guides-17.11/linux_gsg/build_dpdk.html DPDK 17.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-18.11/linux_gsg/build_dpdk.html DPDK 18.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-19.11/linux_gsg/build_dpdk.html DPDK 19.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html DPDK 20.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html DPDK 21.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-22.11/linux_gsg/build_dpdk.html DPDK 22.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-23.11/linux_gsg/build_dpdk.html DPDK 23.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-24.11/linux_gsg/build_dpdk.html DPDK 24.11]&lt;br /&gt;
* [https://doc.dpdk.org/guides-25.11/linux_gsg/build_dpdk.html DPDK 25.11]&lt;br /&gt;
&lt;br /&gt;
DPDK releases come three times per year in April (version X.04), July (version X.07), and November (version X.11). The X.11 version is more of a formal release. While any ''can'' be used with UHD, we recommend using just the formal releases.&lt;br /&gt;
&lt;br /&gt;
NOTE: It is sometimes necessary to use NIC device drivers because of improved feature sets or just getting a NIC to work; the system provided NIC drivers are too old. In this case: (1) remove the system provided DPDK and DPDK-DEV and whatever UHD install is in use; you will need to build these from source. (2) Download and install the new NIC drivers, NVM, and anything else that the NIC needs to be updated to the version needed. (3) Download and install DPDK from source. (4) Download and install UHD from source.&lt;br /&gt;
&lt;br /&gt;
== Installing UHD ==&lt;br /&gt;
&lt;br /&gt;
Once the &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-dev&amp;lt;/code&amp;gt; packages are installed, UHD will locate them during a build and you should see DPDK in the enabled components lists when running &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that in general UHD installed from PPA or system packages ''does not'' include support for DPDK, and even if DPDK is installed alongside these UHD it ''will not be used''. In order to get UHD with DPDK support, [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD ''must'' be built from source].&lt;br /&gt;
&lt;br /&gt;
== Enable hugepages ==&lt;br /&gt;
&lt;br /&gt;
DPDK ''requires'' &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt; to be enabled and &amp;quot;large enough&amp;quot;. There are multiple ways to enable &amp;lt;code&amp;gt;hugepages&amp;lt;/code&amp;gt;. THe following is an easy way to enable this feature and enough allocated for DPDK needs.&lt;br /&gt;
&lt;br /&gt;
Edit your grub configuration file, &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and add the follow parameters to &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    iommu=pt intel_iommu=on hugepages=2048&lt;br /&gt;
&lt;br /&gt;
On a vanilla Ubuntu system it should look like this:&lt;br /&gt;
&lt;br /&gt;
    GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash iommu=pt intel_iommu=on hugepages=2048&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Close &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; and at the command prompt, update your grub configuration with the command:&lt;br /&gt;
&lt;br /&gt;
    sudo update-grub&lt;br /&gt;
&lt;br /&gt;
For these settings to take effect, reboot your host machine.&lt;br /&gt;
&lt;br /&gt;
== Preparing your UHD Configuration File ==&lt;br /&gt;
&lt;br /&gt;
You must note the MAC addresses for your NICs before proceeding.&lt;br /&gt;
&lt;br /&gt;
The MAC addresses for your NICs can be found by running the command:&lt;br /&gt;
&lt;br /&gt;
    ip a&lt;br /&gt;
&lt;br /&gt;
You must then create a UHD configuration file.&lt;br /&gt;
&lt;br /&gt;
For UHD 3 the location is &amp;lt;code&amp;gt;/root/.uhd/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.uhd&lt;br /&gt;
    nano /root/.uhd/uhd.conf&lt;br /&gt;
&lt;br /&gt;
For UHD 4 the location is &amp;lt;code&amp;gt;/root/.config/uhd.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    sudo su&lt;br /&gt;
    mkdir -p /root/.config&lt;br /&gt;
    nano /root/.config/uhd.conf&lt;br /&gt;
&lt;br /&gt;
=== UHD 3.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that field names in UHD 3.x are slightly different from UHD 4.0.&lt;br /&gt;
&lt;br /&gt;
You should update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* Update the MAC address variables, &amp;lt;code&amp;gt;dpdk-mac&amp;lt;/code&amp;gt;, to match your NIC&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&amp;lt;/code&amp;gt; is the default location on Ubuntu 18.04.x when &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; is installed via &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk-io-cpu&amp;lt;/code&amp;gt; fields. In this example, a two port NIC is used. There should be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt;), and then separate cores assigned to each NIC (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the first port on the NIC, &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the second port on the NIC)&lt;br /&gt;
&lt;br /&gt;
* Update the &amp;lt;code&amp;gt;dpdk-ipv4&amp;lt;/code&amp;gt; fields to your desired IP range.&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk-mtu=9000&lt;br /&gt;
    dpdk-driver=/usr/lib/x86_64-linux-gnu/dpdk-17.11-drivers/&lt;br /&gt;
    dpdk-corelist=2,3,4&lt;br /&gt;
    dpdk-num-mbufs=4095&lt;br /&gt;
    dpdk-mbufs-cache-size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk-io-cpu = 3&lt;br /&gt;
    dpdk-ipv4 = 192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk-mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk-io-cpu = 4&lt;br /&gt;
    dpdk-ipv4 = 192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual_archive/v3.15.0.0/html/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
=== UHD 4.x ===&lt;br /&gt;
&lt;br /&gt;
An example &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; file is listed below. Note that the field names in UHD 4.x are slightly different from UHD 3.x.&lt;br /&gt;
&lt;br /&gt;
You must verify and/or update the following fields for your configuration from this example:&lt;br /&gt;
&lt;br /&gt;
* The MAC address variables, &amp;lt;code&amp;gt;dpdk_mac&amp;lt;/code&amp;gt;, to match your NIC(s) link(s); note that the MAC address info ''must be lowercase''&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_driver&amp;lt;/code&amp;gt; if the location is different on your system. &amp;lt;code&amp;gt;/usr/local/lib/&amp;lt;/code&amp;gt; is the default location on when DPDK is built and installed from source.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;dpdk_lcore&amp;lt;/code&amp;gt; fields. In this example, a two port NIC and both links are used. There must be one core for the main &amp;lt;code&amp;gt;dpdk&amp;lt;/code&amp;gt; thread (in this example &amp;lt;code&amp;gt;core #2&amp;lt;/code&amp;gt; because it is not otherwise used in the file) and then separate cores assigned to each NIC link (in this example &amp;lt;code&amp;gt;core #3&amp;lt;/code&amp;gt; for the one of the NIC links and &amp;lt;code&amp;gt;core #4&amp;lt;/code&amp;gt; for the other NIC link).&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;dpdk_ipv4&amp;lt;/code&amp;gt; fields to your desired IP range(s).&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.30.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.40.2&amp;lt;/code&amp;gt; on a default X3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default N3xx system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; on a default E320 system&lt;br /&gt;
** &amp;lt;code&amp;gt;192.168.10.2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;192.168.20.2&amp;lt;/code&amp;gt; on a default X4xx systems&lt;br /&gt;
&lt;br /&gt;
    [use_dpdk=1]&lt;br /&gt;
    dpdk_mtu=9000&lt;br /&gt;
    dpdk_driver=/usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/&lt;br /&gt;
    dpdk_corelist=2,3,4&lt;br /&gt;
    dpdk_num_mbufs=4096&lt;br /&gt;
    dpdk_num_desc=4096&lt;br /&gt;
    dpdk_mbuf_cache_size=315&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f1]&lt;br /&gt;
    dpdk_lcore=3&lt;br /&gt;
    dpdk_ipv4=192.168.10.1/24&lt;br /&gt;
    &lt;br /&gt;
    [dpdk_mac=aa:bb:cc:dd:ee:f2]&lt;br /&gt;
    dpdk_lcore=4&lt;br /&gt;
    dpdk_ipv4=192.168.20.1/24&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Additional information on the [https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config UHD DPDK configuration file is in the UHD manual].&lt;br /&gt;
* The number of cores listed must be used exactly within the file.&lt;br /&gt;
* The number of NIC link(s) listed must exactly match those specified in the UHD instantiation args.&lt;br /&gt;
* A simple way to move between different DPDK configurations is to create different files and then symlink from the desired file to &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Additional information on the UHD configuration file can be found here: https://files.ettus.com/manual/page_dpdk.html#dpdk_nic_config&lt;br /&gt;
&lt;br /&gt;
== Additional Host Configuration for NIC Vendors ==&lt;br /&gt;
&lt;br /&gt;
The process for this step is different for Intel and Mellanox NICs and is detailed in individual sections below.&lt;br /&gt;
&lt;br /&gt;
For these NICs DPDK ''requires'' the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver, and it must generally be loaded beforehand:&lt;br /&gt;
&lt;br /&gt;
    sudo modprobe vfio-pci&lt;br /&gt;
&lt;br /&gt;
=== Intel NICs ===&lt;br /&gt;
&lt;br /&gt;
First, take the link(s) down; for example for the link name &amp;lt;code&amp;gt;eth1np1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    sudo ifconfig eth1np1 down&lt;br /&gt;
&lt;br /&gt;
'''Note:''' You ''may'' need to turn off the NIC first before doing the rebind. In Ubuntu under &amp;lt;code&amp;gt;System&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Network&amp;lt;/code&amp;gt; -&amp;gt; click the switches to &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; for the link(s).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Make sure to pick the correct link name(s) for your specific system! If there are multiple Intel NIC links to be used by DPDK take them all down, one each in turn.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to ''manually'' rebind the NIC to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; drivers. &lt;br /&gt;
&lt;br /&gt;
Identify the PCI address your NIC link(s) is/are at:&lt;br /&gt;
&lt;br /&gt;
    dpdk-devbind.py -s&lt;br /&gt;
&lt;br /&gt;
Make note of the PCI address that your NIC link(s) is/are connected to for the next step; for example for this output:&lt;br /&gt;
&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=ixgbe unused=vfio-pci&lt;br /&gt;
&lt;br /&gt;
one would use &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;02:00.1&amp;lt;/code&amp;gt;, as follows:&lt;br /&gt;
&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.0&lt;br /&gt;
    sudo dpdk-devbind.py --bind=vfio-pci 02:00.1&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Your PCI address will likely be different than &amp;lt;code&amp;gt;02:00.0&amp;lt;/code&amp;gt; as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In older DPDK versions the command does not contain the trailing &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
You should now see the NIC listed under DPDK devices; for example:&lt;br /&gt;
&lt;br /&gt;
    # dpdk-devbind.py -s&lt;br /&gt;
    &lt;br /&gt;
    Network devices using DPDK-compatible driver&lt;br /&gt;
    ============================================&lt;br /&gt;
    0000:02:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
    0000:02:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe&lt;br /&gt;
&lt;br /&gt;
'''Note:''' More info can be found on the rebinding process [https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules  here: https://doc.dpdk.org/guides-25.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules]&lt;br /&gt;
&lt;br /&gt;
Once the NIC link(s) is/are binded to the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver they are ready for use by UHD.&lt;br /&gt;
&lt;br /&gt;
=== Mellanox NICs ===&lt;br /&gt;
&lt;br /&gt;
The NVIDIA Mellanox (&amp;quot;Mellanox&amp;quot;) NICs ''do not'' require manual rebinding. Mellanox provides system IC drivers and additional drivers for DPDK to handle the binding to and from the &amp;lt;code&amp;gt;vfio-pci&amp;lt;/code&amp;gt; driver.&lt;br /&gt;
&lt;br /&gt;
In general the Mellanox system-provided NIC and DPDK drivers should work and you should not need to install Mellanox drivers. Mellanox provides tools for updating drivers and NIC firmware, if desired.&lt;br /&gt;
&lt;br /&gt;
If for some reason your host OS does not provide Mellanox DPDK drivers, then these can be installed manually. For example:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install librte-pmd-mlx5&lt;br /&gt;
    sudo modprobe -a ib_uverbs mlx5_core mlx5_ib&lt;br /&gt;
&lt;br /&gt;
If for some reason you are running into issues using a Mellanox NIC, then you can [https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ download and install the latest Mellanox drivers from the Mellanox website] (https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/).&lt;br /&gt;
&lt;br /&gt;
The MLX5 poll mode driver library (librte_pmd_mlx5) in DPDK provides support for Mellanox ConnextX-4 through -7 NICs. For DPDK 20 and older only this driver must be enabled manually with the build option &amp;lt;code&amp;gt;CONFIG_RTE_LIBRTE_MLX5_PMD=y&amp;lt;/code&amp;gt; when building DPDK. We recommend DPDK 21 and newer when possible; these versions are easy to build from source using &amp;lt;code&amp;gt;meson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ninja&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running UHD Applications with DPDK ==&lt;br /&gt;
&lt;br /&gt;
UHD based application (including GNU Radio flowgraphs) can now be ran using a DPDK transport by passing in the Device Argument: &amp;lt;code&amp;gt;use_dpdk=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Important Note:''' In order for UHD to use DPDK, the UHD application ''must'' be ran as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user; this can be done either by prepending &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to the command or becoming the roort user via &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, running the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; utility after issuing &amp;lt;code&amp;gt;sudo su&amp;lt;/code&amp;gt; (one can also run this command simply as &amp;lt;code&amp;gt;sudo /usr/local/lib/uhd/examples/benchmark_rate ....&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE that the text output from UHD 3 or 4 is about the same; the primary difference will in the initial &amp;lt;code&amp;gt;[INFO]&amp;lt;/code&amp;gt; line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/local/lib/uhd/examples&lt;br /&gt;
&lt;br /&gt;
# ./benchmark_rate --rx_rate 125e6 --rx_subdev &amp;quot;A:0 B:0&amp;quot; --rx_channels 0,1 --tx_rate 125e6 --tx_subdev &amp;quot;A:0 B:0&amp;quot; --tx_channels 0,1 --args &amp;quot;addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106501; UHD_3.14.0.HEAD-0-gabf0db4e&lt;br /&gt;
EAL: Detected 8 lcore(s)&lt;br /&gt;
EAL: Some devices want iova as va but pa will be used because.. EAL: IOMMU does not support IOVA as VA&lt;br /&gt;
EAL: No free hugepages reported in hugepages-1048576kB&lt;br /&gt;
EAL: Probing VFIO support...&lt;br /&gt;
EAL: VFIO support initialized&lt;br /&gt;
EAL: PCI device 0000:02:00.0 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL:   using IOMMU type 1 (Type 1)&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
EAL: PCI device 0000:02:00.1 on NUMA socket -1&lt;br /&gt;
EAL:   Invalid NUMA socket, default to 0&lt;br /&gt;
EAL:   probe driver: 8086:10fb net_ixgbe&lt;br /&gt;
EAL: Ignore mapping IO port bar(2)&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 0: Link Down&lt;br /&gt;
EAL: Port 0 MAC: aa bb cc dd ee f1&lt;br /&gt;
EAL: Port 0 UP: 1&lt;br /&gt;
PMD: ixgbe_dev_link_status_print():  Port 1: Link Down&lt;br /&gt;
EAL: Port 1 MAC: aa bb cc dd ee f2&lt;br /&gt;
EAL: Port 1 UP: 1&lt;br /&gt;
EAL: Init DONE!&lt;br /&gt;
EAL: Starting I/O threads!&lt;br /&gt;
USER2: Thread 1 started&lt;br /&gt;
[00:00:00.000003] Creating the usrp device with: addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=10.2.1.19,master_clock_rate=125e6,use_dpdk=1...&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=10.2.1.19,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6,use_dpdk=1&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args 'product=n310,time_source=internal,master_clock_rate=125e6,clock_source=internal,use_dpdk=1,second_addr=192.168.20.2,mgmt_addr=10.2.1.19'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1344 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1341 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1348 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1347 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  RX Channel: 1&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: B&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
[00:00:03.728707] Setting device timestamp to 0...&lt;br /&gt;
[INFO] [MULTI_USRP]     1) catch time transition at pps edge&lt;br /&gt;
[INFO] [MULTI_USRP]     2) set times next pps (synchronously)&lt;br /&gt;
[00:00:05.331920] Testing receive rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:05.610789] Testing transmit rate 125.000000 Msps on 2 channels&lt;br /&gt;
[00:00:15.878071] Benchmark complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benchmark rate summary:&lt;br /&gt;
  Num received samples:     2557247854&lt;br /&gt;
  Num dropped samples:      0&lt;br /&gt;
  Num overruns detected:    0&lt;br /&gt;
  Num transmitted samples:  2504266704&lt;br /&gt;
  Num sequence errors (Tx): 0&lt;br /&gt;
  Num sequence errors (Rx): 0&lt;br /&gt;
  Num underruns detected:   0&lt;br /&gt;
  Num late commands:        0&lt;br /&gt;
  Num timeouts (Tx):        0&lt;br /&gt;
  Num timeouts (Rx):        0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuning Notes ==&lt;br /&gt;
&lt;br /&gt;
=== General Host Performance Tuning App Note ===&lt;br /&gt;
&lt;br /&gt;
Perform the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks general host performance tuning tips and tricks].&lt;br /&gt;
&lt;br /&gt;
=== Increasing &amp;lt;code&amp;gt;num_recv_frames&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you experience &amp;lt;code&amp;gt;Overflows&amp;lt;/code&amp;gt; at higher data rates, adding the device argument &amp;lt;code&amp;gt;num_recv_frames=512&amp;lt;/code&amp;gt; can help.&lt;br /&gt;
&lt;br /&gt;
=== Full Rate Streaming (UHD 3.x only) ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming data at the full master clock rate, and there is no interpolation or decimation being performed on the FPGA, you can skip the DUC and DDC blocks within the FPGA with the following parameters:&lt;br /&gt;
&lt;br /&gt;
    skip_ddc=1&lt;br /&gt;
    skip_duc=1&lt;br /&gt;
&lt;br /&gt;
=== Full Rate on X3xx ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming two transmit channels at full rate (200e6) on the X3xx platform, you should additionally set the following device arg:&lt;br /&gt;
&lt;br /&gt;
    enable_tx_dual_eth=1&lt;br /&gt;
&lt;br /&gt;
=== Isolate Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Isolating the cores that are used for DPDK can improve performance. This can be done by adding the &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; parameter to your &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (the &amp;quot;&amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;&amp;quot;). For example, to isolate cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    isolcpus=2-4&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. DPDK handles core isolation during runtime for cores assigned to it, but it is OK to isolate cores used by DPDK via this method. Using just &amp;lt;code&amp;gt;isolcpus&amp;lt;/code&amp;gt; does not ''entirely'' isolate cores, nor does it prevent context switching; these are handled by other GRUB parameters and/or system settings.&lt;br /&gt;
&lt;br /&gt;
=== Disable System Interrupts on Cores/CPUs ===&lt;br /&gt;
&lt;br /&gt;
Disabling system interrupts can improve the jitter and performance generally by 1-3%. This can be done by adding the parameters &amp;lt;code&amp;gt;nohz_full&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rcu_nocbs&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt;. For example, to disable system interrupts on cores 2 through and including 4, add this entry:&lt;br /&gt;
&lt;br /&gt;
    nohz_full=2-4 rcu_nocbs=2-4&lt;br /&gt;
&lt;br /&gt;
NOTE: After saving the &amp;lt;code&amp;gt;GRUB_CONFIG&amp;lt;/code&amp;gt; file, execute &amp;lt;code&amp;gt;sudo update-grub&amp;lt;/code&amp;gt; and then reboot the computer for the changes to take effect. It is OK to isolate core used by DPDK via this method.&lt;br /&gt;
&lt;br /&gt;
=== Streaming on Multiple Channels using 1 Thread Per Stream ===&lt;br /&gt;
&lt;br /&gt;
If you're streaming on multiple channels simultaneously, you can create multiple streamer objects on separate threads. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using the parameter &amp;lt;code&amp;gt;--multi_streamer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Elevated Streaming Thread Priority ===&lt;br /&gt;
&lt;br /&gt;
In UHD 4, streaming thread priorities can be elevated with the &amp;lt;code&amp;gt;uhd::set_thread_priority_safe()&amp;lt;/code&amp;gt; function call. This can be accomplished with the &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; example by using parameter &amp;lt;code&amp;gt;--priority high&amp;lt;/code&amp;gt;. Note that if the [https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks#Thread_Priority_Scheduling Thread Schedule Priority] has not been enabled for the current user then this parameter requires &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; to work.&lt;br /&gt;
&lt;br /&gt;
=== Extra &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; Priority ===&lt;br /&gt;
&lt;br /&gt;
Beyond elevating streaming thread priority, one can also increase the [https://www.man7.org/linux/man-pages/man1/nice.1.html &amp;lt;code&amp;gt;nice&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
&lt;br /&gt;
    sudo nice -n -20&lt;br /&gt;
&lt;br /&gt;
=== Limit Execution CPUs/Cores ===&lt;br /&gt;
&lt;br /&gt;
With Linux one can limit the cores being used by the threads in a process via a [https://man7.org/linux/man-pages/man1/taskset.1.html &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;] 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. Note that when using DPDK the MAC cores specified in &amp;lt;code&amp;gt;uhd.conf&amp;lt;/code&amp;gt; will already be included as part of the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; (but those cores will not be isolated nor have system interrupts disabled on them unless using that setting as noted above); it generally won't hurt to include the DPDK cores as part of the overall &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt; but it's not required. For example, to limit process/thread execution to cores 2 through and including 4, one would prepend the following (note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; is ''not'' required):&lt;br /&gt;
&lt;br /&gt;
    taskset -c &amp;quot;2-4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: For best performance do ''not'' include the cores used by DPDK in the &amp;lt;code&amp;gt;dpdk_corelist&amp;lt;/code&amp;gt; argument in the &amp;lt;code&amp;gt;taskset&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Stopping Extraneous Processes ===&lt;br /&gt;
&lt;br /&gt;
The Linux kernel spawns a number of processes and threads that spend most of their time sleeping; one cannot stop these processes/threads. That said, in a typical Linux install (for example Ubuntu) there will be a graphical desktop (e.g., &amp;lt;code&amp;gt;gdm&amp;lt;/code&amp;gt;) and various daemons started up by user request (e.g., &amp;lt;code&amp;gt;containerd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;snapd&amp;lt;/code&amp;gt;). Most of these daemons can be controlled by &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt;; some must be manually quit. Any process that runs regularly stands a chance of interrupting the UHD and DPDK threads, and thus stopping, quitting, or disabling those processes can increase performance. For example, the following commands stop various daemons that execute regularly on Ubuntu; these need to be executed with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; and some might not exist on your specific system and for these the command will do nothing so it's OK to run it:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop containerd containerd.socket&lt;br /&gt;
    systemctl stop docker docker.socket&lt;br /&gt;
    systemctl stop dbus dbus.socket&lt;br /&gt;
    systemctl stop snapd snapd.socket&lt;br /&gt;
    systemctl stop udev systemd-udevd-control.socket systemd-udevd-kernel.socket&lt;br /&gt;
&lt;br /&gt;
The following command stops the main Ubuntu desktop GUI, so running it will render the system accessible only via networking (e.g., &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;), so make sure network access is enabled before executing this command:&lt;br /&gt;
&lt;br /&gt;
    systemctl stop gdm&lt;br /&gt;
&lt;br /&gt;
=== Disable Hyper-threading ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Additional Tuning Notes from Intel ===&lt;br /&gt;
&lt;br /&gt;
* Performance report from Intel on DPDK 17.11: https://fast.dpdk.org/doc/perf/DPDK_17_11_Intel_NIC_performance_report.pdf&lt;br /&gt;
* How to get best performance with NICs on Intel platforms: https://doc.dpdk.org/guides/linux_gsg/nic_perf_intel_platform.html&lt;br /&gt;
&lt;br /&gt;
== Known Issues / Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Regular Overflows on multi-CPU Systems ===&lt;br /&gt;
&lt;br /&gt;
On Multi-CPU systems each CPU is a NUMA node. The NUMA node contains all of the cores on the CPU. For best performance when using CPU/core isolation (&amp;quot;isocpus&amp;quot; per the section &amp;lt;code&amp;gt; Isolate Cores/CPUs&amp;lt;/code&amp;gt; above) make sure that all of the cores are in the same NUMA node.&lt;br /&gt;
&lt;br /&gt;
=== Underruns Every Second with DPDK + Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
With Linux kernels 5.10 and beyond, we have observed periodic underruns on systems that otherwise have no issues. These Linux kernel versions are the default for Ubuntu 20.04.3 LTS and later. The underrun issue is due to the &amp;lt;code&amp;gt;RT_RUNTIME_SHARE&amp;lt;/code&amp;gt; feature being disabled by default in these versions of the Linux kernel (shown as &amp;lt;code&amp;gt;NO_RT_RUNTIME_SHARE&amp;lt;/code&amp;gt;). The following procedure can be used to enable this feature. This process was tested on Linux kernel version 5.13; the procedure may be slightly different on other kernel versions. To determine the Linux kernel version of your system, in a terminal issue the command &amp;lt;code&amp;gt;uname -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo -s&lt;br /&gt;
$ cd /sys/kernel/debug/sched&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
NO_RT_RUNTIME_SHARE&lt;br /&gt;
$ echo RT_RUNTIME_SHARE &amp;gt; features&lt;br /&gt;
$ cat features | tr ' ' '\n' | grep RUNTIME_SHARE&lt;br /&gt;
RT_RUNTIME_SHARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>MichaelDickens</name></author>	</entry>

	</feed>