Posts Dpdk 问题
Post
Cancel

Dpdk 问题

1. 安装

1
2
3
4
5
6
* (HEAD detached at v23.11.5)

cd ~/xx/dpdk_brige/dpdk
rm -rf build
meson setup build -Dmax_numa_nodes=1
ninja -C build

2. 环境基础配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
xm@xm:~/xx/dpdk_brige/dpdk$ cat /proc/meminfo |grep Huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
FileHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:               0 kB
xm@xm:~/xx/dpdk_brige/dpdk$ free -g
              total        used        free      shared  buff/cache   available
Mem:              7           0           6           0           0           6
Swap:             1           0           1
xm@xm:~/xx/dpdk_brige/dpdk$ lscpu
Architecture:                         x86_64
CPU op-mode(s):                       32-bit, 64-bit
Byte Order:                           Little Endian
Address sizes:                        36 bits physical, 48 bits virtual
CPU(s):                               4
On-line CPU(s) list:                  0-3
Thread(s) per core:                   1
Core(s) per socket:                   4
Socket(s):                            1
NUMA node(s):                         1
Vendor ID:                            GenuineIntel
CPU family:                           6
Model:                                167
Model name:                           11th Gen Intel(R) Core(TM) i7-11700 @ 2.50GHz
Stepping:                             1
CPU MHz:                              2496.000
BogoMIPS:                             4992.00
Hypervisor vendor:                    KVM
Virtualization type:                  full
L1d cache:                            192 KiB
L1i cache:                            128 KiB
L2 cache:                             2 MiB
L3 cache:                             16 MiB
NUMA node0 CPU(s):                    0-3
Vulnerability Gather data sampling:   Unknown: Dependent on hypervisor status
Vulnerability Itlb multihit:          KVM: Mitigation: VMX unsupported
Vulnerability L1tf:                   Mitigation; PTE Inversion
Vulnerability Mds:                    Vulnerable: Clear CPU buffers attempted, no microcode; SMT Host state unknown
Vulnerability Meltdown:               Mitigation; PTI
Vulnerability Mmio stale data:        Vulnerable: Clear CPU buffers attempted, no microcode; SMT Host state unknown
Vulnerability Reg file data sampling: Not affected
Vulnerability Retbleed:               Vulnerable
Vulnerability Spec rstack overflow:   Not affected
Vulnerability Spec store bypass:      Vulnerable
Vulnerability Spectre v1:             Mitigation; usercopy/swapgs barriers and __user pointer sanitization
Vulnerability Spectre v2:             Mitigation; Retpolines; STIBP disabled; RSB filling; PBRSB-eIBRS Not affected; BHI Retpoline
Vulnerability Srbds:                  Not affected
Vulnerability Tsx async abort:        Not affected
Flags:                                fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc nopl xtopology nonstop_tsc cpuid tsc_kn
                                      own_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single pti
                                       fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid avx512f avx512dq rdseed adx smap clflushopt avx512cd avx512bw avx512vl xsaveopt xsavec dtherm arat pln pts

3. numa 问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
xm@xm:~/xx/dpdk_brige/dpdk$ numactl --hardware
available: 1 nodes (0)
node 0 cpus: 0 1 2 3
node 0 size: 7930 MB
node 0 free: 6466 MB
node distances:
node   0 
  0:  10 
xm@xm:~/xx/dpdk_brige/dpdk$ 
xm@xm:~/xx/dpdk_brige/dpdk$ 
xm@xm:~/xx/dpdk_brige/dpdk$ free -g
              total        used        free      shared  buff/cache   available
Mem:              7           0           6           0           0           6
Swap:             1           0           1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
===============================
        NUMA 节点示意图
===============================

NUMA Node 0
+-------------------------------+
| CPU Cores: 0 1 2 3            |
|                               |
|   +-----------------------+   |
|   | Hugepages (DMA mem)   |   | <- DPDK 分配的内存,网卡 DMA 直接访问
|   +-----------------------+   |
|                               |
| Network Card (ens4)            | <- PCIe 网卡属于本 NUMA 节点
+-------------------------------+

