也无风雨也无晴。- 苏轼(宋)
接下来介绍VIRTIO相关内容。首先从VIRTIO-BLK开始分析,VIRTIO-BLK各部分交互图如下所示:
这里包含以下几个部分:
- Guest UserSpace:虚拟机用户空间,如虚拟机中运行fio等;
- Guest KernelSpace:虚拟机内核空间,它包含IO存储软件栈以及virtio-blk驱动;
- QEMU:作为Host UserSpace,负责为虚拟机模拟virtio设备;
- Host Kernel Space:KVM用于虚拟机中MMIO处理以及中断注入;IO栈和block驱动用于将IO下发给硬件或硬件处理完成后向上传递;
- Virtqueue:用于VIRTIO驱动与VIRTIO设备之间通信;
首先对图中IO请求下发过程(蓝色箭头)作介绍。
- 步骤1,虚拟机中用户态应用如fio进行IO下发;
- 步骤2,这里IO栈包含VFS,文件系统,通用block层,block调度层,它建立硬盘和内存数据的映射,存储和组织数据,作IO请求的下发,在block调度层作IO的合并和切分(详细见之前博文);
- 步骤3,virtio-blk驱动,在准备好数据并加入到virtioqueue后,虚拟机中访问MMIO(类似doorbell寄存器)陷入到KVM中;
- 步骤4,KVM将上述异常操作分发给QEMU;
- 步骤5,QEMU中模拟virtio device根据支持的io类型作IO下发;
- 步骤6,类似于步骤2,只不过当前是host上,建立硬盘和内存数据的映射,存储和组织数据,作IO请求的下发,在block调度层作IO的合并和切分;
- 步骤7,BLOCK驱动将IO请求真正下发给硬件;
在硬件完成数据处理后,IO请求完成过程(红色箭头)如下:
- 步骤1,硬件完成数据处理后以中断或其他方式(轮询)通知BLOCK层驱动;
- 步骤2,IO完成信息经过IO栈各层传递;
- 步骤3,IO完成信息返回到QEMU进程,经过处理并传递给virtio device;
- 步骤4,QEMU调用virtio_notify(),当MSIX中断时写对应内存访问到KVM;
- 步骤5,KVM对虚拟机注入中断,通知虚拟机数据处理完成;
- 步骤6和7作IO完成信息在各层逐步传递,最终返回给虚拟机中fio;