网卡架构
OS 分配两个内存空间,用来放 Ring buffer,可以用两个 ring 一个是 TX ring 一个是 RX ring,每一个 descriptor (entry) 描述一个 packet 的基址/长度。
TX descriptor:
- base address of a packet
- length
- status bit(已发送还是将要发送)
- flags for options
两个寄存器,指向 ring 当前头和尾。
完全参考这个:io-paravirtualization-tour.pdf
以太网(Ethernet)
是一种计算机局域网技术。是一个数据链路层以及物理层的概念。
以太网的一个重要特点:数据链路层和物理层是相关的。由于以太网的物理层和数据链路层是相关的,针对物理层的不同工作模式,需要提供特定的数据链路层来访问。
一张网卡同一时间可以配有几个 IP 地址?/ 网卡是几层设备?
每一个网卡都可以有一个 IP 地址,那么网卡一定是三层设备吧?
但是其实网卡是 2 层设备,就是工作在数据链路层的。原因见 ARP 协议^。
多个 IP 地址。
网卡本身是感知不到 IP 地址这个概念存在的,网卡只能知道 MAC 地址的存在。配置多网卡的意义在于:
为了让每个网站都有独立的 IP 地址。 这样,服务器可以根据请求的目标 IP 地址,将流量正确地路由到对应的网站。 意义:这种配置使得服务器可以高效地使用单一物理接口服务多个网站,而无需为每个网站配备独立的网络接口。
也就是多个网站,每个网站流量都不大的时候,就不用买很多张网卡浪费资源了。
DPDK
还记得 [[2025-04-02-NIC#网卡的环形队列(Ring buffer)]] 吗?DPDK 把 Ring buffer 都放到了用户空间,相当于完全 bypass 了 kernel。但是这就不得不依赖于 DPDK 提供的软件栈进行开发了,因为每一个 DPDK 的用户都直接从 Ring buffer 开始写协议进行优化是不现实的。
和 RDMA 区别:
- 两者均为 kernel bypass 技术,可以减少中断次数,消除内核态到用户态的内存拷贝;
不同点:
- DPDK 是将协议栈上移到用户态,而 RDMA 是将协议栈下沉到网卡硬件,DPDK 仍然会消耗 CPU 资源;因此,DPDK 的并发度取决于 CPU 核数,而 RDMA 的收包速率完全取决于网卡的硬件转发能力。
- DPDK 用户可获得协议栈的控制权,可自主定制协议栈;RDMA 则无法定制协议栈,只能用 RDMA 协议。
总结:
- 从灵活性上来说,DPDK 是无疑是更加灵活的,因为其允许用户自定义协议,代价就是协议仍然需要 CPU 来跑。
网卡收发包流程 / 网卡收发包需要几次拷贝?
经过几次拷贝?
不考虑报文特殊处理,包会放在 4 个位置,需要 2 次数据拷贝:
- 刚开始的时候,包到来,到达网卡设备上的缓冲区;
- 网卡通过 DMA 放到 [[2025-04-02-NIC#网卡的环形队列(Ring buffer)]] 中去,这一步并不算做需要优化的大开销内存拷贝,原因在这里 [[#内存拷贝]]。
- 网卡的环形队列固定大小,内核需要及时将这些包取走否则队列满网卡将丢弃接下来的包。内核从网卡环形队列中取走放到
struct sk_buff
结构中,这是第一次拷贝,在内核的接下来协议栈、socket 处理中,始终使用这个结构不需要内存拷贝。 - 第二次内存拷贝发生在内核态到用户态中,用户态进程取回报文中的内容。
可见这两次拷贝都是必须的,发包过程也是一样的。
linux网络数据从网卡到应用层需要几次内存拷贝?_linux socket几次拷贝-CSDN博客
一个非常全的整体收发包流程:Linux 网络栈接收数据(RX):原理及内核实现(2022) 里面提到了从 ring buffer 到 skb 结构体的这一次复制。
网卡 multi-host / socket direct
支持在多个主机之间共享一张网卡,多个主机可以是同一个物理主机的不同接口,或者不同物理主机的不同接口。
这样做的好处主要是是节省成本,假设一张 100G 的网卡成本 10000,200G 的成本在 15000,当一台服务器或者一个节点需要一个 100G 的网卡是,你可以选择每个节点或配备一张网卡,或者选择一张带有 Multi Host 的 200G 网卡,很显然,从成本来讲孰优孰劣一目了然。
NVIDIA Socket Direct 是 NVIDIA 的一种 multi-host 技术,此技术允许双插槽服务器中的每个 CPU 通过其专用 PCIe 接口直接访问网络。请看下图:
Socket Direct 消除了处理器间总线上的负载,让网络流量无需遍历进程间总线。
网卡的环形队列(Ring buffer)
环形队列的存储区域位于主机内存(Host Memory) 中,而非网卡设备本身,这一点一定要熟记于心。
网卡通过 DMA 技术直接读写主机内存中的环形队列,无需 CPU 参与数据传输。网卡自身可能仅有少量缓存(如预取缓冲区),但主要数据存储依赖主机内存。网卡硬件上的缓存(如接收/发送缓冲区)通常只有几 KB 到几十 KB,仅用于临时暂存数据包。网卡从网络收到数据包后,先暂存到硬件缓存,随后立即通过 DMA 写入主机内存的接收环形队列(Rx Ring)。
所以就是说网卡在收发包的过程中需要大量的 DMA 操作?否则网卡上自己的缓存应该很快就满了。
是的。