Currently, all blk requests are processed in notify_vq() which is in the context of ioeventfd thread: ioeventfd__thread(). The processing in notify_vq() may take a long time to complete. We should make notify_vq() return as soon as possible, since all devices are sharing the single ioeventfd thread. Otherwise, it will block other device's notify_vq() being called and starve other devices. In virtio net's notify_vq(), we simply signal the tx/rx handle thread and return. This patch makes virtio blk's notify_vq() just notify the blk thread instead of doing the real hard read/write work. Tests show that the overhead of the notification operations introduced by this patch is small. Signed-off-by: Asias He <asias.hejun@xxxxxxxxx> --- tools/kvm/virtio/blk.c | 26 +++++++++++++++++++++++++- 1 files changed, 25 insertions(+), 1 deletions(-) diff --git a/tools/kvm/virtio/blk.c b/tools/kvm/virtio/blk.c index d1a0197..9d2f37e 100644 --- a/tools/kvm/virtio/blk.c +++ b/tools/kvm/virtio/blk.c @@ -51,6 +51,11 @@ struct blk_dev { struct virt_queue vqs[NUM_VIRT_QUEUES]; struct blk_dev_req reqs[VIRTIO_BLK_QUEUE_SIZE]; + + pthread_t io_thread; + int io_efd; + + struct kvm *kvm; }; static LIST_HEAD(bdevs); @@ -176,11 +181,26 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 pfn) return 0; } +static void *virtio_blk_thread(void *dev) +{ + struct blk_dev *bdev = dev; + u64 data; + + while (1) { + read(bdev->io_efd, &data, sizeof(u64)); + virtio_blk_do_io(bdev->kvm, &bdev->vqs[0], bdev); + } + + pthread_exit(NULL); + return NULL; +} + static int notify_vq(struct kvm *kvm, void *dev, u32 vq) { struct blk_dev *bdev = dev; + u64 data = 1; - virtio_blk_do_io(kvm, &bdev->vqs[vq], bdev); + write(bdev->io_efd, &data, sizeof(data)); return 0; } @@ -228,6 +248,8 @@ void virtio_blk__init(struct kvm *kvm, struct disk_image *disk) .capacity = disk->size / SECTOR_SIZE, .seg_max = DISK_SEG_MAX, }, + .io_efd = eventfd(0, 0), + .kvm = kvm, }; virtio_trans_init(&bdev->vtrans, VIRTIO_PCI); @@ -244,6 +266,8 @@ void virtio_blk__init(struct kvm *kvm, struct disk_image *disk) disk_image__set_callback(bdev->disk, virtio_blk_complete); + pthread_create(&bdev->io_thread, NULL, virtio_blk_thread, bdev); + if (compat_id != -1) compat_id = compat__add_message("virtio-blk device was not detected", "While you have requested a virtio-blk device, " -- 1.7.7.3 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html