Abstract and Introduction
netmap:一个新型的框架,使得现在的操作系统可以在不需要特定硬件或针对应用进行改变的前提下,每秒钟通过1..10 Gbit/s的link处理百万级的packet。
减少或移除了三处packet处理过程中的cost:
- 每个packet的动态内存分配——通过预分配资源进行处理
- 系统调用的开销——摊销到large batches上
- 内存的备份——在kernel与userspace中共享buffer与metadata,同时仍保护了到device register和其他kernel memory areas的access。
主要贡献:
- performance超过了大部分的previous work
- 提供了一个architecture,在不使用特定硬件的条件下,紧密地整合了现有的操作系统primitives,且容易使用与维护。
performace具体性能:
- 基于FreeBSD,Linux和几个1Gbit/s 10Gbit/s的网络适配器实现
- 一个900MHz的single core接受发送速率可以达到14.88Mpps,超过了传统API的20倍。在使用了libpcap库(libpcap is a system-independent interface for user-level packet capture. )的情况下,仍能加速五倍以上。
- 在wire与userspace应用中传递一个packet只需要低于70个CPU clock cycles。
容易使用与维护的具体表现:
- 用户很难crash这个系统,因为设备的registers和关键的kernel memory区域不会暴露给用户,且用户无法在kernel中插入伪造的memory指针。
- netmap使用了一个极其简单的数据模型,使其可以适用于zero-copy的packet传递。
- netmap支持multi-queue的适配器。
- netmap使用了标准的系统调用。
以上几点使得netmap可以很容易地将现有应用转移到新的mechanism上,也可以很容易地通过有效地使用netmap API来实现新的应用。
为了提高性能,其他系统进行的处理:
- 完全在kernel中运行
- 绕开设备驱动,通过将NIC(网络适配器)的数据结构完全暴露给用户空间的应用,来堆放整个网络。
这些系统的缺陷:
- 依赖于特定的硬件特征
- 指向硬件的access不受保护
- 与现有的OS primitives整合得不好
Background
主要阐述了通用的OS的network stack组织结构,并展示了不同stages中的processing costs。
NIC数据结构与操作
NIC:通过buffer descriptors中的circular queues (rings) 管理packets的输入输出。
- 接收时:输入的packets被存储在下一个可使用的buffer中,length/status信息被写回到slot中。通过中断来告知CPU这些events。
- 传递时:将请求写入到NIC的register中,然后开始发送在TX(Transmit Traffic) ring中被标记为available的packets。
- 问题:高packet传输率时,中断处理比较昂贵,可能导致receive livelock,可能不能到达一定的装载量(load)。
- 解决方法:Polling device drivers,Hardware interrupt mitigation
Kernel与用户API
- OS中会保存一个NIC数据结构的影备份(见Figure1中的mbufs),其中存储着背个packet的元数据:size, source, destination interface, attributes, 标记NIC与OS应如何处理该buffer的flags。
- Driver/OS:设备驱动与OS间的API会希望subsystems可以保存packets来进行延迟处理,因此buffer和元数据需要被备份及reference-counted,这个处理则会导致运行时产生很大的overhead。API的通信,buffer chain的分配/管理/navigating也很影响性能。
- Raw packet I/O:为用户程序读/写raw packet的标准API, 每个packet至少需要一次kernel与user space间的memory copy及一个系统调用。
Case Study: FreeBSD sendto()