31 内核与VirtIO:无需模拟的网络驱动程序
# 31 内核与VirtIO:无需模拟的网络驱动程序
当虚拟机发送或接收数据包时,Linux内核不会模拟物理网卡,而是直接使用虚拟机监视器(VMM)暴露的虚拟设备,并通过VirtIO驱动程序提供的半虚拟化接口工作。就网络而言,该驱动程序是virtio_net,它完全在内核空间中运行,无需设备模拟即可处理数据包流。
VirtIO定义了客户机与主机之间的共享内存传输机制,它用基于内存映射环和事件信号的精简协议取代了模拟硬件的开销。客户机看到的是标准网络接口,主机则直接移动数据,双方通过各自的内核进行协调。
在客户机内部,virtio_net注册一个虚拟以太网接口。应用程序进行诸如send()和recv()之类的套接字调用,而意识不到不涉及任何物理网卡。在底层,驱动程序分配数据包缓冲区并将它们组织成称为virtqueue的环形结构,每个结构包含一个描述符表、一个用于出站缓冲区的可用环和一个用于已完成缓冲区的已用环。
这项工作完全由客户机内核管理,它用描述符填充可用环,处理后从已用环回收描述符,并处理信号(在数据包准备好时通知主机,在数据到达时响应中断)。
主机内核也扮演着同样积极的角色。当虚拟机在QEMU等虚拟机监视器下启动时,VMM会配置VirtIO网络设备,并通过/dev/vhost-net向主机注册客户机的内存布局和virtqueue地址。从那里开始,vhost_net模块接管,它作为内核线程运行,完全绕过用户空间以实现高性能网络。
对于出站流量,vhost_net直接从客户机的TX virtqueue读取数据,并将数据包转发到TAP设备(主机上的虚拟第2层接口)。对于入站流量,TAP接口接收以太网帧,vhost_net将它们写入客户机的RX缓冲区,更新环状态,并引发eventfd。KVM的irqfd机制将其转换为传递给客户机的虚拟中断。
TAP设备连接到Linux网桥,该网桥充当虚拟交换机,在虚拟机和物理网卡之间路由流量。主机内核管理此流程,确保所有组件之间可靠高效地传递数据包。
这一切都不涉及硬件模拟,数据包永远不会通过模拟设备。相反,两个内核都在共享协议中执行各自的角色。VirtIO不模仿硬件,而是实现直接协作。
这不是模拟,而是真实的内核到内核的协调。