DPDK is on my TODO list for a long time. It is a super interesting library and here is little blurb from wiki

It provides a set of data plane libraries and network interface controller polling-mode drivers for offloading TCP packet processing from the operating system kernel to processes running in user space. This offloading achieves higher computing efficiency and higher packet throughput than is possible using the interrupt-driven processing provided in the kernel.

Installation Link to heading

The installation is straightforward with meson and ninja.

sudo apt update && sudo apt install -y build-essential meson ninja-build \
  libnuma-dev python3 python3-pip libpcap-dev
git clone https://github.com/DPDK/dpdk.git
cd dpdk
meson setup --prefix=$HOME/.local build
ninja -C build
ninja -C build install
sudo ldconfig

Then, We need to set env vars to find DPDK includes and libs

export RTE_SDK=$HOME/.local
export PKG_CONFIG_PATH=$RTE_SDK/lib/x86_64-linux-gnu/pkgconfig:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=$RTE_SDK/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH

To test installation, pkg-config is used to make sure libs and headers are found

pkg-config --cflags --libs libdpdk

Hugepages Link to heading

Here is a quick definition of Hugepages and how to set it. But first, let’s get the blurb from wiki

Huge pages are a memory management feature in Linux that allow larger memory pages than the standard 4KB pages.

echo 1024 | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
mkdir -p /mnt/huge
sudo mount -t hugetlbfs none /mnt/huge

To make sure it has taken effect, we can check /proc/meminfo

$ cat /proc/meminfo | grep Huge
AnonHugePages:         0 kB
ShmemHugePages:   270336 kB
FileHugePages:         0 kB
HugePages_Total:     155
HugePages_Free:      155
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:          317440 kB

Hello World Link to heading

This small example application just initializes dpdk calling rte_eal_init.

gcc -o hello hello.c $(pkg-config --cflags --libs libdpdk)
#include <rte_eal.h>
#include <rte_ethdev.h>
#include <rte_mbuf.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
    int ret = rte_eal_init(argc, argv);
    if (ret < 0) {
        printf("Failed to initialize DPDK\n");
        return -1;
    }
    printf("DPDK initialized successfully!\n");
    return 0;
}

Running hello as root shows the following (remember to export above)

# ./hello 
EAL: Detected CPU lcores: 8
EAL: Detected NUMA nodes: 1
EAL: Detected shared linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'VA'
DPDK initialized successfully!

dpdk-testpmd Link to heading

To check the status of the current network interface, ./usertools/dpdk-devbind.py is good way to do this.

./usertools/dpdk-devbind.py --status
Network devices using kernel driver
===================================
0000:00:14.3 'Wi-Fi 6 AX201 a0f0' if=wlp0s20f3 drv=iwlwifi unused= *Active*

Then, we use the PCIe ID to get bind to DPDK with address we got above.

sudo modprobe vfio-pci
sudo ./usertools/dpdk-devbind.py -b vfio-pci <PCI_ADDR>

At this point, we can run one DPDK application polling mode driver (PMD).

sudo ./build/app//dpdk-testpmd -l 0-1 -n 4 -- --portmask=0x1 --forward-mode=io --auto-start

> start

> stop

> quit