赞
踩
NAPI是linux新的网卡数据处理API,用于提高网络处理效率。外部设备与中央处理器交互一般有两种手段:轮询和中断。中断看似很高效,但是却会遗漏一些数据,避免遗漏的机制要么由硬件实现要么由上层的软件实现,而轮询就没有中断高效了,它会做很多徒劳的操作,而且必须引入暂存机制,就是说由于cpu不可能在每次查询硬件的时候正好有事情可做,但轮询不会遗漏请求。当外部设备活跃时,频繁的中断会导致大量的CPU开销,此时最好用轮询,但是外设活动很缓和的时候,轮询将会浪费CPU资源。无论设备是否发生状态改变,轮询总在进行。在实际情况中,大多数设备的状态改变通常不会那么频繁,轮询空转将白白浪费CPU时间片。NAPI是两者的结合,数据量低时采用中断,数据量高时采用轮询。平时是中断方式,当有数据到达时,会触发中断处理函数执行,中断处理函数关闭中断开始处理。如果此时有数据到达,则没必要再触发中断了,因为中断处理函数中会轮询处理数据,直到没有新数据时才打开中断。
驱动可以继续使用老的 2.4 内核的网络驱动程序接口,NAPI 的加入并不会导致向前兼容性的丧失,但是 NAPI 的使用至少要得到下面的保证:
1. 要使用 DMA 的环形输入队列(也就是 ring_dma,这个在 2.4 驱动中关于 Ethernet 的部分有详细的介绍),或者是有足够的内存空间缓存驱动获得的包。
2. 在发送/接收数据包产生中断的时候有能力关断 NIC 中断的事件处理,并且在关断 NIC 以后,并不影响数据包接收到网络设备的环形缓冲区(以下简称 rx-ring)处理队列中。
NAPI 对数据包到达的事件的处理采用轮询方法,在数据包达到的时候,NAPI 就会强制执行dev->poll 方法。而和不像以前的驱动那样为了减少包到达时间的处理延迟,通常采用中断的方法来进行。
1、支持NAPI的网卡驱动必须提供轮询方法poll()。
2、非NAPI的内核接口为netif_rx(),NAPI的内核接口为napi_schedule()。
3、非NAPI使用共享的CPU队列softnet_data->input_pkt_queue,NAPI使用设备内存(或者设备驱动程序的接收环)。
以下是非NAPI设备和NAPI设备的数据包接收流程对比图:
因此,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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。