Commit 6730b51f authored by Jean-Philippe Brucker's avatar Jean-Philippe Brucker Committed by Will Deacon
Browse files

virtio/blk: Reset virtqueue



Move pthread creation to init_vq, and kill the thread in exit_vq.
Initialize the virtqueue states at runtime.

All in-flight I/O is canceled with the virtqueue pthreads, except for AIO
threads, but after reading the code I'm not sure if AIO has ever worked
anyway.
Signed-off-by: default avatarJean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: default avatarJulien Thierry <julien.thierry@arm.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent 49bada43
...@@ -178,9 +178,29 @@ static void notify_status(struct kvm *kvm, void *dev, u32 status) ...@@ -178,9 +178,29 @@ static void notify_status(struct kvm *kvm, void *dev, u32 status)
{ {
} }
static void *virtio_blk_thread(void *dev)
{
struct blk_dev *bdev = dev;
u64 data;
int r;
kvm__set_thread_name("virtio-blk-io");
while (1) {
r = read(bdev->io_efd, &data, sizeof(u64));
if (r < 0)
continue;
virtio_blk_do_io(bdev->kvm, &bdev->vqs[0], bdev);
}
pthread_exit(NULL);
return NULL;
}
static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align, static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
u32 pfn) u32 pfn)
{ {
unsigned int i;
struct blk_dev *bdev = dev; struct blk_dev *bdev = dev;
struct virt_queue *queue; struct virt_queue *queue;
void *p; void *p;
...@@ -194,26 +214,37 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align, ...@@ -194,26 +214,37 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
vring_init(&queue->vring, VIRTIO_BLK_QUEUE_SIZE, p, align); vring_init(&queue->vring, VIRTIO_BLK_QUEUE_SIZE, p, align);
virtio_init_device_vq(&bdev->vdev, queue); virtio_init_device_vq(&bdev->vdev, queue);
if (vq != 0)
return 0;
for (i = 0; i < ARRAY_SIZE(bdev->reqs); i++) {
bdev->reqs[i] = (struct blk_dev_req) {
.bdev = bdev,
.kvm = kvm,
};
}
mutex_init(&bdev->mutex);
bdev->io_efd = eventfd(0, 0);
if (bdev->io_efd < 0)
return -errno;
if (pthread_create(&bdev->io_thread, NULL, virtio_blk_thread, bdev))
return -errno;
return 0; return 0;
} }
static void *virtio_blk_thread(void *dev) static void exit_vq(struct kvm *kvm, void *dev, u32 vq)
{ {
struct blk_dev *bdev = dev; struct blk_dev *bdev = dev;
u64 data;
int r;
kvm__set_thread_name("virtio-blk-io"); if (vq != 0)
return;
while (1) { close(bdev->io_efd);
r = read(bdev->io_efd, &data, sizeof(u64)); pthread_cancel(bdev->io_thread);
if (r < 0) pthread_join(bdev->io_thread, NULL);
continue;
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) static int notify_vq(struct kvm *kvm, void *dev, u32 vq)
...@@ -259,6 +290,7 @@ static struct virtio_ops blk_dev_virtio_ops = { ...@@ -259,6 +290,7 @@ static struct virtio_ops blk_dev_virtio_ops = {
.set_guest_features = set_guest_features, .set_guest_features = set_guest_features,
.get_vq_count = get_vq_count, .get_vq_count = get_vq_count,
.init_vq = init_vq, .init_vq = init_vq,
.exit_vq = exit_vq,
.notify_status = notify_status, .notify_status = notify_status,
.notify_vq = notify_vq, .notify_vq = notify_vq,
.get_vq = get_vq, .get_vq = get_vq,
...@@ -269,7 +301,6 @@ static struct virtio_ops blk_dev_virtio_ops = { ...@@ -269,7 +301,6 @@ static struct virtio_ops blk_dev_virtio_ops = {
static int virtio_blk__init_one(struct kvm *kvm, struct disk_image *disk) static int virtio_blk__init_one(struct kvm *kvm, struct disk_image *disk)
{ {
struct blk_dev *bdev; struct blk_dev *bdev;
unsigned int i;
if (!disk) if (!disk)
return -EINVAL; return -EINVAL;
...@@ -279,13 +310,11 @@ static int virtio_blk__init_one(struct kvm *kvm, struct disk_image *disk) ...@@ -279,13 +310,11 @@ static int virtio_blk__init_one(struct kvm *kvm, struct disk_image *disk)
return -ENOMEM; return -ENOMEM;
*bdev = (struct blk_dev) { *bdev = (struct blk_dev) {
.mutex = MUTEX_INITIALIZER,
.disk = disk, .disk = disk,
.blk_config = (struct virtio_blk_config) { .blk_config = (struct virtio_blk_config) {
.capacity = disk->size / SECTOR_SIZE, .capacity = disk->size / SECTOR_SIZE,
.seg_max = DISK_SEG_MAX, .seg_max = DISK_SEG_MAX,
}, },
.io_efd = eventfd(0, 0),
.kvm = kvm, .kvm = kvm,
}; };
...@@ -295,14 +324,8 @@ static int virtio_blk__init_one(struct kvm *kvm, struct disk_image *disk) ...@@ -295,14 +324,8 @@ static int virtio_blk__init_one(struct kvm *kvm, struct disk_image *disk)
list_add_tail(&bdev->list, &bdevs); list_add_tail(&bdev->list, &bdevs);
for (i = 0; i < ARRAY_SIZE(bdev->reqs); i++) {
bdev->reqs[i].bdev = bdev;
bdev->reqs[i].kvm = kvm;
}
disk_image__set_callback(bdev->disk, virtio_blk_complete); disk_image__set_callback(bdev->disk, virtio_blk_complete);
pthread_create(&bdev->io_thread, NULL, virtio_blk_thread, bdev);
if (compat_id == -1) if (compat_id == -1)
compat_id = virtio_compat_add_message("virtio-blk", "CONFIG_VIRTIO_BLK"); compat_id = virtio_compat_add_message("virtio-blk", "CONFIG_VIRTIO_BLK");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment