哪些网络系统调用导致 VM 退出到 Intel VMX 中的管理程序?
Which networking syscalls cause VM Exits to Hypervisor in Intel VMX?
我无法理解在 Intel VMX 下哪些(如果有的话)系统调用导致 VM 退出到 VMX root 模式。我对与网络相关的系统调用(即套接字、接受、发送、接收)特别感兴趣,因为它们需要一个“虚拟”设备。我知道必须调用管理程序才能实际打开套接字,但这是否可以并行完成(假设在多核处理器上)?
任何澄清将不胜感激。
根据Intel 64 and IA-32 Architectures Software Developer's Manual(第3卷第22章)none的int 0x80
、sysenter
和syscall
,下面主要使用的三个指令Linux执行系统调用,会导致VM退出本身。所以通常没有明确的方法来判断哪些系统调用导致 VM 退出,哪些不会。
VM退出可以在很多场景下发生,例如主机可以配置一个异常位图来决定哪些异常导致VM退出,包括页面错误,所以理论上几乎任何一段代码做内存操作(内核或用户)可能导致虚拟机退出。
排除这种极端情况并专门讨论网络,如Peter Cordes suggests in the ,您应该关注的是[可能]发送和接收数据的操作,因为这些操作最终将需要与硬件进行通信(网卡):
像 socket
、socketpair
、{get,set}sockopt
、bind
、shutdown
等系统调用不应导致 VM 退出因为它们不需要与底层硬件通信,它们只是操纵逻辑内核数据结构。
read
、recv
和 write
会导致 VM 退出,除非内核已经有数据可供读取或正在等待积累足够的数据来写入 (例如,在发送之前按照 Nagle's algorithm)。内核是否实际停止从硬件读取或直接发送到硬件取决于套接字选项、系统调用标志和底层的当前状态 socket/connection.
sendto
、recvfrom
、sendmsg
、recvmsg
(等等)、select
、poll
、 epoll
网络套接字上的(等)都可能导致 VM 退出,同样取决于具体情况,与上一点的推理几乎相同。
connect
不需要为数据报套接字 (SOCK_DGRAM
) 退出 VM,因为它只是设置一个默认地址,但绝对可以用于基于连接的协议(例如 SOCK_STREAM
) 因为内核需要发送和接收数据包来建立连接。
accept
还需要 send/receive 数据,因此可能导致 VM 退出。
I understand the hypervisor will have to be invoked to actually open a socket, but could this be done in parallel (assuming on a multi-core processor)?
“并行”不是我要使用的术语,但是网络 I/O 操作可以由 OS 异步处理,例如数据包不一定在通过系统调用请求时准确接收或发送,而是在需要时接收或发送。例如,在来宾用户空间程序发出相关系统调用之前,可能已经执行了一个或多个接收数据所需的 VM 退出。
Is it always necessary for a VM Exit to occur (if necessary) to send a packet on the NIC if on a multi-core system and there are available cores that could allow the VMM and a guest to run concurrently? I guess what I'm asking if increased parallelism could prevent VM Exits simply by allowing the hypervisor to run in parallel with a guest.
当发生 VM 退出时,来宾 CPU 停止并且无法恢复执行,直到 VMM 为其发出 VMRESUME(请参阅 Intel SDE 第 3 卷第 23.1 章“虚拟机控制结构概述”)。不可能“阻止”VM 退出的发生,但是在多处理器系统上,理论上 VMM 可以在多个内核上 运行 并将 VM 退出的处理委托给另一个 VMM 线程,同时恢复已停止的 VM早。
因此,虽然增加并行度不能阻止 VM 退出,但理论上可以减少它们的开销。但是请注意,这只会发生在恢复来宾时可以“延迟”处理的 VM 退出。例如,如果来宾页面错误和 VM 退出,则 VMM 无法真正“委托”处理 VM 退出并更早地恢复来宾,因为来宾需要在恢复执行之前解决页面错误。
总而言之,每当来宾内核需要与硬件通信时,这可能是 VM 退出的原因。访问模拟硬件以进行 I/O 操作需要管理程序介入,因此导致 VM 退出。然而,有可能的优化需要考虑:
硬件直通可用于支持IOMMU to make devices directly available to the guest OS and achieve very low overhead in HW communication with no need for VM exits. See Intel VT-d, Intel VT-c, SR-IOV, and also "PCI passthrough via OVMF" on ArchWiki的系统。
Virtio is a standard for paravirtualization of network (NICs) and block devices (disks) which aims at reducing I/O overhead (i.e. overall number of needed VM exits), but needs support from both guest and host. The guest is "aware" of being a guest in this case. See also: Virtio for Linux/KVM.
延伸阅读:
我无法理解在 Intel VMX 下哪些(如果有的话)系统调用导致 VM 退出到 VMX root 模式。我对与网络相关的系统调用(即套接字、接受、发送、接收)特别感兴趣,因为它们需要一个“虚拟”设备。我知道必须调用管理程序才能实际打开套接字,但这是否可以并行完成(假设在多核处理器上)?
任何澄清将不胜感激。
根据Intel 64 and IA-32 Architectures Software Developer's Manual(第3卷第22章)none的int 0x80
、sysenter
和syscall
,下面主要使用的三个指令Linux执行系统调用,会导致VM退出本身。所以通常没有明确的方法来判断哪些系统调用导致 VM 退出,哪些不会。
VM退出可以在很多场景下发生,例如主机可以配置一个异常位图来决定哪些异常导致VM退出,包括页面错误,所以理论上几乎任何一段代码做内存操作(内核或用户)可能导致虚拟机退出。
排除这种极端情况并专门讨论网络,如Peter Cordes suggests in the
像
socket
、socketpair
、{get,set}sockopt
、bind
、shutdown
等系统调用不应导致 VM 退出因为它们不需要与底层硬件通信,它们只是操纵逻辑内核数据结构。read
、recv
和write
会导致 VM 退出,除非内核已经有数据可供读取或正在等待积累足够的数据来写入 (例如,在发送之前按照 Nagle's algorithm)。内核是否实际停止从硬件读取或直接发送到硬件取决于套接字选项、系统调用标志和底层的当前状态 socket/connection.sendto
、recvfrom
、sendmsg
、recvmsg
(等等)、select
、poll
、epoll
网络套接字上的(等)都可能导致 VM 退出,同样取决于具体情况,与上一点的推理几乎相同。connect
不需要为数据报套接字 (SOCK_DGRAM
) 退出 VM,因为它只是设置一个默认地址,但绝对可以用于基于连接的协议(例如SOCK_STREAM
) 因为内核需要发送和接收数据包来建立连接。accept
还需要 send/receive 数据,因此可能导致 VM 退出。
I understand the hypervisor will have to be invoked to actually open a socket, but could this be done in parallel (assuming on a multi-core processor)?
“并行”不是我要使用的术语,但是网络 I/O 操作可以由 OS 异步处理,例如数据包不一定在通过系统调用请求时准确接收或发送,而是在需要时接收或发送。例如,在来宾用户空间程序发出相关系统调用之前,可能已经执行了一个或多个接收数据所需的 VM 退出。
Is it always necessary for a VM Exit to occur (if necessary) to send a packet on the NIC if on a multi-core system and there are available cores that could allow the VMM and a guest to run concurrently? I guess what I'm asking if increased parallelism could prevent VM Exits simply by allowing the hypervisor to run in parallel with a guest.
当发生 VM 退出时,来宾 CPU 停止并且无法恢复执行,直到 VMM 为其发出 VMRESUME(请参阅 Intel SDE 第 3 卷第 23.1 章“虚拟机控制结构概述”)。不可能“阻止”VM 退出的发生,但是在多处理器系统上,理论上 VMM 可以在多个内核上 运行 并将 VM 退出的处理委托给另一个 VMM 线程,同时恢复已停止的 VM早。
因此,虽然增加并行度不能阻止 VM 退出,但理论上可以减少它们的开销。但是请注意,这只会发生在恢复来宾时可以“延迟”处理的 VM 退出。例如,如果来宾页面错误和 VM 退出,则 VMM 无法真正“委托”处理 VM 退出并更早地恢复来宾,因为来宾需要在恢复执行之前解决页面错误。
总而言之,每当来宾内核需要与硬件通信时,这可能是 VM 退出的原因。访问模拟硬件以进行 I/O 操作需要管理程序介入,因此导致 VM 退出。然而,有可能的优化需要考虑:
硬件直通可用于支持IOMMU to make devices directly available to the guest OS and achieve very low overhead in HW communication with no need for VM exits. See Intel VT-d, Intel VT-c, SR-IOV, and also "PCI passthrough via OVMF" on ArchWiki的系统。
Virtio is a standard for paravirtualization of network (NICs) and block devices (disks) which aims at reducing I/O overhead (i.e. overall number of needed VM exits), but needs support from both guest and host. The guest is "aware" of being a guest in this case. See also: Virtio for Linux/KVM.
延伸阅读: