本人目前就职于烽火集成,从事云计算产品架构设计相关工作,长期专注于内核、虚拟化、分布式、云计算等方向。
技术交流请联系:xiaoding@fiberhome.com
在kvm下,virtio-blk的实现特性有virtio-blk,dataplane,vhost-blk。其中前2个已经进入了社区。而vhost-blk仅仅提了patch,并没有通过。
在开发中需要对比这3种特性下,block的io性能,所以找到了vhost-blk的patch,但是patch直接合入后不能成功使用。所以在解决该问题时候,
刚好又看了一次virtio-blk的初始化,以及io路径,这里为了避免忘记总结一下。这里分2次来讲,先将一下virtio-pci设备的正常通信流程。
再来说vhost-blk。
一 总览
1.简单来说,virtio的设备模拟都是基于virtio-pci设备来进行的。在guest中可以使用lspci看到设备名称。
这里可以看到使用的驱动都是virtio-pci。
2.在kvm下基于virtio-pci最终实现了virtiobus。这里让所有的设备最终挂在virtiobus上。这一细节要放到对virtio-pci前端驱动分析时候来讲。
3.通信流程。通过virtio-pci的中断事件来达到virtio前后端中断的通信。然后通过共享内存的读写,达到数据的传递。所以可以看到半虚驱动的实现基本点就是 1 中断。2共享内存。
二 virtio-block后端的初始化。
在qemu启动时,会对相应设备进行初始化。这里,可以看下hw/virtio/virtio-pci.c
我们需要初始化virtio-block, 在该文件中
这里就从virtio-pci初始化开始讲起。
virtio-pci,也是一个pci设备。所以初始化时候会调用到TYPE_PCI_DEVICE的初始化
在pci设备初始化时候,调用pci_device_class_init函数。
pci_device_class_init函数定义了初始化pci_qdev_init 。
这样,在virio-pci初始化时候,就会触发pci_qdev_init 函数,从而把pci设备加入到qdev tree中,同时也在I/O设备空间的内存中进行了注册。
pci_qdev_init主要添加了pci rom。以及调用do_pci_register_device函数对pci设备在内存进行了注册。
do_pci_register_device中初始化了pci相关config配置。
完成后,调用virtio_blk_pci_init初始化
调用virtio_pci_device_plugged。添加到virtio_bus上。
这里初始化完成。
在main函数中 所有设备初始化完成,会调用一次qemu_devices_reset对应pci设备。这个动作复位了pci设备的状态等信息。
在VM状态变化时候,会调用virtio_vmstate_change函数,来改变virtio的状态。
这里需要在VM处于runing状态,和virtio驱动都初始化以后,才开始改变状态。
现在就等待virtio-pci的驱动开始生效时候,和virtio-back来进行信息协商。