3

我在研究提高虚拟机(VM)的 TCP/UDP 性能时遇到了一些问题,如果有人可以为我提供一些帮助或建议来解决我的问题,我将不胜感激。

RPS & RFS 在物理机上运行良好,但有时它们可​​能无法在 VM 上运行。例如,RFS 旨在向运行相应接收进程的 CPU 发送 IRQ。但是,当多个 vCPU 共享一个物理 CPU (pCPU) 时,每个 VM 的虚拟 CPU (vCPU) 并不总是在线(这里我们可以简单地假设 vCPU 调度是循环的。)。因此,即使目标用户级进程正在其上运行,将 IRQ 发送到脱机 vCPU 也没有意义。从理论上讲,将 NIC IRQ 发送到正在运行的 VM 的 vCPU 将缩小 NIC IRQ 处理延迟并提高 TCP/UDP 性能。因此,我为每个 VM 分配了一个几乎总是在线的虚拟协处理器 (co-vCPU),并将 VM 的 NIC IRQ 固定到这个 co-vCPU。从VM中的Guest OS的角度来看,用户进程(例如 iperf) 在一个核心上运行,而 eth0 的 IRQ 上下文在另一个核心上运行。在我的实验中,它适用于 UDP,但不适用于 TCP。

我怀疑这是由于进程上下文和 IRQ 上下文之间的同步造成的。因为当我阅读linux中TCP层的一些源代码时,我发现IRQ上下文(例如net/ipv4/tcp_ipv4.c中的tcp_v4_rcv())和用户上下文(例如net/ipv4/tcp.c中的tcp_recvmsg())当他们访问内核中的缓冲区(receive_queue、backlog_queue、prequeue)时调用 lock_sock()/unlock_sock()。因此,有时 IRQ 无法访问被另一个运行用户级接收进程(iperf 服务器)的 vCPU 锁定的接收缓冲区,并且这个持有锁的 vCPU 已被 VM 监视器(VMM)或管理程序取消调度。

我不确定我是否清楚地描述了我的问题。无论如何,欢迎对此提出任何建议。

4

0 回答 0