网卡队列与发包

参考文献

linux 网络子系统 DMA方式介绍
https://cloud.tencent.com/developer/article/1628161
网卡与DMA工作原理和流程
https://zhuanlan.zhihu.com/p/553904728
对收报、发包过程中网卡和网卡驱动工作流程有比较详细的介绍
https://www.cnblogs.com/jmilkfan-fanguiju/p/12789806.html#_50
多队列网卡与网卡发包源码解读
https://blog.csdn.net/tenfyguo/article/details/8777436
这篇比较全面详细: 对发包过程非常详细的描述,对涉及到的函数有详细分析,很多图很直观
https://zhuanlan.zhihu.com/p/373060740
发送数据包流程dev_queue_xmit分析
https://blog.csdn.net/wdscq1234/article/details/51926808
对网卡内存也就是RX TX FIFO有一个介绍,对收包流程也有介绍:
https://www.jianshu.com/p/e6162bc984c8

意义

现在问题大概都解决了,网卡有内存,但只是简单的RX TX FIFO,不起调度作用。多队列网卡应该接收时会有多个CPU可以并行处理,处理完成的顺序和实际接收的顺序可能不一致。
我猜测:发送包的时候,应该也会有多个队列,每个队列绑定到一个CPU上,哪个CPU有空,就抢把锁去发送队列。这个队列存在主存还是网卡自带的什么存并不重要,关键的是这个队列和tc Qdisc是什么关系,一个包是如何进某个网卡队列的,是如何出队列被真正发送出去的,然后这些多个队列能并行发送吗?不过不能,那每次如何决定哪个队列出包发送呢?
这些问题对于全部包的一个发送情况有着决定性的影响,但是如果我只考虑单队列的网卡,或者说假如网卡的每一个队列下都有一个qdisc的话,因为网卡驱动是根据包的四元组进行HASH来决定到哪个队列的,那同一个流总还是到同一个队列的,那我只考虑这一个队列上的所有流的一个调度情况即可,也就是说尽可能在这些流的一个时延约束空间内找最大的吞吐率(或者某价值函数)。那这和单队列网卡的情况是一样的。
因为对网卡多队列还需要花费一些时间去了解、实验。所以现在先只考虑单网卡队列情况。

网卡队列我看这个文章说的应该就是多个在内存中的RingBuffer,由网卡驱动程序在内存中创建:
现在的服务器上的网卡一般都是支持多队列的。每一个队列上都是由一个 RingBuffer 表示的,开启了多队列以后的的网卡就会对应有多个 RingBuffer。
网卡队列与发包_第1张图片
网卡在启动时最重要的任务之一就是分配和初始化 RingBuffer
我想多RingBuffer的好处应该就是可以发挥多核CPU的优势,能并行处理多个RingBuffer。
尽管网卡发包收报应该还是对packet一个接一个地进行。

问题

网卡队列是个啥啊?packet是存在内存里,然后网卡以DMA的方式读取发出。还是说packet被copy到网卡的内存里,然后网卡读自己内存发出啊?网卡有内存吗?
我还是没明白网卡多队列是怎么工作的。
qdisc是搭载在队列上的吗?一个网卡队列上搭载一个qdisc?
网卡队列是在内存上用网卡驱动创建实现的吗?还是说网卡硬件上本身就存在多个队列存储空间?但这好像不重要,比较关键的是一个包是如何进某个网卡队列的,是如何出队列被真正发送出去的,然后这些多个队列能并行发送吗?不过不能,那每次如何决定哪个队列出包发送呢?

网卡DMA工作

网卡队列与发包_第2张图片
DMA 环形缓冲区建立在与处理器共享的内存中。每一个输入数据包被放置在环形缓冲区中下一个可用缓冲区,然后发出中断。接着驱动程序将网络数据包传给内核的其它部分处理,并在环形缓冲区中放置一个新的 DMA 缓冲区。

驱动程序在初始化时分配DMA缓冲区,并使用驱动程序直到停止运行。
网卡队列与发包_第3张图片
准备工作:

系统启动时网卡(NIC)进行初始化,在内存中腾出空间给 Ring BufferRing Buffer 队列每个中的每个元素 Packet Descriptor指向一个sk_buff ,状态均为ready

上图中虚线步骤的解释:

  • 1.DMA 接口将网卡(NIC)接收的数据包(packet)逐个写入 sk_buff ,被写入数据的 sk_buff 变为 used 状态。一个数据包可能占用多个 sk_buff , sk_buff读写顺序遵循先入先出(FIFO)原则。
  • 2.DMA 写完数据之后,网卡(NIC)向网卡中断控制器(NIC Interrupt Handler)触发硬件中断请求。
  • 3.NIC driver 注册 poll 函数。
  • 4.poll 函数对数据进行检查,例如将几个 sk_buff 合并,因为可能同一个数据可能被分散放在多个 sk_buff 中。
  • 5.poll 函数将 sk_buff 交付上层网络栈处理。

后续处理:

