浅谈NAPI

什么是NAPI?

NAPI是linux新的网卡数据处理API,用于提高网络处理效率。外部设备与中央处理器交互一般有两种手段:轮询和中断。中断看似很高效,但是却会遗漏一些数据,避免遗漏的机制要么由硬件实现要么由上层的软件实现,而轮询就没有中断高效了,它会做很多徒劳的操作,而且必须引入暂存机制,就是说由于cpu不可能在每次查询硬件的时候正好有事情可做,但轮询不会遗漏请求。当外部设备活跃时,频繁的中断会导致大量的CPU开销,此时最好用轮询,但是外设活动很缓和的时候,轮询将会浪费CPU资源。无论设备是否发生状态改变,轮询总在进行。在实际情况中,大多数设备的状态改变通常不会那么频繁,轮询空转将白白浪费CPU时间片。NAPI是两者的结合,数据量低时采用中断,数据量高时采用轮询。平时是中断方式,当有数据到达时,会触发中断处理函数执行,中断处理函数关闭中断开始处理。如果此时有数据到达,则没必要再触发中断了,因为中断处理函数中会轮询处理数据,直到没有新数据时才打开中断。

使用 NAPI 先决条件

驱动可以继续使用老的 2.4 内核的网络驱动程序接口,NAPI 的加入并不会导致向前兼容性的丧失,但是 NAPI 的使用至少要得到下面的保证:

1.         要使用 DMA 的环形输入队列(也就是 ring_dma,这个在 2.4 驱动中关于 Ethernet 的部分有详细的介绍),或者是有足够的内存空间缓存驱动获得的包。

2.         在发送/接收数据包产生中断的时候有能力关断 NIC 中断的事件处理,并且在关断 NIC 以后,并不影响数据包接收到网络设备的环形缓冲区(以下简称 rx-ring)处理队列中。

NAPI 对数据包到达的事件的处理采用轮询方法,在数据包达到的时候,NAPI 就会强制执行dev->poll 方法。而和不像以前的驱动那样为了减少包到达时间的处理延迟,通常采用中断的方法来进行。

NAPI和非NAPI的区别

1、支持NAPI的网卡驱动必须提供轮询方法poll()。

2、非NAPI的内核接口为netif_rx(),NAPI的内核接口为napi_schedule()。

3、非NAPI使用共享的CPU队列softnet_data->input_pkt_queue,NAPI使用设备内存(或者设备驱动程序的接收环)。

以下是非NAPI设备和NAPI设备的数据包接收流程对比图:

 NAPI 的缺陷

  1. 不能及时处理数据包,随着数据包到达速度的增加,会消耗大量的内存。
  2. 对于大数据包低速率的情况,接收中断就会急剧增加,直到最后每个数据包都需要一次 POLL 的方法来进行处理,最后的结果就是每个中断都需要一次 POLL 的方法,最后造成效率的急剧下降,以至于系统的效率就会大大降低。

因此,NAPI 并不是改善网络效率的唯一途径,只适用于大量的数据包而且尽可能是小的数据包,根本的解决途径还是在于上层应用程序能够独占网络设备,或者是提供大量的缓冲资源。

文章为整理相关资料写成,详细参考

https://www.ibm.com/developerworks/cn/linux/l-napi/

https://www.cnblogs.com/ck1020/p/5939829.html

https://blog.csdn.net/bingqingsuimeng/article/details/7858119

https://blog.csdn.net/zhangskd/article/details/21627963

猜你喜欢

转载自blog.csdn.net/qq_29187357/article/details/84711429
今日推荐