目录
文章目录
Lcore-related options(lcore 相关选项)
查看 CPU 布局
在使用 Lcore-related options 前,我们通常需要对目标系统的 CPU 布局有一个清晰的了解。DPDK 为此提供了一个查看 NUMA Topology 的工具脚步。
$ cd ${RTE_SDK}/usertools/
$ ./cpu_layout.py
======================================================================
Core and Socket Information (as reported by '/sys/devices/system/cpu')
======================================================================
cores = [0, 1]
sockets = [0, 1]
Socket 0 Socket 1
-------- --------
Core 0 [0] [2]
Core 1 [1] [3]
查看更详细的 CPU 布局信息可以使用 hwloc 指令工具。
yum install hwloc -y
- 1
如果没有图形化界面则使用指令:
$ lstopo-no-graphics
Machine (9835MB)
Package L#0 + L3 L#0 (16MB) + L2 L#0 (4096KB) + L1d L#0 (32KB) + L1i L#0 (32KB) + Core L#0 + PU L#0 (P#0)
Package L#1 + L3 L#1 (16MB) + L2 L#1 (4096KB) + L1d L#1 (32KB) + L1i L#1 (32KB) + Core L#1 + PU L#1 (P#1)
Package L#2 + L3 L#2 (16MB) + L2 L#2 (4096KB) + L1d L#2 (32KB) + L1i L#2 (32KB) + Core L#2 + PU L#2 (P#2)
Package L#3 + L3 L#3 (16MB) + L2 L#3 (4096KB) + L1d L#3 (32KB) + L1i L#3 (32KB) + Core L#3 + PU L#3 (P#3)
Package L#4 + L3 L#4 (16MB) + L2 L#4 (4096KB) + L1d L#4 (32KB) + L1i L#4 (32KB) + Core L#4 + PU L#4 (P#4)
Package L#5 + L3 L#5 (16MB) + L2 L#5 (4096KB) + L1d L#5 (32KB) + L1i L#5 (32KB) + Core L#5 + PU L#5 (P#5)
Misc(MemoryModule)
HostBridge L#0
PCI 8086:7010
PCI 1013:00b8
PCI 1af4:1000
PCI 1af4:1001
3 x { PCI 15b3:1018 }
- 15
系统层面的 CPU 隔离
虽然 DPDK Application 可以指定 CPU 绑定,但在操作系统层面,Linux 调度程序仍然会使用这些 CPU 来运行其他的任务,所以还需要额外的 CPU 隔离设置。e.g.
isolcpus=2,4,6
- 1
-c COREMASK
指定用于运行 DPDK Application 的 CPUs。
COREMASK 选项参数是一个十六进制的掩码,MASK(掩码)的每个 Bit(位)对应到相应的 CPU ID。
例如:-c 3
,3 的十六进制为 0x03、二进制为 11。假设有 8 个 CPUs,那么二进制 00000011,就从右到左依次代表 CPU 0-7,且指定使用 CPU 0、1。
-l CORELIST
指定用于运行 DPDK Application 的 CPUs。
CORELIST 选项参数是一个十进制数,直接指定了要用到的 CPU IDs。区别于 COREMASK 是一个十六进制数表示。
例如:-c 3
和 -l 0-1
的效果是一致的。
–lcores COREMAPS
用于将 EAL lcore 或 lcores 绑定到指定的 CPU 或 CPU set 上。
--lcores <lcores[@cpus]>[<,lcores[@cpus]>...]
- 1
示例:
--lcores='(0,4,5)@2,1@3,2@4,3@5'
# lcores 0,4,5 绑定在 CPU2
# lcore 1 绑定在 CPU3
# lcore 2 绑定在 CPU4
# lcore 3 绑定在 CPU5
- 1
- 2
- 3
- 4
- 5
- 6
–master-lcore COREID
指定 Master Core 的 CPU 亲和性,默认为 ID 最小的可用 CPU。
-s SERVICE_CORE_MASK
指定 Slave Core 的 CPU 亲和性,默认不分配。
Memory-related options(Memory 相关参数)
查看 Main Memory 布局
在使用 Memory-related options 之前,我们需要对计算机系统的 Main Memory 布局有一个清晰的了解。
- Channel:CPU Socket 到 Main Memory 的传输通道,是 Main Memory 传输带宽的关键。服务器规格 Socket 通常是 2 / 4 / 6 Memory Channels,每个 Channel 对应一个 Memory Controller(内存控制器)。
- DIMM(Dual Inline Memory Modules,双列直插式存储模块):就是一条条可插拔的内存条。每个 Channel 可以配备多个 DIMM 插槽。
- Rank(芯片列):由多个 Chips(存储芯片)组成,有具体的字宽规格,例如 64bit。内存控制器只允许 CPU 每次与 Memory 进行一组字宽为 64bits 的数据交换。如果 Rank 规格也是 64bit 的,那么一次交换就会在一个 Rank 上完成。
- Chip(存储芯片):有具体的字宽规格,例如:x4(4bit)/ x8(8bit)等。Chip 下属还有更小的组成单元。
Options
--socket-mem <amounts of memory per socket>
:从指定的 NUMA node local memory 分配 HugePage,参数是一个列表值,用逗号分隔。建议使用 --socket-mem 选项指定 DPDK Application 使用的 HugePage 与设置的 HugePage 大小一致。如果没有指定,则由 DPDK Application 在启动时自动完成确定。
# 在 Socket 0 上预分配 1024M,在 Socket 1 上分配 2048M。
--socket-mem 1024,2048
- 1
- 2
-
--socket-limit <amounts of memory per socket>
:指定 NUMA node local memory 分配的配额,0 代表关闭限制。 -
--huge-dir <path to hugetlbfs directory>
:指定的 hugetlbfs 的挂载点目录,例如:/dev/hugepages。 -
-m <megabytes>
:指定预分配的 HugePage 容量。不考虑 NUMA 亲和,不建议使用。 -
-n <number of channels>
:指定使用的 Channels 数量,默认为自动检测。 -
-r <number of ranks>
:指定使用的 Ranks 数量,默认为自动检测。
Others
- –single-file-segments:在 hugetlbfs 中创建少量的文件(仅仅是非传统存储模式)。
- –huge-unlink:创建大页文件后 Unlink (暗指不支持多进程)。
- –match-allocations:释放 hugepages 回到系统完全像他们最初分配前一样。
- –in-memory:不要创建任何共享数据结构,完全运行在存储中。暗指 --no-shconf 和 --huge-unlink。
- –iova-mode <pa|va>:强制设置 IOVA 模式为指定值。
- –no-shconf:不创建共享文件。暗指不支持多进程。
- –no-huge:使用匿名存储而不是大页。暗指不支持多进程。
- –legacy-mem:使用传统 DPDK 存储分配模式。
Device-related options(设备相关参数)
-b, --pci-blacklist <[domain:]bus:devid.func>
:PCIe 设备黑名单,避免 EAL 使用指定的 PCIe 设备。可以使用多次。-w, --pci-whitelist <[domain:]bus:devid.func>
:PCIe 设备白名单,可以使用多次。
NOTE:黑白名单是互斥的。
--use-device [domain:]bus:devid.func
:仅使用指定的以太网设备。使用逗号分隔,不能与 -b 选项一起使用。--vdev <driver><id>[,key=val, ...]
:添加一个虚拟设备,e.g.
--vdev 'net_pcap0,rx_pcap=input.pcap,tx_pcap=output.pcap'
- 1
-
--vfio-intr <legacy|msi|msix>
:为绑定到 VFIO 内核驱动的设备指定中断模式(如果不支持 VFIO,则配置无效)。 -
-d <path to shared object or directory>
:加载额外驱动,参数可以是一个驱动文件或是包含了多个驱动文件的文件夹。可以使用多次。 -
–create-uio-dev:为设备创建 /dev/uioX 文件并绑定指定的 igb_uio 内核驱动。
-
–no-hpet:禁止使用 HPET 定时器。
-
–no-pci:禁止 PCI 总线。
-
–vmware-tsc-map:使用 VMware TSC 映射而不是本地 RDTSC。
Multiprocessing-related options(多进程相关参数)
--file-prefix <prefix name>
:用于 hugepage 文件名的前缀文本,为每个 DPDK App 设置一个不同的共享文件前缀,以及配置目录(默认为:/var/run/dpdk/rte/config)。使用多个不同的前缀文件允许运行多个独立的 DPDK 进程组。DPDK 支持多进程协同完成工作,多进程使用相同的共享文件组成进程组(进程组里的进程分为 primary 和 secondary)。e.g.
# --file-prefix=vhost-1
/dev/hugepages/vhost-1map_12
/dev/hugepages/vhost-1map_11
/dev/hugepages/vhost-1map_10
- 1
- 2
- 3
- 4
NOTE:当我们使用 --file-prefix 可以在响应的路径中找到内存的内置文件 config、hugepage 的信息文件,以及对于 dpdk-pdump 而言非常重要的 server-socket-file mp_socket。dpdk-pdump 通过 mp_socket 来向 DPDK app 发送抓包的请求。反之,如果 dpdk-pdump 找到不这个文件则无法抓包。
$ ll /var/run/dpdk/vhost-1/
总用量 228
-rw-r----- 1 root root 11396 6月 8 23:22 config
-rw------- 1 root root 4096 6月 8 23:22 fbarray_memseg-1048576k-0-0
-rw------- 1 root root 4096 6月 8 23:22 fbarray_memseg-1048576k-0-1
-rw------- 1 root root 4096 6月 8 23:22 fbarray_memseg-1048576k-0-2
-rw------- 1 root root 4096 6月 8 23:22 fbarray_memseg-1048576k-0-3
-rw------- 1 root root 188416 6月 8 23:22 fbarray_memzone
-rw-r--r-- 1 root root 12432 6月 8 23:22 hugepage_info
srwxr-xr-x 1 root root 0 6月 8 23:22 mp_socket
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
-
--proc-type <primary|secondary|auto>
:设置当前的进程类型。 -
--base-virtaddr <address>
:指定基本虚拟地址。DPDK 的 primary 进程尝试使用一个不同的内存映射开始地址。对于因为地址映射冲突而不能启动的 secondary 进程非常有用。
Logging options
DPDK Logging 采用 Logger type 和 Logger level 分离的设计模式。通过 Logging options 设置日志打印级别时,需要通过指定这两个元素。
--log-level=<type_name:level_number>
# e.g. 内建日志类型:EAL 模块设定为 DEBUG 级别。
--log-level=eal:8
# e.g. 自定义日志类型:ixgbe pmd 驱动模块设定为 DEBUG 级别。
--log-level=pmd.net.ixgbe.driver:8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- type_name 有内建类型的 21 种,以及若干个自定义类型。
/* SDK log type */
#define RTE_LOGTYPE_EAL 0 /**< Log related to eal. */
#define RTE_LOGTYPE_MALLOC 1 /**< Log related to malloc. */
#define RTE_LOGTYPE_RING 2 /**< Log related to ring. */
#define RTE_LOGTYPE_MEMPOOL 3 /**< Log related to mempool. */
#define RTE_LOGTYPE_TIMER 4 /**< Log related to timers. */
#define RTE_LOGTYPE_PMD 5 /**< Log related to poll mode driver. */
#define RTE_LOGTYPE_HASH 6 /**< Log related to hash table. */
#define RTE_LOGTYPE_LPM 7 /**< Log related to LPM. */
#define RTE_LOGTYPE_KNI 8 /**< Log related to KNI. */
#define RTE_LOGTYPE_ACL 9 /**< Log related to ACL. */
#define RTE_LOGTYPE_POWER 10 /**< Log related to power. */
#define RTE_LOGTYPE_METER 11 /**< Log related to QoS meter. */
#define RTE_LOGTYPE_SCHED 12 /**< Log related to QoS port scheduler. */
#define RTE_LOGTYPE_PORT 13 /**< Log related to port. */
#define RTE_LOGTYPE_TABLE 14 /**< Log related to table. */
#define RTE_LOGTYPE_PIPELINE 15 /**< Log related to pipeline. */
#define RTE_LOGTYPE_MBUF 16 /**< Log related to mbuf. */
#define RTE_LOGTYPE_CRYPTODEV 17 /**< Log related to cryptodev. */
#define RTE_LOGTYPE_EFD 18 /**< Log related to EFD. */
#define RTE_LOGTYPE_EVENTDEV 19 /**< Log related to eventdev. */
#define RTE_LOGTYPE_GSO 20 /**< Log related to GSO. */
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- level_number 有 8 个。
/* Can't use 0, as it gives compiler warnings */
#define RTE_LOG_EMERG 1U // 系统不可用
#define RTE_LOG_ALERT 2U // 必须立即采取行动
#define RTE_LOG_CRIT 3U // 严重级别
#define RTE_LOG_ERR 4U // 错误级别
#define RTE_LOG_WARNING 5U // 警告级别
#define RTE_LOG_NOTICE 6U // 正常但重要的情况
#define RTE_LOG_INFO 7U // 信息级别
#define RTE_LOG_DEBUG 8U // DEBUG 级别
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
另外 DPDK Loggin 使用了 Syslog 协议作为日志模块的底层支撑。支持的日志设备如下:auth、cron、daemon、ftp、kern、lpr、mail、news、syslog、user、uucp、local0-7。
--syslog <syslog facility>
- 1
默认输出日志文件为:
tailf /var/log/rte.log
- 1
使用基于 Intel VT-d 的 Linux IOMMU Pass-Through 来运行 DPDK Application
要在 Linux 内核中启用 Intel VT-d 硬件辅助的 IO 技术,必须配置一系列内核选项,包括:
- IOMMU_SUPPORT
- IOMMU_API
- INTEL_IOMMU
要使用 Intel VT-d 来运行 DPDK Application,在使用 igb_uio 驱动时,Grub2 参数必须携带 iommu=pt 参数。 这使得主机可以直接通过 DMA 重映射查找网卡的存储空间。另外,如果内核中没有设置 INTEL_IOMMU_DEFAULT_ON 参数,那么还必须要使用到 intel_iommu=on 参数。这可以确保 Intel IOMMU 被正确初始化。
而在使用 vfio-pci 驱动程序时,则直接同时使用 iommu=pt 和 intel_iommu=on。