Faster Packet Filtering on BlueField-3 Arm Cores with VPP’s Native RDMA Driver

FastNetMon

October 14, 2026

Home ‣ FastNetMon Blog ‣ Faster Packet Filtering on BlueField-3 Arm Cores with VPP’s Native RDMA Driver
Portrait of a man with short dark hair and light stubble, wearing a dark gray T-shirt, facing the camera (circular crop).

This post is a repost of a technical blog originally published by Denys Haryachyy, shared here with permission as part of ongoing research and engineering work around FastNetMon’s inline traffic processing capabilities.

In the first post on the BlueField-3 I ran an FD.io VPP data plane with an ACL filter plugin on the DPU’s sixteen Arm cores, with DPDK driving its two 100G uplinks. VPP has a second way to drive the same mlx5 NIC: its native RDMA driver, which uses mlx5 Direct Verbs and no DPDK at all. This post puts the two side by side on the same cores, with the same filter and the same traffic. On 64-byte packets the RDMA driver drops 86.0 Mpps against 58.7 Mpps with DPDK (+46.5%), and it filters at 100G line rate from 128-byte frames instead of from 256 bytes.

What Changed Since the First Post

First postThis post
DOCA / BF-bundle2.9.1 (DOCA 24.11)3.4.0 (bf-release 4.15.0)
Arm kernel5.15.0-1057-bluefield5.15.0-1093-bluefield
mlx5 driver (OFED)24.1026.04
NIC firmware32.43.240832.49.1014
VPP25.1026.10-rc1
NIC driver in VPPDPDKRDMA (Direct Verbs)

The cores, the filter, the traffic and the twelve VPP workers are the same as in the first post. For a fair comparison I re-ran the DPDK driver on exactly this setup, so the two columns in the results below differ only in the NIC driver. Every number is the median of three 15-second trials on one 100G ingress port with a drop rule matching the flood; the trials agreed within 1%.

Two Receive Paths into VPP

DPDK and RDMA receive paths into the VPP ACL filter
Both drivers hand packets to the same VPP graph; only the receive path differs

Both drivers sit on the same bifurcated mlx5 device: the uplinks stay on the kernel’s mlx5_core and user space gets its own receive and transmit queues (DPDK mlx5 guide: bifurcated driver). With DPDK, the mlx5 poll-mode driver fills DPDK rte_mbuf descriptors and dpdk-input turns them into VPP buffers. VPP’s RDMA plugin uses mlx5 Direct Verbs instead: the queue rings are mapped into VPP, and rdma-input reads the NIC’s completion entries and builds VPP buffers from them directly, with no DPDK layer in between (VPP docs: RDMA (ibverb) driver, mlx5dv(7)).

The DMA-Ordering Fix on Arm

In Direct Verbs mode the CPU and the NIC hand ring entries to each other through completion-entry owner bits, doorbell records in host memory and a write to the NIC’s doorbell register. On x86, compiler barriers are enough for the DMA memory, plus a store fence before the doorbell write; Arm’s weaker memory model can reorder these accesses, so compiler barriers are not enough there (Linux kernel: memory barriers). The change “rdma: enforce mlx5 DV DMA ordering” adds dmb oshld after each ownership check and dmb oshst before each publication to the device on AArch64, and leaves x86 with compiler barriers only. It first ships in VPP 26.10-rc1, which is why this test runs on that release.

On Arm, run VPP’s RDMA driver in Direct Verbs mode only on a release that contains the DMA-ordering fix: VPP 26.10-rc1 or later.

Starting VPP with the RDMA Driver

The start-up configuration loses its dpdk section; the DPDK plugin is disabled and the RDMA plugin enabled, and everything else from the first post stays as it was:

plugins {
  plugin dpdk_plugin.so { disable }
  plugin rdma_plugin.so { enable }
  plugin acl_filter_plugin.so { enable }
}

The interfaces are created in the start-up script, before the same cross-connect and filter set-up as in the first post. Giving them the Linux names keeps the rest of the configuration unchanged:

create interface rdma host-if p0 name p0 num-rx-queues 12 rx-queue-size 4096 tx-queue-size 4096 mode dv
create interface rdma host-if p1 name p1 num-rx-queues 12 rx-queue-size 4096 tx-queue-size 4096 mode dv

host-if is the kernel network device, which stays up after the uplinks leave the OVS bridges. One RX queue per worker spreads the flood across all twelve cores, as with DPDK. The rate comes from VPP’s interface counter, which matched the filter node’s and rdma-input’s packet counts within timing slack, and the NIC-side loss from the port’s rx_packets_phy counter. VPP 26.10-rc1 comes from FD.io’s arm64 packages and the plugin is built out of tree against them, as described in the first post (FD.io 26.10 package repository).

Results

Drop rate per frame size, DPDK versus RDMA, BlueField-3 Arm cores
Drop rate per frame size on one 100G port, VPP 26.10-rc1, DOCA 3.4.0
FrameDPDKRDMAChange
64 B58.7 Mpps · 41 Gbps · 58.6% dropped in the NIC86.0 Mpps · 61 Gbps · 39.4% dropped in the NIC+46.5%
128 B50.2 Mpps · 61 Gbps · 39.0% dropped in the NIC82.2 Mpps · 100 Gbps (line rate)+63.7%
256 B44.2 Mpps · 99 Gbps (line rate)44.3 Mpps · 99 Gbps (line rate)—
512 B23.3 Mpps (line rate)23.3 Mpps (line rate)—
1024 B11.9 Mpps (line rate)11.9 Mpps (line rate)—
1500 B8.2 Mpps (line rate)8.2 Mpps (line rate)—
IMIX32.9 Mpps (line rate)32.9 Mpps (line rate)—

Where the cores have headroom, both drivers run at line rate. Where they do not, the RDMA driver moves the limit: 64-byte traffic gains 27 Mpps, and 128-byte traffic goes from 61% to 100% of line rate.

Where the Cycles Go

Arm core cycles per 64-byte packet, DPDK versus RDMA
Per-packet cycle budget at 64 B with all twelve workers saturated

At 64 bytes all twelve workers are saturated, so the measured rate fixes the budget per packet: 12 cores × 2.13 GHz divided by the rate gives 435 core cycles per packet with DPDK and 297 with RDMA. The filter node costs the same in both, about 100 cycles (15.4 and 16.3 ticks of the 330 MHz Arm timer). The difference is all in receiving, buffer handling and graph dispatch: 336 cycles with DPDK, 192 with RDMA. On frames of 256 bytes and more, the filter node’s own figure rises to 19–24 ticks with the RDMA driver against 15–17 with DPDK, but at those sizes both drivers run at line rate with cycles to spare.

Summary

On the BlueField-3 Arm cores the NIC driver underneath VPP decides the small-packet rate. With VPP 26.10-rc1, DOCA 3.4.0 and twelve workers, VPP’s native RDMA driver in Direct Verbs mode drops 86.0 Mpps of 64-byte packets, 46.5% more than DPDK’s 58.7 Mpps, and filters at 100G line rate from 128-byte frames. Both drivers run at line rate from 256 bytes and on IMIX. On Arm the RDMA driver needs the DMA-ordering fix that first ships in VPP 26.10.

References