写点什么

多队列网卡简介

用户头像
依旧廖凯
关注
发布于: 2021 年 03 月 19 日

多队列网卡是一种技术,最初是用来解决网络 IO QoS (quality of service)问题的,后来随着网络 IO 的带宽的不断提升,单核 CPU 不能完全处满足网卡的需求,通过多队列网卡驱动的支持,将各个队列通过中断绑定到不同的核上,以满足网卡的需求。


常见的有 Intel 的 82575、82576,Boardcom 的 57711 等,下面以公司的服务器使用较多的 Intel 82575 网卡为例,分析一下多队列网卡的硬件的实现以及 linux 内核软件的支持。


1.多队列网卡硬件实现


图 1.1 是 Intel 82575 硬件逻辑图,有四个硬件队列。当收到报文时,通过 hash 包头的 SIP、Sport、DIP、Dport 四元组,将一条流总是收到相同的队列。同时触发与该队列绑定的中断。



2. 2.6.21 以前网卡驱动实现


kernel 从 2.6.21 之前不支持多队列特性,一个网卡只能申请一个中断号,因此同一个时刻只有一个核在处理网卡收到的包。如图 2.1,协议栈通过 NAPI 轮询收取各个硬件 queue 中的报文到图 2.2 的 net_device 数据结构中,通过 QDisc 队列将报文发送到网卡。




3. 2.6.21 后网卡驱动实现


2.6.21 开始支持多队列特性,当网卡驱动加载时,通过获取的网卡型号,得到网卡的硬件 queue 的数量,并结合 CPU 核的数量,最终通过 Sum=Min(网卡 queue,CPU core)得出所要激活的网卡 queue 数量(Sum),并申请 Sum 个中断号,分配给激活的各个 queue。


如图 3.1,当某个 queue 收到报文时,触发相应的中断,收到中断的核,将该任务加入到协议栈负责收包的该核的 NET_RX_SOFTIRQ 队列中(NET_RX_SOFTIRQ 在每个核上都有一个实例),在 NET_RX_SOFTIRQ 中,调用 NAPI 的收包接口,将报文收到 CPU 中如图 3.2 的有多个 netdev_queue 的 net_device 数据结构中。


这样,CPU 的各个核可以并发的收包,就不会应为一个核不能满足需求,导致网络 IO 性能下降。




4.中断绑定


当 CPU 可以平行收包时,就会出现不同的核收取了同一个 queue 的报文,这就会产生报文乱序的问题,解决方法是将一个 queue 的中断绑定到唯一的一个核上去,从而避免了乱序问题。同时如果网络流量大的时候,可以将软中断均匀的分散到各个核上,避免 CPU 成为瓶颈。



/proc/interrupts


5.中断亲合纠正


一些多队列网卡驱动实现的不是太好,在初始化后会出现图 4.1 中同一个队列的 tx、rx 中断绑定到不同核上的问题,这样数据在 core0 与 core1 之间流动,导致核间数据交互加大,cache 命中率降低,降低了效率。



inux network 子系统的负责人 David Miller 提供了一个脚本,首先检索/proc/interrupts 文件中的信息,按照图 4.1 中 eth0-rx-0($VEC)中的 VEC 得出中断 MASK,并将 MASK


写入中断号 53 对应的 smp_affinity 中。由于 eth-rx-0 与 eth-tx-0 的 VEC 相同,实现同一个 queue 的 tx 与 rx 中断绑定到一个核上





set_irq_affinity 脚本位于http://mirror.oa.com/tlinux/tools/set_irq_affinity.sh


6.多队列网卡识别


#lspci -vvv


Ethernet controller 的条目内容,如果有 MSI-X && Enable+ && TabSize > 1,则该网卡是多队列网卡,



Message Signaled Interrupts(MSI)是 PCI 规范的一个实现,可以突破 CPU 256 条 interrupt 的限制,使每个设备具有多个中断线变成可能,多队列网卡驱动给每个 queue 申请了 MSI。MSI-X 是 MSI 数组,Enable+指使能,TabSize 是数组大小。


用户头像

依旧廖凯

关注

还未添加个人签名 2021.02.27 加入

还未添加个人简介

评论

发布
暂无评论
多队列网卡简介