qemu: virtio 设备 VIRTIO_PCI_QUEUE_NOTIFY 寄存器处理

目录

 

1. 问题描述

2.  问题跟踪及解释


1. 问题描述

VIRTIO_PCI_QUEUE_NOTIFY 是前端驱动进行 KICK 的接口,前端驱动写完报文,就要通过 VIRTIO_PCI_QUEUE_NOTIFY 发送 KICK 消息给qemu以便发送出来,我们以0.95为例,在QEMU中抓取对 VIRTIO_PCI_QUEUE_NOTIFY 的写操作,发现只有一次 VIRTIO_PCI_QUEUE_NOTIFY 的IO写操作,和预期是不符合的

但从前端驱动打印来看,确实每个报文都有kick操作

这些KICK操作都上哪里去了?

2.  问题跟踪及解释

想跟踪这个问题,有一个很好的入口,就是Control Queue,因为驱动加载后的第一步就是通过Control Queue发送使用的queue pair数量,那么我们就可以进行断点抓取,入口是 virtio_net_handle_ctrl

可以看到 virtio的事件处理接口是 virtio_queue_host_notifier_read

virtio_queue_host_notifier_read 是在 virtio_device_start_ioeventfd_impl 中注册的

我们继续跟踪  virtio_bus_set_host_notifier

可以看到是在驱动加载最后一个向 0x18(PCI_STATUS)中写入 0x7 (DRVIER_OK)时候完成 注册的,我们下面来看一下注册的过程

从 virtio_bus_start_ioeventfd 开始看

virtio_device_start_ioeventfd_impl

首先调用  virtio_bus_set_host_notifier ,把 notifier 注册给KVM

virtio_pci_ioeventfd_assign

我们可以看到把 notifier 注册给地址  legacy_mr 的 VIRTIO_PCI_QUEUE_NOTIFY(0x10), 这就是KICK地址端,长度2WORD,16字节,这就和前端驱动对起来了

之后,KVM接收到这段地址MR的退出后,直接就dispatch到notifier上了,就完成了kick通知

我们回到 virtio_device_start_ioeventfd_impl, 可以看到将 host_notifier 注册为  virtio_queue_host_notifier_read

这样,一旦guest发生了写KICK事件,KVM退出后,就会通过MR直接 dispatch 到 virtio_queue_host_notifier_read上进行处理

不再经过QEMU的IO处理,提高了效率。从而qemu的virtio_ioport_write也就接收不到对VIRTIO_PCI_QUEUE_NOTIFY写操作了

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值