数据包如何从networking接口队列调度到CPU,然后再转发到线程进行处理? 什么需要考虑到如何在队列,硬件中断vs softirqs,CPU /内存/应用程序/线程局部性,multithreading与多进程守护进程中散列数据包,以避免尽可能多的数据包重新计划/复制尽可能?
我有一个使用Linux 2.6.32(yes,old)的Debian amd64上运行16个本地线程的multithreadingnetworking守护进程(比如Unbound resolver),因此应用程序负载分布在16个CPU上。 网卡是bnx2(BCM5709S),支持8个MSI-X rx / tx队列。 每个队列的IRQ通过在/ proc / irq / n / smp_affinity中静态映射中断关联被分配给一个单独的CPU(irqbalance从来没有做好),队列哈希types(RSStypes)是默认的(src + dst ,TCP sport + dport),使用默认的散列键。
所有这些都有助于传播负载,但不是平均的:通常有一个应用程序线程执行两倍于其他线程的工作(=每秒请求数),一个CPU(可能是处理该特定线程的CPU)的softirq速率是其他线程的两倍的CPU。
CPU已经启用了超线程,但是我还没有做任何事情来传播负载到'真正'的核心(我真的应该)。
Linux提供了一个相当全面的networking缩放文档 ,但我错过了一些空白:
该文件说这关于RSSconfiguration:
如果设备支持足够的队列,则典型的RSSconfiguration将是每个CPU具有一个接收队列,否则对于每个存储器域至less一个接收队列,其中存储器域是共享特定存储器级别的一组CPU(L1,L2 ,NUMA节点等)。
问:如何确定我的服务器的CPU /caching/内存域configuration?
有关接收stream量转向(RFS)的信息似乎回答了一些关于将数据包传送到正确的CPU /线程的问题:
RFS的目标是通过将数据包的内核处理引导到消耗数据包的应用程序线程正在运行的CPU来增加datacache hitrate。
问:在DNSparsing的情况下,通常有一个查询包和一个应答包。 使用multithreading守护进程,只有一个线程运行bind()+ recvfrom(),因此在将工作调度到其他线程之前,必须处理所有新的传入数据包? 这个特殊用例会从分叉操作中受益吗(每个CPU有一个进程)呢?
问:接收stream量转向后,通常最适用于multithreadingTCP守护进程?
问:你将如何确定是否进行multithreading或多进程操作? 显然有共享内存和数据结构,资源争夺等,但我在考虑包stream和应用程序监听器。
问:如果没有接收stream量转向或简单的UDP服务,数据包是否能到达“错误的”CPU,因此会被重新安排到“正确的”CPU? 这会触发一个NET_RX softirq?
问:NIC队列和CPU之间是否有NET_RX softirq? CPU和侦听线程/进程之间是否还有一个? 如果接收线程将数据包安排到工作线程,是否还有另外一个可能性?
太糟糕了,Ben Hutchings的netconf 2011谈话中没有video或其他细节,他在这里涵盖了大部分的内容。 幻灯片比较简短。
我将尝试升级到更新的可用的perf版本的内核,然后检查CPU的function,或许可以find比其他CPU更高的CPU。
注意:我不想在这里解决一个特定的问题,而是试图理解这些东西在Linux内核中是如何工作的。 我也意识到中断合并的各种选项。