真正的零拷贝驱动

2835阅读 0评论2010-08-09 yzw131421
分类:LINUX

一个完整支持用户空间零拷贝收发网络报文的开源项目 Network Tapping Zero Copy (NTZC)。与大家分享。
用于捕获报文的零拷贝技术有很多讨论,但迄今还没有一个可用的、开源的实现。最接近的两个实现,一个是PF_RING,一个是NTA,前者仍然存在一次拷贝,后者则年代较为久远且问题多多。借鉴NTA的很多思路,NTZC这个项目基本原理如下

1、将连续的若干页mmap映射到用户空间; 2、内核模块自行管理这些页的内存,并且作为DMA地址交给网卡驱动收发包使用; 3、网卡驱动接收到的报文,如果需要交给用户空间时,该报文的描述符,即报文内存指针的页起始地址和相对偏移位置会被内核模块放到特定的缓冲区中,等待用户空间读取;相应的,报文内存引用计数会增加; 4、用户空间通过文件方式读取报文描述符,并计算出对应的用户空间地址,即可访问报文;在 报文生命周期结束后,通过写文件方式告诉内核空间减少引用计数,如果引用计数为1,内核模块则释放之。 5、用户空间发报文也采取类似的方式,只不过报文内存由用户空间发起命令,内核分配,再交由用户空间使用。

NTZC的设计中,认为既然用户空间可以以足够低的成本收发报文了,因此取消了网卡驱动和Linux 协议桟之间的交互,当然,从NTZC管理的报文内存中拷贝一份出来交给标准协议栈处理,也是很容易的事情。

由于优先考虑到不对内核打补丁,因此没有修改sk_buff的内存管理机制,相反的,实现了和sk_buff接口语义几乎相同,但内存管理机制发生变化的报文数据结构(m_buf,只是借用了BSD里面的数据结构名称,骨子里就是对sk_buff的复制)。使用这个m_buf数据结构及API,需要对网卡驱动进行修改。

正因为是个通用的零拷贝支持模块,网卡驱动的修改很容易,全局替换sk_buff的操作到m_buf的操作即可,因此,理论上任何在Linux中已经有源代码支持的NIC Driver,都很容易被改造成NTZC的NIC驱动,只是,这块网卡将不能在被Linux协议栈使用。NTZC的代码中也给出了Intel 82575改造后的驱动作为例子。

最后,提供一个配套的用户空间API代码,以帮助应用程序方便的访问零拷贝的编程接口。对应的收包和发包示例程序也包含在内。

目前,NTZC已经进行过一些基本测试,开始趋于稳定,简单测试数据表明,收包可以做到单核普通CPU上 >1M pps报文(无论大小包)不丢包且CPU占用率极低;而发包的性能则可以做到libpcap 发包 4倍左右(特别是大包)。

现在用户空间API的定义还是一个非标准的私有接口,未来可能会考虑发展成和libpcap接口一致。


NTZC零拷贝支持恒扬科技 提供的高性能网络业务加速卡,可以实现低成本、高性能、高接口密度的网络流量管理和安全网关方案,这些方案在标准Linux系统上已经有了长时间成熟的商业应用,而零拷贝的支持,将进一步扩大加速卡的应用范围。
 
测试平台有三个:
1、虚拟机,用定时器每个jiffies模拟产生报文,交给sniff程序计数、读报文头然后释放,在2.8G Macbook Pro + Vmware Fusion(2core, 4G memory, 64-bit kernel 2.6.31) 虚拟机上每秒可以做到 250*8k = 2M pps(2K以内各种大小报文对性能没有影响); 此时一个核CPU已经被内核生成包的定时器占满,另一个核跑sniff程序,大概占用了 10-20%;

2、AMD Opteron 2.0G CPU, 4核 1M cache的服务器,BCM万兆卡,kernel 没有打开irq balance;没有运行sniff之前,直接修改原生驱动程序在netif_receive 之前释放收到的报文,CPU1个核可以达到1.7M pps的收包能力,再大就因为ksoftirq占满1个CPU核而导致丢包;运行ntzc+sniff后,CPU可以达到1.1M pps的抓包能力(包括用户空间sniffer收包、计数、读报文头和释放空间),此时CPU1个核被ksoftirq线程占满,另一个核运行sniff程序,CPU占用率 <30%;

3、Intel C2D E4500的一台兼容机上,网卡是我们自己的网络业务加速卡(Semptian NSA卡,4GE业务接口),加速卡和CPU之间的接口是Intel 82575 Dual GE,流量经过双通道负载分担后上到2个CPU核后,可以达到1.5Mpps的抓包能力(包括用户空间sniffer收包、计数、读报文头和释放),每个核CPU占用率 <50%;在报文大小 >=256字节时,sniffer GE线速抓包的CPU占用率降到 10% 以内。

从2和3的情况来看,ntzc本身并没有增强对突发小包的捕获能力,但大大节省了大包到用户空间时memcpy对CPU的占用;另外,由于ntzc可以很容易支持每个核上独立管理报文内存,如果配合网卡的多通道能力,在多进(线)程用户程序处理报文时,可以最大程度减少cache在多个核间同步带来的性能损失。
 

欢迎感兴趣的同好对访问、使用甚至一起完善代码

上一篇:FS3200分流器作为前端分流设备的解决方案
下一篇:低成本、高性能的千兆采集卡