深入理解virtio kick操作
本文将结合virtio spec与linux 源码,深入解析下virtio中的kick操作。
Overview
本文将详细的阐述virtio中的kick操作。根据kick操作的发展历史,按照如下顺序去介绍:
- legacy device kick
- modern device kick
- VIRTIO_F_NOTIFICATION_DATA feature的kick
legacy device
1 | /* the notify function used when creating a virt queue */ |
1 | // legacy device |

kick寄存器位于bar0中的VIRTIO_PCI_QUEUE_NOTIFY位置;不同vq使用同一个kick寄存器地址,往kick寄存器写入vq的index,告诉virtio后端要处理哪个vq。
modern device

在设备实现中,一般会将queue_notify_off设置为vq index;也就是说,vp_modern_get_queue_notify_off的返回值,一般会与输入变量index相同。
1 | /* |


- 当notify_off_multiplier不为0时,不同vq使用不同的kick寄存器地址,往kick寄存器写入vq的index,告诉virtio后端要处理哪个vq
- 当notify_off_multiplier为0时,不同vq使用相同的kick寄存器地址,往kick寄存器写入vq的index,告诉virtio后端要处理哪个vq
1 | // modern device |
VIRTIO_F_NOTIFICATION_DATA feature

值得注意的是,对于split vq,desc table的最大size为2^16;对于packed vq,desc table的最大size为2^15;


在kick寄存器中,不止存放了vq index:
- 对于split vq,kick寄存器中还存放了avail_idx
- 对于packed vq,kick寄存器中还存放了avail_idx(为了表述的方便,严格来说,packed vq已经没有了avail ring,也就不存在avail_idx了)与wrap counter

vq_notif_config_data在一般情况下,就是vq index。
1 | // modern device |
1 | static bool vp_notify_with_data(struct virtqueue *vq) |
参考资料:
- virtio 0.9.5 spec
- virtio 1.3 spec