数据流示意:
CPU 0/1/2/3  <--->  Hugepages 内存  <--->  网卡 DMA

特点:
- CPU 访问本地 NUMA 内存延迟低
- 网卡 DMA buffer 在本地 NUMA 节点,吞吐最高
- PMD 轮询线程固定绑定 CPU 核心
- RX/TX 队列绑定本地 CPU + 内存 + 网卡


===============================
        NUMA 节点示意图
===============================

NUMA Node 0                     NUMA Node 1
+---------------------+         +---------------------+
| CPU Cores: 0 1      |         | CPU Cores: 2 3      |
| Hugepages mem       |         | Hugepages mem       |
| Network Card ens4   |         | Network Card ens5   |
+---------------------+         +---------------------+

最佳访问:
CPU(node0) -> Mem(node0) -> NIC(node0)   // 快
CPU(node1) -> Mem(node1) -> NIC(node1)   // 快

跨节点访问(CPU(node0) -> Mem(node1)  NIC(node1))会增加延迟

DPDK 做的事情:

  1. 检测 CPU 核心和 NUMA 节点
  2. 检测网卡所在 NUMA 节点
  3. 为每个 NUMA 节点分配 Hugepages 内存
  4. 将 PMD 线程绑定到 CPU
  5. 将 RX/TX 队列和内存绑定到网卡所在 NUMA 节点

4. 大页内存问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/*
 * =====================================================
 * DPDK 大页内存(Hugepages)说明
 * =====================================================
 *
 * 1. 定义
 * --------
 * - Linux 默认页大小:4 KB
 * - Hugepages(大页):通常 2 MB 或更大
 * - 优势:
 *     - 减少页表条目数量
 *     - 降低 CPU TLB(Translation Lookaside Buffer)缺失
 *     - 提升内存访问效率
 *
 * 2. 为什么 DPDK 需要 Hugepages
 * --------------------------------
 * - 高性能数据平面需要零拷贝(zero-copy)DMA:
 *     - 网卡直接访问内存(RX/TX buffer)
 *     - 需要物理连续的内存页,普通 4 KB 页容易碎片化
 * 
 * - 减少内存管理开销:
 *     - 高速轮询模式的 PMD 线程需要频繁访问大量 buffer
 *     - 使用大页减少页表查找次数和 TLB Miss
 *
 * - 配合 NUMA 优化:
 *     - 每个 NUMA 节点分配 Hugepages
 *     - 线程、网卡、内存本地化,避免跨节点访问
 *
 * 3. 配置 Hugepages 示例(单 NUMA 节点)
 * ----------------------------------------
 * // 查看当前 Hugepages 配置
 * cat /proc/meminfo | grep Huge
 *
 * // 设置 2 GB 内存为 Hugepages(假设页大小 2 MB)
 * sudo sysctl -w vm.nr_hugepages=1024
 *
 * // 为 NUMA 节点单独设置
 * echo 1024 | sudo tee /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
 *
 * 4. DPDK 使用 Hugepages
 * ----------------------
 * sudo build/app/dpdk-testpmd -l 0-3 -n 1 -- --socket-mem 1024
 * - -l 0-3       : 使用 CPU 核心 0-3
 * - -n 1         : 内存通道数
 * - --socket-mem : 每个 NUMA 节点分配的 Hugepages 内存大小(MB)
 * 
 * DPDK 会:
 * - 检测 CPU 核心和 NUMA 节点
 * - 检测网卡 NUMA 节点
 * - 分配 Hugepages 内存,作为 DMA buffer
 * - 将 PMD 线程绑定到 CPU,队列绑定到网卡所在 NUMA 节点
 *
 * 5. 总结
 * --------
 * - Hugepages 提供物理连续内存,降低页表/TLB开销
 * - 必须与 NUMA 配合保证线程、内存、网卡本地化
 * - DPDK 程序初始化失败(Cannot get hugepage information)通常意味着
 *   Hugepages 未分配或权限不足
 *
 */

