SylixOS 网络零拷贝技术
1. 网络零拷贝介绍
网络零拷贝技术指的是在数据报文从网络设备到用户程序传递的过程中,一种减少数据拷贝次数,减少系统调用,实现CPU的零参与,从而减轻 CPU负载的技术。
1.1 SylixOS网络现状
SylixOS网络使用的是Lwip协议栈,其数据报文从网络设备到用户程序只需要一次拷贝即可实现。产生这次拷贝的原因是数据报文从网络设备往协议栈传输时,数据格式不一样。网络协议栈需要专门的数据结构(pbuf)来管理报文,而设备层只会将数据本身存放在一块内存缓冲区中。
1.2 SylixOS零拷贝技术使用前提
SylixOS目前版本已经支持网络零拷贝,但这只适用于x86架构的CPU。主要原因是使用零拷贝技术后,网络协议栈对报文数据的管理并不会使用cache。这种方式在ARM等架构上使用时,协议栈需要对报文不停的访问,但由于没有cache,因此访问效率反而会降低。
2. 网络零拷贝技术实现
2.1 不使用零拷贝的报文接收流程
不使用零拷贝的数据接收流程如图 2‑1 所示。
图 2‑1 不使用零拷贝接收
不使用零拷贝时,报文从网络设备到用户应用程序,只会进行一次拷贝操作,这一次拷贝操作位于网卡驱动中,即网络设备在接收到DMA搬运的数据报文时,会将报文的内容拷贝到协议栈支持的数据管理结构(pbuf)中。如图 2‑1 ,拷贝后的报文位于Lwip协议栈管理的内存区内。
拷贝完成后,协议栈会对pbuf管理的报文做各种分析,最后,通过IPC(进程通信方式)与用户程序进行交互。使用IPC就可以不进行数据拷贝,应用程序通过信号量、消息邮箱等机制去通知协议栈,让协议栈进行对应的处理。
2.2 使用零拷贝的报文接收流程
使用零拷贝接收流程如图 2‑2 所示。
图 2‑2 使用零拷贝接收
SylixOS里零拷贝是将报文从驱动往协议栈传送的一次拷贝也省去。实现的思路是让协议栈可以直接使用驱动收到的网络数据。因此,驱动代码需要将用于接收网络报文的数据结构换成协议栈数据管理的结构,即换成pbuf类型。实现的方式是将原本驱动中描述符指向的buf地址换成pbuf结构里payload指针指向的内容即可。
主要实现流程如下:
-
驱动需要创建一块大的零拷贝pbuf内存池(zc_pool),后续的报文接收的pbuf都从零拷贝pbuf池子里分配;
-
驱动初始化描述符时,不调用DMAmalloc去分配一块物理地址,而是从上一步分配的零拷贝池子里获取一个零拷贝的pbuf,然后将pbuf所指向的内存地址赋值给DMA接收描述符;
-
此后,网卡接收处理函数不需要再做拷贝,而是直接将收到报文的描述符对应的pbuf传到协议栈,同时按照上一步的方法,给这个完成接收的描述符分配一个新的零拷贝pbuf。
由于上述申请的零拷贝pbuf类型是custom_pbuf类型,因此经过上述操作后,协议栈对接收到的pbuf进行释放操作时,会调用零拷贝对应的释放函数。