胡 炜,阳 春,李 文
(中国电子科技集团公司第三十研究所,四川 成都 610041)
龙芯是中国科学院计算所自主研发的通用处理器,采用自主LoongISA 指令系统,兼容MIPS 指令。目前系列芯片在政企、安全、金融、能源等应用场景得到了广泛的应用。该系列芯片为通用处理器未针对网络数据处理做特殊设计,在应用于网络报文处理的安全产品时,存在一定性能瓶颈。当前广为流行的数据平面开发套件(DPDK)针对通用处理器进行设计,减少不必要的I/O 开销,更好的利用处理器运算能力,实现了高性能网络数据包处理。为此,本文尝试对该套件在龙芯3A2000 平台进行移植以及性能对比测试。
龙芯3A2000/3B2000 以龙芯3A1000 四核框架结构为基础,处理器核升级为新一代GS464E 架构,内存控制升级为高性能激进调度控制器,IO 总线升级至HT3.0,内部互连网络则进行了大量的性能优化。龙芯3A2000 处理器核心采用自主设计高性能GS464E 微结构,微结构综合技术水平达到了与Intel 的Ivy Bridge 及AMD 的Steamroller 相当的水平。龙芯3A2000 支持自主龙芯指令系统LoongISA,在MIPS64 架构500 多条指令的基础上,在基础指令、虚拟机指令、面向X86 和ARM 的二进制翻译指令、向量指令四个方面增加了近1400 条新指令。龙芯3A2000/3B2000 芯片在对龙芯3A1000 引脚兼容的基础上,大幅提升了系统性能[1]。
该芯片于2015 年推出,而目前最新型号为龙芯3A4000,但其指令集与最新型号差异不大,程序完全可兼容运行。同时,由于其处理性能相对较差也能更好评估DPDK 在该平台上的性能变化情况。
DPDK 全称Intel Data Plane Development Kit,最初由Intel 公司开发的数据平面开发工具开发套件,代码已经开源并得到业界和爱好者的广泛支持和应用。最初该套件针对X86处理器开发也仅适配该架构。目前,通过一系列适配开发,官方已明确支持X86、Power、Arm 等处理器架构。该套件为通用处理器架构下用户空间高效的数据包处理提供库函数和驱动的支持。由于该开发套件的成功,原用于网络设备开发的网络处理器,逐步被通用处理器替代[2]。
DPDK 运行在Linux 操作系统的用户空间,基于系统UIO 机制,实现在用户空间上直接收发网络数据包,绕过内核对数据包处理,避免数据在内核态与用户态间的数据拷贝。相比原生Linux 内核数据转发,采用DPDK 技术后能够大幅提升网络数据的转发性能。同时由于整个业务处理均在用户态进行,大大方便了程序的开发、调试以及维护。
该开发套件主要具备以下技术特点[3]:
(1)UIO 技术,在用户空间直接从网卡收发数据,实现数据零拷贝。
(2)CPU 预取、数据包批处理机制,提高Cache 使用效率,降低数据处理时延。
(3)CPU 亲和性设置,减少任务切换,并确保程序热点一直处于Cache 中。
(4)大页内存技术,提高Cache 命中率和内存访问速率。
(5)无锁队列技术,避免数据在不同CPU 核间传递的锁开销。
DPDK 开发套件包含硬件抽象库(EAL)、网卡轮询驱动、内存池管理、无锁队列等一系列组件,其系统架构如图1 所示。
图1 DPDK 架构
从图1中可以看出DPDK的EAL组件承上启下,在内核空间、用户空间均有出现,EAL 完成对各种硬件平台、操作系统的适配工作,也是移植中需重点关注的部分。
本次移植基于DPDK17.11.4 版本进行,代码结构如图2 所示。
图2 DPDK 代码结构
在DPDK 中新增架构支持需调整config、lib、mk 目录相关的配置文件、EAL 组件和编译配置[4]。
下面将针对X86 架构下的EAL 组件做进一步分析,其组成如下:
(1)内核态
EAL 组件在Linux 系统内核中包括两个模块,igb_uio、kni。这两个模块与硬件平台无关主要适配不同版本的Linux 内核,其中igb_uio 用于实现对PCIE 网卡的UIO 访问提供支持。
(2)用户态
EAL 组件在用户态的部分包括原子操作、字节序、CPU 时间标签计数器、内存拷贝、预取操作、读写锁、自旋锁、向量指令、I/O 读写等等系列操作,与具体硬件相关代码列表如表1 所示。
表1 EAL 组件硬件相关代码列表
从上面的分析可知,实现DPDK 在不同硬件架构的移植主要需解决:
(1)硬件架构相关配置文件、编译选项添加;
(2)EAL 内核模块移植;
(3)EAL用户态组件的硬件架构相关实现调整。
本次移植选用龙芯3A2000 处理器、Intel 公司支持DPDK 的82 580 千兆网卡,运行龙芯公司提供的Loongnix 操作系统,Linux 内核版本为3.10。
在config 目录中添加配置文件defconfig_mips-loongson3a-linuxapp-gcc,其中主要包括:
CONFIG_RTE_ARCH=”mips”
CONFIG_RTE_MACHINE=”loongson3a”
CONFIG_RTE_CACHE_LINE_SIZE=64
CONFIG_RTE_ARCH_64=y
在mk目录中添加arch/mips/rte.vars.mk,machine/loongson3a/rte.vars.mk 文件,定义编译相关选项,其中主要包括:
ARCH ?=mips
RTE_OBJCOPY_TARGET=elf64-tradlittlemips
RTE_OBJCOPY_ARCH=mips:loongson_3a
MACHINE_CFLAGS +=-march=loongson3a
本次移植所选版本DPDK 开发套件可支持3.10版本的Linux 内核,在内核编译添加UIO 功能支持后,igb_uio 模块可直接编译、运行。由于所用龙芯平台的内核不支持MSI 中断方式,需调整igb_uio代码,使用legacy 中断方式。
龙芯3A2000 处理器基于MIPS 架构,采用小端序,大页内存的页大小为32 M,指令集也与X86存在较大的差异。
新建lib/librte_eal/common/include/arch/mips目录,在目录中添加并实现表1 中相关代码,其中关键的是rte_atomic.h(原子操作),rte_cycles.h(CPU 时间标签计数器)。
注:本次移植暂不支持rte_vect.h(向量指令)。
(1)原子操作
原子操作包括内存屏障函数,16 位、32 位、64 位的原子加减、CAS 函数。这里以rte_atomic32_add 为例做说明,其龙芯平台实现如图3 所示[5-6]。
图3 rte_atomic32_add 实现
(2)CPU 时间标签计数器操作
该操作用于快速获得CPU 时间戳,可避免使用开销较大的系统函数gettimeofday。这在数据包轮询处理中非常有用。其函数为rte_rdtsc,实现如图4 所示[5-6]。
图4 rte_rdtsc 实现
其他组件的移植实现不再详细叙述。
为评估DPDK 对龙芯平台网络数据转发性能的影响情况,采用信尔泰网络测试仪对Linux 内核桥转发、DPDK l2fwd 程序转发的吞吐率进行测试评估,评估基于RFC2544 进行,包长包括64 字节、256字节、1280 字节。
Linux 内核转发配置如下:
(1)配置网桥
brctl addbr br
brctl addif br eth0
brctl addif br eth1
ifconfig br up
(2)启用IP 转发
echo 1 >/proc/sys/net/ipv4/ip_forward
测试结果如图5 所示。
通过性能测试结果可以看出包长64 字节时,转发吞吐率仅为155 Mbps,距离2000 Mbps 的理论值相差巨大。同时通过查看详细测试统计,发现该字节包长情况下,稍超出155 Mbps 性能测试时,丢包率已超过1%。这意味着已达到性能瓶颈,进一步提升困难。
首先配置DPDK 运行环境,通过usertools 目录下的dpdk-setup.sh 进行。配置网卡驱动为igb_uio,配置大页内存数量为32(龙芯平台页大小为32 M)。l2fwd 运行参数如下所示[7]:
l2fwd -c 0x6 -n 2 ---p 0x3
测试结果如图6 所示。
图5 内核桥转发吞吐率
图6 l2fwd 转发吞吐率
通过性能测试结果可以看出包长64 字节时,转发吞吐率已提升为551.58 Mbps,性能提升接近3.6倍。同时通过查看详细测试情况,发现该字节包长情况下,稍超出551.58 Mbps 性能测试时,丢包仅仅丢包100 多个,丢包率小于万分之一,平台性能还存在进一步提升空间。初步怀疑网卡收发包的缓冲不足导致在某个临界值时,无法缓存网络报文进而导致丢包。为此,修改l2fwd 程序,增加网卡缓存并再次进行测试。
配置及l2fwd 运行参数与5.2 章节保持一致,仅调整程序缓存大小。
性能测试结果如图7 所示。
图7 l2fwd 再次测试的转发吞吐率
通过性能测试结果可以看出包长64 字节时,转发吞吐率再次提升,达到为692.2 mbps,性能提升相对内核桥转发达到4.5 倍。
本文针对DPDK 开发套件在龙芯平台上进行了移植,并进行了网络数据转发吞吐率测试及对比分析。结果证明DPDK 可以在龙芯平台上正常运行,并且能将转发性能提升接近5 倍。同时l2fwd 仅是简单的数据报文转发测试工具,不能很好利用处理器的多核运算能力,平台转发性能具备较高的提升空间。因此,基于龙芯平台开发网络安全产品具备技术可行性,可满足自主可控要求。