5. igb_uio 问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*
 * igb_uio 与 DPDK 的关系
 *
 * 1️⃣ igb_uio 不是网卡驱动
 * ----------------------------------------------------
 * - 厂商内核驱动 (i40e/igb/ixgbe):
 *     * 负责网卡收发
 *     * 依赖内核协议栈 (TCP/IP)
 *
 * - DPDK 用户态驱动 (PMD,例如 net_i40e/net_igb):
 *     * 负责网卡收发
 *     * 完全在用户态处理,不走内核协议栈
 *
 * - igb_uio:
 *     * 不是网卡驱动
 *     * 只是“搬运工”,负责把 PCI 资源交给用户态
 *
 *
 * 2️⃣ igb_uio 的作用
 * ----------------------------------------------------
 * - 解除网卡和内核驱动绑定 (如 i40e/igb)
 * - 把 PCI 设备绑定到 igb_uio
 * - 通过 /dev/uioX 暴露设备资源给用户态:
 *     * BAR 寄存器
 *     * MSI-X 中断
 *     * DMA 地址空间
 * - 用户态 PMD 可以直接访问网卡寄存器和 DMA 内存
 *
 *
 * 3️⃣ 为什么 igb_uio 能“适配所有网卡”?
 * ----------------------------------------------------
 * - 网卡硬件的寄存器/DMA 访问方式是由 PCIe 总线暴露的
 * - 这些操作和驱动框架分离,属于通用行为
 * - 因此:
 *     * igb_uio 只做通用 PCI → 用户态映射
 *     * 不关心网卡型号
 *     * 具体逻辑交给 DPDK PMD 实现
 *
 *   举例:
 *     - i40e 网卡 → DPDK 使用 net_i40e PMD
 *     - igb 网卡 → DPDK 使用 net_igb PMD
 *     - virtio 网卡 → DPDK 使用 net_virtio PMD
 *
 *
 * 4️⃣ 总结
 * ----------------------------------------------------
 * - igb_uio = 通用“网关”,负责 PCI → 用户态映射
 * - DPDK PMD = 针对具体网卡型号的“驱动大脑”
 * - 内核驱动 (i40e/igb/ixgbe) 与 DPDK PMD 二选一:
 *     * 内核驱动 → 内核协议栈
 *     * igb_uio + PMD → 用户态高速收发
 */

