目录:
多队列网卡
-
多队列网卡硬件实现
-
内核对多队列网卡的支持
-
多队列网卡的结构
-
DPDK 与多队列网卡
虚拟化
-
CPU 虚拟化
-
内存虚拟化
-
I/O 虚拟化
Virtio
-
为什么是 virtio?
多队列网卡
多队列网卡硬件实现
有四个硬件队列(Queue0, Queue1, Queue2, Queue3),当收到报文时,通过 hash 包头
的(sip, sport, dip, dport)四元组,将一条流总是收到相同队列,同时触发与该队列绑定的中断。
内核对多队列网卡的支持
Linux 内核中, RPS ( Receive Packet Steering )在接收端提供了这样的机制。RPS 主要是把软中断的负载均衡到 CPU 的各个 core 上,网卡驱动对每个流生成一个 hash 标识,这个 hash值可以通过四元组(源 IP 地址 SIP ,源四层端口 SPOR T,目的 IP 地址 DIP ,目的四层端口DPORT )来计算,然后由中断处理的地方根据这个 hash 标识分配到相应的 core 上去,这样就可以比较充分地发挥多核的能力了。
NAPI 是 linux 上采用一种提高网络处理效率的技术,其核心概念就是不采用中断的方式读取数据,取而代之是采用中断唤醒数据接收的服务程序,然后 POLL 的方式轮询数据。
NAPI 的优点:
-
中断缓和,在日常使用中,网卡产生的高达几 k/s,每次中断都需要系统来处理,是一个很大的压力,而 NAPI 使用轮询是禁止了网卡接收中断,减小处理中断的压力。
-
数据包节流,NAPI 之前的 NIC 总在接收数据包之后产生一个 IRQ,接着在中断服务函数将 skb 加入本地 softnet,然后触发本地 NET_RX_SOFTIRQ 软中断后续处理。如果包速过高,因为 IRQ 的优先级高于 SoftIRQ,导致系统的大部分资源都在响应中断,但 softnet 的队列大小有限,接收到的超额数据包也只能丢掉,所以这时这个模型是在用宝贵的系统资源做无用功。而 NAPI 则在这样的情况下,直接把包丢掉,不会继续将需要丢掉的数据包扔给内核去处理,这样,网卡将需要丢掉的数据包尽可能的早丢弃掉,内核将不可见需要丢掉的数据包,这样也减少了内核的压力。
NAPI 的缺点:
-
对于上层的应用程序而言,系统不能在每个数据包接收到的时候都可以及时地去处理它,而且随着传输速度增加,累计的数据包将会耗费大量的内存。
-
另外一个问题是对于大的数据包处理比较困难,原因是大的数据包传送到网络层上的时候耗费的时间比短数据包长很多(即使是采用 DMA 方式)。所以,NAPI 技术适用于对高速率的短长度数据包的处理。
QDisc 是 queueing discipline 的简写,它是理解流量(traffic control)的基础。无论何时,内核如果需要通过某个网络接口发送数据包,需要按照这个接口配置的 qdisc(排队规则)把数据包加入队列。然后,内核会尽可能多的从 qdisc 里面取出数据包,把它们交给网络适配器模块。最简单的 QDisc 是 pfifo,他不对进入的数据包做任何处理,数据包采用先入先出的方式。

多队列网卡的结构
Linux 内核的网卡结构体是由 net_device 表示,数据包是由 sk_buff 表示的
接收端
