关于网卡:网卡队列与发包
参考文献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。网卡在启动时最重要的工作之一就是调配和初始化 RingBuffer我想多RingBuffer的益处应该就是能够施展多核CPU的劣势,能并行处理多个RingBuffer。只管网卡发包收报应该还是对packet一个接一个地进行。 问题网卡队列是个啥啊?packet是存在内存里,而后网卡以DMA的形式读取收回。还是说packet被copy到网卡的内存里,而后网卡读本人内存收回啊?网卡有内存吗?我还是没明确网卡多队列是怎么工作的。qdisc是搭载在队列上的吗?一个网卡队列上搭载一个qdisc?网卡队列是在内存上用网卡驱动创立实现的吗?还是说网卡硬件上自身就存在多个队列存储空间?但这如同不重要,比拟要害的是一个包是如何进某个网卡队列的,是如何出队列被真正发送进来的,而后这些多个队列能并行发送吗?不过不能,那每次如何决定哪个队列出包发送呢? 网卡DMA工作DMA 环形缓冲区建设在与处理器共享的内存中。每一个输出数据包被搁置在环形缓冲区中下一个可用缓冲区,而后收回中断。接着驱动程序将网络数据包传给内核的其它局部解决,并在环形缓冲区中搁置一个新的 DMA 缓冲区。 驱动程序在初始化时调配DMA缓冲区,并应用驱动程序直到进行运行。筹备工作: 系统启动时网卡(NIC)进行初始化,在内存中腾出空间给 Ring Buffer 。Ring 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。 网卡构造 没有内存网卡的组成: ...