6. why is dpdk?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
 * ============================================================
 * DPDK 简要说明(C 注释版)
 * ============================================================
 *
 * 1️⃣ DPDK 是什么?
 * ------------------------------------------------------------
 * - DPDK (Data Plane Development Kit)
 * - 一套用户态高速网络包处理框架
 * - 核心思路:绕过内核协议栈,直接用用户态驱动(PMD)收发包
 *
 * 传统方式(Linux 内核网络栈):
 *   [ 网卡 ] → [ 内核驱动 ] → [ 内核协议栈 TCP/IP ] → [ 用户应用 ]
 *   -> 每收一个包,要经过内核和系统调用,性能开销大
 *
 * DPDK 方式:
 *   [ 网卡 ] → [ DPDK 驱动 PMD + 用户态应用 ]
 *   -> 内核完全绕开,CPU 轮询方式处理,效率更高,可达到数千万 PPS
 *
 * 2️⃣ 为什么要用 DPDK?
 * ------------------------------------------------------------
 * - 极致性能:小包转发可做到线速 (10G/25G/100G)
 * - 可控性强:开发者自己掌握内存管理、调度策略
 * - 广泛应用:
 *   - 防火墙 / WAF / IDS / IPS
 *   - 负载均衡 / 代理(LVS、HAProxy DPDK 版)
 *   - 5G Core、vRAN
 *   - 金融交易(超低延迟收发包)
 *
 * 3️⃣ 业界一般如何使用 DPDK?
 * ------------------------------------------------------------
 * 🅰️ 直接写 DPDK 应用(硬核派)
 *   - 使用 DPDK API 编程:
 *       - 收包: rte_eth_rx_burst
 *       - 发包: rte_eth_tx_burst
 *   - 适合做定制化网络功能(DPI、防火墙、SD-WAN)
 *   - 性能极致,但开发成本高
 *
 * 🅱️ 基于 DPDK 的框架(主流派)
 *   - 封装了 DPDK,开发更方便:
 *       - OVS-DPDK → Open vSwitch DPDK 加速版
 *       - VPP (FD.io) → 用户态转发平面
 *       - Snort/Suricata with DPDK → 入侵检测系统
 *       - NGINX with DPDK patches → 高速代理
 *   - 企业常见做法:在 OVS-DPDK 或 VPP 上跑业务,不裸写 DPDK
 *
 * 🅾️ 用于网络性能测试(学习/验证)
 *   - DPDK 自带 testpmd:验证环境是否可用、网卡性能
 *   - DPDK 自带 pktgen-dpdk:生成流量
 *   - 适合学习和环境验证
 *
 * 4️⃣ 小结
 * ------------------------------------------------------------
 * - DPDK = 用户态收发包框架,绕过内核,加速网络处理
 * - 业界用法:
 *   - 硬核型:自己写 DPDK 应用(安全厂商、金融)
 *   - 框架型:用 OVS-DPDK / VPP(云厂商、运营商)
 *   - 工具型:用 testpmd / pktgen(研发、实验室)
 *
 * =============================================================
 * End of summary
 * =============================================================
 */

