dpdk学习01—环境搭建

dpdk学习01—环境搭建

# 什么是dpdk?

dpdk是intel开源的一个网络加速工具包,目的是在IA平台上解决高性能网络数据包处理的问题。
传统网络包处理的过程是:

  1. 网卡收到数据包
  2. 网卡将帧DMA到内存
  3. 网卡发送硬中断
  4. cpu响应中断,调用对应函数进行收包
  5. 将ring buffer保存到skb
  6. 内核协议栈处理帧
  7. 用户进程处理报文

因为传统网络包处理是中断驱动的,所以在大量网络请求下会出现irq风暴,降低处理性能。除此之外还涉及到多次用户态和内核态数据拷贝,降低性能。当时流行的做法是通过硬件来加速网络包处理,但是dpdk的产生证明了通用化硬件在软件极致优化的情况下也能做到达到io的极限。 基于IA处理器的DPDK技术,很好地解决高性能数据包处理的问题,这些技术包括:

  • 通过轮询来处理数据包,避免中断上下文切换的开销
  • 使用用户态驱动,避免内核态到用户态不必要的内存拷贝和系统调用
  • 设置cpu亲和性与独占,避免线程在不同核心间频繁切换; 限制某些核心不参与Linux系统调试, 可使线程独占该核心
  • 利用大页内存降低TLB miss

# dpdk安装

环境:Mac m1,Vmware Fusion 虚拟机,Ubuntu 20.04
版本:dpdk 22.11.4
因为ubuntu已经有了dpdk的二进制源,直接安装即可,如果需要二进制安装,可参考官方文档

1
apt install -yq dpdk dpdk-dev dpdk-doc gcc g++

# 配置环境

dpdk环境最好配置2张网卡,一个选择桥接,用来配置dpdk开发,一个选择NAT,用来和宿主机连接。cpu选择4核,内存选择8G,按宿主机资源即可。 启动dpdk环境需要3步:

  1. 安装uio启动
  2. 将网卡和dpdk绑定
  3. 设置内存大页

# 安装驱动

dpdk一般多采用两种驱动:vfio-pci和igb_uio。
vfio-pci:

1
2
3
4
sudo modprobe vfio && \
sudo modprobe vfio-pci
# 配置noiommu_mode。
sudo bash -c 'echo 1 > /sys/module/vfio/parameters/enable_unsafe_noiommu_mode'

igb_uio: ``

1
git clone https://dpdk.org/git/dpdk-kmods

下载以后make安装即可

1
2
3
4
pushd dpdk-kmods/linux/igb_uio
sudo make
sudo depmod && sudo insmod igb_uio.ko
popd

或者直接apt install dpdk-kmods-dkms

# 绑定网卡

使用dpdk安装自带了工具`dpdk-devbind.py直接配置:

1
2
dpdk-devbind.py -s # 查看网卡绑定状态
dpdk-devbind.py -b vfio-pci 0000:03:00.0 # 将0000:03:00.0网卡绑到vfio-pci驱动

# 设置hugepage

x86架构CPU支持2M和1G大小的pagesize,一般linux默认配置了2M的大小,通过cat /proc/meminfo|grep -i huge来查看。

1
2
3
4
5
6
# 挂载1G的hugepage
sudo mkdir /mnt/huge
sudo mount -t hugetlbfs -o pagesize=1G none /mnt/huge
# 设置巨页数量 以下都是在numa节点0上设置 如果设置其他节点可修改路径
sudo bash -c 'echo 2 > /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages'
sudo bash -c 'echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages'

方便起见,写一个init脚本,方便快速拉起dpdk环境:

1
2
3
4
5
6
7
8
modprobe vfio
modprobe vfio-pci
echo 1 > /sys/module/vfio/parameters/enable_unsafe_noiommu_mode
dpdk-devbind.py -b vfio-pci 0000:03:00.0
dpdk-devbind.py -b vfio-pci 0000:1a:00.0
mount -t hugetlbfs -o pagesize=1G none /mnt/huge
echo 2 > /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

# 第一个测试程序

测试程序使用dpdk官方提供的testpmd,测试dpdk网卡绑定 。
测试环境: 两台虚拟机,要求都已经安装了dpdk的环境。

# 安装pktgen

1
2
3
4
5
6
7
git clone git://dpdk.org/apps/pktgen-dpdk
cd pktgen-dpdk/
meson build
cd build
ninja
# app/pktgen 编译出的程序
mv app/pktgen /usr/local/bin

# 开始测试

node1 node2 mac信息

1
2
3
4
5
6
node1
绑定接口名称: ens161, MAC地址: 00:0c:29:a5:21:1e, IP地址: 未分配
绑定接口名称: ens256, MAC地址: 00:0c:29:a5:21:14, IP地址: 未分配
node2
绑定接口名称: ens161, MAC地址: 00:0c:29:57:f0:2f, IP地址: 未分配
绑定接口名称: ens256, MAC地址: 00:0c:29:57:f0:25, IP地址: 未分配
  1. 在node1 上运行testpmd:
1
dpdk-testpmd -l 0-1 -n 1 -- -i
  1. 将网卡设为只读模式、非混杂模式(这样就只收pktgen发来的包)后开始收包
1
2
3
4
set fwd rxonly
set promisc all off
show  port stats all
start
  1. 在node2 运行pktgen 进行发包
1
pktgen -l 0-1 -n 3 -- -P -m "[1].0"
  1. 设置目的mac,发送100个包
1
2
3
set 0 dst mac 00:0c:29:a5:21:1e
set 0 count 100
start 0

在node1上执行 show port stats all,此时可以发现其中一张网卡多了6400,pktgen发包默认大小64字节。 执行quit退出 测试符合预期,环境搭建完成。

Licensed under CC BY-NC-SA 4.0
最后更新于 Apr 22, 2024 19:16 CST