总结下,网卡内核驱动收发包流程,并记录一些网卡驱动的兼容性列表
网卡驱动&&固件兼容性列表
首先明确一点,对于计算机来说,网卡属于外设,既然是外设,其必然会有自身硬件,而在外设自身硬件上运行的程序,就被称为固件。计算机想要控制外设,就需要使用驱动,利用驱动程序与外设固件配合,进而控制外设。所以某一版本的驱动,往往有其对应的固件版本,以下就列举下比较常见的网卡驱动和固件兼容性列表的获取方式。
●Intel网卡
1.Network Adapter Device Feature Support Matrix PDF(需要从网络适配器的发布文档上获取,例如:332191_X710-XXV710-XL710 Feature Summary Rev4.8.pdf)
2.DPDK官方文档:https://doc.dpdk.org/guides/nics/i40e.html(DPDK官网上会列举一些测试过的网卡驱动和固件)
●Mellanox网卡
https://docs.mellanox.com/display/OFEDv512580/General+Support+in+MLNX_OFED(驱动发布文档)
●Broadcom网卡
联系服务器厂商获取(一般是戴尔的服务器)
●Qlogic网卡
1.https://driverdownloads.qlogic.com/QLogicDriverDownloads_UI/SearchByProduct.aspx?ProductCategory=325&Product=1296&Os=175#49(推荐用最新的固件+驱动,老版本的固件,Qlogic可能就直接不支持了)
2.2.DPDK官方文档:https://doc.dpdk.org/guides/nics/qede.html (有说明DPDK驱动需要搭配的固件版本)
名词解析
●DMA控制器:DMA(Direct Memory Access)控制器是一种在系统内部转移数据的独特外设(一般会集成在芯片内部),DMA控制器可将外设I/O数据搬运到某处(有的DMA控制器也能支持内存间内存的互拷),且搬运全程无需计算机的CPU参与,从而提高了CPU的处理效率。
●中断上半部:在网络收包流程分为中断上半部和中断下半部,其中硬中断部分被称为中断上半部(kernel无法嵌套同种硬中断,所以外设硬中断的处理逻辑,往往需要足够短小,才能避免丢中断的问题)。
●中断下半部:软中断部分,则被称为中断下半部。
网卡收包
●收包大致流程如上图所示:
1.在网卡PCIe和网卡初始化时,会初始化DMA控制器,将网卡和DMA通道进行绑定等操作(判断一款网卡硬件层面是否支持DMA操作,可查看其datasheet或发布的特性文档)。
2.当包到达网卡后,网卡会发起DMA传输请求,DMA控制器便会进行报文拷贝。
3.当DMA单元将网卡收到的报文,拷贝到DMA环形缓冲区后,会产生一个DMA硬中断,此中断将被kernel所感知,从而绑定了该中断的CPU,将进入到硬中断处理函数do_IRQ中(中断上半部开始)。
4.在硬中断处理函数中,会调用网卡驱动所注册的硬中断处理函数xxx_intr,处理一些网卡自身需要的短小的处理逻辑。
5.在xxx_intr函数准备结束时,会在当前CPU上,挂起一个软中断,为软中断(中断下半部)做准备。
6.当xxx_intr函数结束后,继续回到do_IRQ中,此后do_IRQ会调用irq_exit(中断上半部基本已结束),在此函数中,将唤醒该CPU上的ksoftirqd线程(软中断处理线程),此后报文的处理,便被ksoftirqd线程所接管(中断下半部开始)。
7.在ksoftirqd中将调用驱动实现的xxx_poll函数,将缓冲区中的报文取出,调用netif_receive_skb将报文送入协议栈处理,并补充收包描述符。
●关键函数调用关系(已ixgbe+PCIe支持MSIX特性+NAPI为例)
硬中断入口函数:
do_IRQ
硬中断:
do_IRQ->ixgbe_msix_clean_rings->napi_schedule->napi_schedule->__napi_schedule->__raise_softirq_irqoff//挂起软中断(PCIe支持MSIX特性的前提下,ixgbe的硬中断中,啥都没干,直接挂起了软中断)
软中断:
do_IRQ->irq_exit->invoke_softirq//唤醒ksoftirqd/[cpu号]软中断处理线程
ksoftirqd/[cpu号]线程:
net_rx_action->ixgbe_poll->ixgbe_clean_rx_irq->ixgbe_rx_skb->napi_gro_receive->napi_gro_complete->netif_receive_skb//进入内核协议栈处理
●收包流程中需要注意的点
1.ksoftirq线程处理软中断。
2.硬中断绑定到了哪个CPU上,则软中断也会被与该CPU所绑定的ksoftirqd线程处理(cat /proc/irq/19/smp_affinity_list)。
3.两个命令mpstat -P ALL 1(查看CPU负载情况,%soft打满时,及达到了内核收包极限)和sar -I xxx -n DEV 1(查看网卡收发包数量以及中断数量)(可用于判断是否达到了某处的性能瓶颈)。
4.xxx_poll软中断收包函数和xxx_intr硬中断处理函数,都是由网卡驱动维护的(由网卡驱动所维护的函数,及其大致功能需要特别关注,可用于判断是否是驱动版本所引发的问题)。
网卡发包
●发包大致流程如上图所示:
1.报文在走完内核协议栈后,将调用dev_hard_start_xmit进入网卡驱动的发包函数中。
2.使用网卡驱动所注册的ndo_start_xmit函数,触发DMA拷贝,拷贝报文至网卡。
3.当DMA完成后,将会再次发送DMA硬中断,此后便再次走了一遍收包流程,只是在此次软中断中,是去回收tx描述符。
●关键函数调用关系(已ixgbe+PCIe支持MSIX特性+NAPI为例)
硬中断入口函数:
do_IRQ
硬中断:
do_IRQ->ixgbe_msix_clean_rings->napi_schedule->napi_schedule->__napi_schedule→__raise_softirq_irqoff//挂起软中断(PCIe支持MSIX特性的前提下,ixgbe的硬中断中,啥都没干,直接挂起了软中断)
软中断:
do_IRQ->irq_exit->invoke_softirq//唤醒ksoftirqd/[cpu号]软中断处理线程
ksoftirqd/[cpu号]线程:
net_rx_action->ixgbe_poll->ixgbe_clean_tx_irq//回收tx描述符
●发包流程中需要注意的点
1.包发给网卡后,依然会触发再次触发硬中断和软中断,所以当发包后,依然会消耗些许设备的CPU资源,需要留意。
总结
以上便是网卡内核驱动大致的收发包流程,可以看出其涉及了内核中断、NAPI框架、网卡驱动实现、以及网卡固件三方面的协同工作,所以当遇到问题时,也应该从这三方面去排查处理。
尚存疑问
应用程序系统调用,CPU时间片用完后(一般用完前都能发出去),是本CPU所绑定的软中断内核线程继续处理,还是随机一个ksoftirqd继续处理?