7. 再聊 DPDK 应用场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
 * ===========================================================
 * DPDK 简介与使用示例(C 注释版)
 * ===========================================================
 *
 * 1️⃣ DPDK 本质
 *
 * DPDK = 框架 + 用户态库 + PMD 驱动
 * - 高性能网络包处理的 C 库
 * - C 程序通过 #include <rte_*.h> 引用头文件
 * - 编译链接 DPDK 后即可直接调用 API
 * - 核心思想:绕过内核网络栈,用户态直接操作网卡 DMA 内存
 *   CPU 轮询收发包,性能极高
 *
 * -----------------------------------------------------------
 *
 * 2️⃣ dpdk-testpmd 与自己写的 C 程序
 *
 * - dpdk-testpmd 本质上是一个 C 程序二进制
 * - 调用的都是 DPDK 官方提供的 API:
 *   - 初始化 EAL
 *   - 配置端口和队列
 *   - 创建内存池
 *   - 收发包循环
 * - 自己写的程序与 testpmd 同类,只是功能自定义
 *
 * -----------------------------------------------------------
 *
 * 3️⃣ DPDK C 程序伪码示例
 *
 * #include <rte_eal.h>
 * #include <rte_ethdev.h>
 * #include <rte_mbuf.h>
 *
 * int main(int argc, char **argv) {
 *     // 1. 初始化 EAL(DPDK 环境)
 *     rte_eal_init(argc, argv);
 *
 *     // 2. 查询可用网卡数量
 *     uint16_t nb_ports = rte_eth_dev_count_avail();
 *
 *     // 3. 创建 mbuf 内存池
 *     struct rte_mempool *mbuf_pool = rte_pktmbuf_pool_create(
 *         "MBUF_POOL", 8192, 256, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
 *
 *     // 4. 配置端口 & 队列
 *     for (int port_id = 0; port_id < nb_ports; port_id++) {
 *         rte_eth_dev_configure(port_id, 1, 1, NULL);
 *         rte_eth_rx_queue_setup(port_id, 0, 1024, rte_eth_dev_socket_id(port_id), NULL, mbuf_pool);
 *         rte_eth_tx_queue_setup(port_id, 0, 1024, rte_eth_dev_socket_id(port_id), NULL);
 *         rte_eth_dev_start(port_id);
 *     }
 *
 *     // 5. 收发包主循环
 *     while (1) {
 *         struct rte_mbuf *pkts[32];
 *         int nb_rx = rte_eth_rx_burst(0, 0, pkts, 32);
 *         if (nb_rx > 0) {
 *             rte_eth_tx_burst(0, 0, pkts, nb_rx);
 *         }
 *     }
 *
 *     // 6. 停止端口
 *     for (int port_id = 0; port_id < nb_ports; port_id++) {
 *         rte_eth_dev_stop(port_id);
 *         rte_eth_dev_close(port_id);
 *     }
 *
 *     return 0;
 * }
 *
 * -----------------------------------------------------------
 *
 * 核心 API 快览
 *
 * 功能          | API                        | 说明
 * ------------------------------------------------------------
 * 初始化 DPDK    | rte_eal_init()             | 初始化 hugepages、NUMA、CPU 绑定
 * 查询网卡      | rte_eth_dev_count_avail()  | 可用网卡数量
 * 创建内存池    | rte_pktmbuf_pool_create()  | 分配 mbuf 内存用于收发包
 * 配置端口      | rte_eth_dev_configure()    | 配置 RX/TX 队列数量
 * 配置 RX 队列  | rte_eth_rx_queue_setup()   | 设置 RX 队列参数
 * 配置 TX 队列  | rte_eth_tx_queue_setup()   | 设置 TX 队列参数
 * 启动端口      | rte_eth_dev_start()        | 激活端口开始收发
 * 收包          | rte_eth_rx_burst()         | 批量收包
 * 发包          | rte_eth_tx_burst()         | 批量发包
 * 停止端口      | rte_eth_dev_stop()         | 停止收发
 * 关闭端口      | rte_eth_dev_close()        | 释放端口资源
 *
 * -----------------------------------------------------------
 *
 * 💡 总结
 *
 * - DPDK = 用户态高性能网络库
 * - dpdk-testpmd = 官方示例程序,调用 API 做收发测试
 * - 自己写 C 程序 = 同理,也调用 API,只是功能自定义
 */

8. DPDK 预备流程 & 启动流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
 * ================= DPDK 启动与 testpmd 流程注释 =================
 *
 * 1️⃣ 预备步骤:系统 & 驱动准备
 *
 * Hugepages(大页内存)分配
 * - DPDK PMD 需要连续大块内存(DMA buffer)来放 mbuf
 * - 示例:
 *   echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
 * - 可按 NUMA 节点分配:
 *   echo 512 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
 *   echo 512 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
 *
 * 网卡绑定到用户态驱动
 * - 内核驱动不能同时被 DPDK 使用
 * - 使用 dpdk-devbind.py 绑定:
 *   sudo ./usertools/dpdk-devbind.py -b igb_uio 0000:00:05.0
 * - 绑定完成后 PMD 驱动才能探测到网卡
 *
 * CPU & NUMA 核心规划(可选,但推荐)
 * - 确定哪些核心用于轮询线程、哪些核心留给系统
 * - 避免跨 NUMA 节点访问,提高 DMA 速度
 *
 *
 * 2️⃣ DPDK 应用初始化(以 testpmd 为例)
 *
 * // 1. 初始化 EAL(Environment Abstraction Layer)
 * rte_eal_init(argc, argv); 
 * // 作用:
 * // - 解析命令行参数(CPU掩码、NUMA节点、Hugepage目录等)
 * // - 初始化 Hugepages 映射
 * // - 初始化用户态 PCI 访问
 * // - 绑定 PMD 驱动到网卡
 *
 * // 2. 探测网卡
 * uint16_t nb_ports = rte_eth_dev_count_avail();
 * // DPDK PMD 驱动查看绑定的网卡,记录 NUMA 节点
 *
 * // 3. 创建 mbuf 内存池
 * struct rte_mempool *mbuf_pool = rte_pktmbuf_pool_create(
 *     "MBUF_POOL", 8192, 256, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
 * // - 分配大页内存
 * // - 按 NUMA 节点分配
 *
 * // 4. 配置端口和队列
 * for (port_id = 0; port_id < nb_ports; port_id++) {
 *     rte_eth_dev_configure(port_id, nb_rx_queues, nb_tx_queues, &conf);
 *     rte_eth_rx_queue_setup(port_id, ... , mbuf_pool);
 *     rte_eth_tx_queue_setup(port_id, ...);
 *     rte_eth_dev_start(port_id);
 * }
 *
 * // 5. 主循环:轮询收发包
 * while (!quit) {
 *     // 收包
 *     nb_rx = rte_eth_rx_burst(port_id, queue_id, pkts, BURST_SIZE);
 *     // 发包
 *     nb_tx = rte_eth_tx_burst(port_id, queue_id, pkts, nb_rx);
 * }
 *
 * // 6. 停止端口
 * for (port_id = 0; port_id < nb_ports; port_id++) {
 *     rte_eth_dev_stop(port_id);
 *     rte_eth_dev_close(port_id);
 * }
 *
 *
 * 3️⃣ 核心点说明
 *
 * 环节            | 作用                          | 注意事项
 * ----------------|-------------------------------|---------------------------
 * Hugepages       | 提供连续 DMA 内存             | 必须提前分配,否则 EAL 初始化报错
 * 网口绑定        | 解除内核驱动,绑定 PMD        | 没绑定,PMD 无法探测网卡
 * PMD 驱动        | 用户态轮询网卡收发            | 网卡型号不同,PMD 不同(i40e/igb/virtio)
 * NUMA            | 优化 CPU-内存-网卡访问        | 多节点需绑定线程 & 队列到网卡所在 NUMA
 * Mbuf 内存池     | 存放数据包                     | 分配在本地 NUMA 节点 Hugepages
 * 主循环          | 收发包                         | 轮询方式,没有中断,CPU 100% 工作
 *
 *
 * ✅ 总结:
 * - 执行 dpdk-testpmd 前:
 *   1. 分配 Hugepages
 *   2. 绑定网卡到用户态驱动
 *   3. 可选:确定 CPU & NUMA 配置
 * - testpmd 初始化:
 *   1. EAL 初始化(Hugepages + PCI + NUMA + PMD 驱动)
 *   2. 网卡探测
 *   3. 内存池创建
 *   4. 队列配置 & 端口启动
 * - 主循环:
 *   收包 → 发包 → 循环
 *   使用 mbuf 内存池里的大页,避免跨 NUMA 节点访问
 */

9. 再谈大页文件系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 文件系统挂载
xm@xm-virtual-machine:~/xx_dpdk/dpdk/build/app$ mount | grep huge
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,pagesize=2M)


// 应用使用大页内存举例
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>

int main() {
    // 打开文件
    int fd = open("/dev/hugepages/myhugepagefile", O_CREAT | O_RDWR, 0755);
    if (fd < 0) { perror("open"); return 1; }

    // 映射 2MB 内存
    size_t size = 2 * 1024 * 1024;
    void* addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (addr == MAP_FAILED) { perror("mmap"); return 1; }

    // 使用内存
    sprintf((char*)addr, "Hello hugepage!\n");
    printf("%s", (char*)addr);

    // 解除映射
    munmap(addr, size);
    close(fd);
    return 0;
}

10. testpmd 自测

1
2
3
4
5
6
7
sudo ./build/app/dpdk-testpmd -l 0-1 -n 4 \
  --vdev=net_pcap0,iface=lo \
  --vdev=net_pcap1,iface=lo \
  --no-pci \
  -- -i --forward-mode=io --port-topology=chained --auto-start


This post is licensed under CC BY 4.0 by the author.

Contents

Trending Tags