poll 函数清理 sk_buff,清理 Ring Buffer 上的 Descriptor 将其指向新分配的 sk_buff 并将状态设置为 ready。

网卡结构 没有内存

网卡的组成:

   (1)主芯片: 网卡的主控制芯片是网卡的核心元件,一块网卡性能的好坏和功能的强弱多寡,主要就是看这块芯片的质量。如下图所示:

(2)BOOTROM槽:BOOTROM 插座也就是常说的无盘启动ROM 接口,其是用来通过远程启动服务构造无盘工作站的。如下图所示:

(3)数据泵:作用一是传输数据;二是隔离网线连接的不同网络设备间的不同电平,还能对设备起到一定的防雷保护作用。如下图所示:

(4)晶振即石英振荡器,提供基准频率,如下图所示:

(5)LED指示灯:用来标识网卡的不同工作状态,例如,Link/Act表示连接活动状态,Full表示是否全双工,而Power是电源指示。
(6)网线接口:有BNC接口和RJ-45接口,目前主要使用8芯线的RJ-45接口。

(7)总线接口:用于网卡与电脑相连接,内置式网卡需要通过俗称“金手指”的总线接口插在计算机主板的扩展槽中。主要有ISA,PCI,PCMCIA和USB等常见的是PCI总线接口的网卡。

  • 网卡充当计算机和网络缆线之间的物理接口或连线,负责将计算机中的数字信号转换成电或光信号。
  • 网卡要承担串行数据或并行数据间的转换,数据在计算机总线中并行传输,而在网络的物理缆线中以串行的比特流传输。

网卡结构工作过程

https://zhuanlan.zhihu.com/p/553904728

  • 网卡驱动申请 Rx descriptor ring,本质是一致性 DMA 内存,保存了若干的 descriptor。将 Rx descriptor ring 的总线地址写入网卡寄存器 RDBA。
  • 网卡驱动为每个 descriptor 分配 skb_buff 数据缓存区,本质上是在内存中分配的一片缓冲区用来接收数据帧。将数据缓存区的总线地址保存到 descriptor。
  • 网卡接收到高低电信号。
  • PHY 芯片首先进行数模转换,即将电信号转换为比特流。
  • MAC 芯片再将比特流转换为数据帧(Frame)。
  • 网卡驱动将数据帧写入 Rx FIFO。
  • 网卡驱动找到 Rx descriptor ring 中下一个将要使用的 descriptor。
  • 网卡驱动使用 DMA 通过 PCI 总线将 Rx FIFO 中的数据包复制到 descriptor 保存的总线地址指向的数据缓存区中。其实就是复制到 skb_buff 中。
  • 因为是 DMA 写入,所以内核并没有监控数据帧的写入情况。所以在复制完后,需要由网卡驱动启动硬中断通知 CPU 数据缓存区中已经有新的数据帧了。每一个硬件中断会对应一个中断号,CPU 执行硬下述中断函数。实际上,硬中断的中断处理程序,最终是通过调用网卡驱动程序来完成的。硬中断触发的驱动程序首先会暂时禁用网卡硬中断,意思是告诉网卡再来新的数据就先不要触发硬中断了,只需要把数据帧通过 DMA 拷入主存即可。
    网卡队列与发包_第4张图片
    当网卡接收光/电信号,将其转换为数据帧内容,如果帧符合以太网地址等过滤条件,则保存到RX FIFO缓存对列中。
    网卡解析FIFO中数据帧的2/3/4层信息,进行流过滤、流定向、RSS队列分流,计算出帧对应的分流队列号。
    网卡从 mem 空间的寄存器中获取环形缓冲区的信息,DMA 控制器把接收的数据包直接DMA到内存中,该过程都是由网卡硬件完成的。
    网卡接收消息处理流程如下:
    网卡队列与发包_第5张图片
    对收报、发包过程中网卡和网卡驱动工作流程有比较详细的介绍:
    https://www.cnblogs.com/jmilkfan-fanguiju/p/12789806.html#_50

网卡工作在物理层和数据链路层,主要由 PHY/MAC 芯片、Tx/Rx FIFO、DMA 等组成,其中网线通过变压器接 PHY 芯片、PHY 芯片通过 MII 接 MAC 芯片、MAC 芯片接 PCI 总线。
PHY 芯片主要负责:CSMA/CD、模数转换、编解码、串并转换。

MAC 芯片主要负责:
比特流和数据帧的转换(7 字节的前导码 Preamble 和 1 字节的帧首定界符 SFD);
CRC 校验;
Packet Filtering(L2 Filtering、VLAN Filtering、Manageability/Host Filtering)。

Tx/Rx FIFO:Tx 表示发送(Transport),Rx 是接收(Receive)。

DMA(Direct Memory Access):直接存储器存取 I/O 模块。

对网卡内存也就是RX TX FIFO有一个介绍,对收包流程也有介绍:
https://www.jianshu.com/p/e6162bc984c8

你可能感兴趣的:(网卡)