高性能数据平面 & DPDK

在计算机网络课程里面,我们学习了各种网络设备,协议,和网络层次模型。为了适应网络传输数据量的增大,逐步将数据和控制分别从逻辑和硬件上分离。

实际编写网卡驱动程序后,对耗时点,和优化点,有了一些直观的体会。

本质上驱动程序就是一个中断,外围设备网卡和CPU异步的执行,但数据包到达网卡(NIC),通过DMA(Direct Memory Access)复制到主机的内存空间并触发中断。

那么对于传统网卡驱动以下几个开销是无法忽视的。

  1. 网卡中断,网络带宽变大,大量的频繁的中断,带来的上下文切换时间是一个不可忽略的点。
  2. 内存拷贝,应用程序位于用户空间,我们发现,不论接受数据:网络数据->内核空间->用户空间,还是发送数据:用户空间->内核空间->网络数据。都存在两次的拷贝。
  3. 锁,网卡作为一种互斥资源,先获得网卡需要加锁,同时Linux内核的网路协议栈中,对于共享资源,也有相关的锁进行同步
  4. 缓存,缓存未命中。页表在TLB的命中率,相关缓存设计,页地址转换,和页表读取时间。

以上1-3问题的出现,我们发现,都是因为我们依赖于内核处理,有没有什么办法即可以完成内核所完成功能,又不需要经过内核。

内核旁路

内核旁路技术,即应用程序不通过内核直接操作硬件,应用程序直接和网络硬件通信。1.没有了用户空间和内核空间的切换2. 即使用户空间驱动奔溃,不会造成操作系统奔溃

而DPDK(Data Plane Development Kit)就是一个全面的网络内核旁路解决方案。(Netmap并没有真正从内核中脱离,直接操作网卡)


关于4 的问题,是硬件设计,以及我们如何去使用设备特性

平台增强

我们知道CPU中每个核都有其独立的硬件支持,而核之间的切换会到导致原来核上的缓存失效,那么我们将任务绑定在特定核上,将有效提高缓存命中率。

Intel Xeno E5系列处理器,引入DDIO(Data Direct I/O)技术,直接将I/O流量传输到处理器高速缓存(LLC),而不需要任何软件参与。

Hugepage,通过扩大页的大小,可以有效减少TLB失效的情况,减少访问页表的次数,缩短了地址转化时间。

NUMA,普通CPU多个核共享内存和硬件,当内存访问到达饱和时,那么增加处理器核并不能获得更高的性能,而NUMA就是每个处理器有独立的本地内存,I/O设备。


DPDK

DPDK在IA(Intel Architecture)多核处理器的核心思想如下

  1. 轮询模式,避免了传统网卡中断上下文开销
  2. 用户态驱动:避免内核和用户空间的数据拷贝和系统调用
  3. 降低访问存储开销:大页减低TLB命中率,保持缓存对齐避免处理器核之间缓存交叉访问
  4. 亲和性和独占:特定线程与和核绑定
  5. 批处理:一次处理多个包,降低一个包处理的平均开销。有点像外存的读取,以块为单位。
  6. 利用IA新硬件技术,专用硬件

开发模型

Run-to-Completion模型

一核处理,一气呵成

Pipeline模型

流水线,每个核相当于流水线上的工人,只完成特定的一部分事情

实现框架

  • 核心库:抽象内存管理,无锁环,缓存池
  • 流分类:匹配(精确,最长,通配匹配)
  • 软件加速库:IP分片,报文重排,排序
  • Stats:查询和统计数据组件
  • Qos:提供网络服务质量组件,限速(Meter)和调度(Scheduler)
  • 数据包分组框架:多核Pipeline模型的基础组件

核心库

系统抽象层

屏蔽环境,提供统一接口,包括DPDK的加载、启动,支持多进程和多线程,核亲和/绑定,系统内存的管理,总线访问,设备加载,CPU特性抽象,跟踪调试函数,中断处理,Alarm处理

rte_ring

支持多生产者和多消费者的无锁环,是FIFO队列

rte_mempool

负责管理从内存分配mempool的库。

rte_mbuf

封装网络帧缓存或控制消息缓存,以ring的形式存在于MemPool中。

端口对于的以太网设备,常用初始化步骤API

1
2
3
4
rte_eth_dev_configure();//配置设备
rte_eth_tx_queue_setup();//创建发送队列,对于硬件设备,驱动为其分配DMA ring用于发送数据包
rte_eth_rx_queue_setup();//创建接受队列,对于硬件设备,驱动为其分配DMA ring用于发送数据包
rte_eth_dev_start();//启动该设备

具体可看DPDK开发者手册


网卡

网卡的缓冲区是NIC ring的环形数组,缓冲区是操作系统和网卡硬件共享。网卡将网络数据放到缓冲去,操作系统通过mbufs指针读出,发包流程正好相反。