Commit 3279beac authored by Halil Pasic's avatar Halil Pasic Committed by Michael S. Tsirkin

virtio/s390: use vring_create_virtqueue

The commit 2a2d1382 ("virtio: Add improved queue allocation API")
establishes a new way of allocating virtqueues (as a part of the effort
that taught DMA to virtio rings).

In the future we will want virtio-ccw to use the DMA API as well.

Let us switch from the legacy method of allocating virtqueues to
vring_create_virtqueue() as the first step into that direction.
Signed-off-by: default avatarHalil Pasic <pasic@linux.ibm.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Reviewed-by: default avatarCornelia Huck <cohuck@redhat.com>
parent a5581206
...@@ -108,7 +108,6 @@ struct virtio_rev_info { ...@@ -108,7 +108,6 @@ struct virtio_rev_info {
struct virtio_ccw_vq_info { struct virtio_ccw_vq_info {
struct virtqueue *vq; struct virtqueue *vq;
int num; int num;
void *queue;
union { union {
struct vq_info_block s; struct vq_info_block s;
struct vq_info_block_legacy l; struct vq_info_block_legacy l;
...@@ -423,7 +422,6 @@ static void virtio_ccw_del_vq(struct virtqueue *vq, struct ccw1 *ccw) ...@@ -423,7 +422,6 @@ static void virtio_ccw_del_vq(struct virtqueue *vq, struct ccw1 *ccw)
struct virtio_ccw_device *vcdev = to_vc_device(vq->vdev); struct virtio_ccw_device *vcdev = to_vc_device(vq->vdev);
struct virtio_ccw_vq_info *info = vq->priv; struct virtio_ccw_vq_info *info = vq->priv;
unsigned long flags; unsigned long flags;
unsigned long size;
int ret; int ret;
unsigned int index = vq->index; unsigned int index = vq->index;
...@@ -461,8 +459,6 @@ static void virtio_ccw_del_vq(struct virtqueue *vq, struct ccw1 *ccw) ...@@ -461,8 +459,6 @@ static void virtio_ccw_del_vq(struct virtqueue *vq, struct ccw1 *ccw)
ret, index); ret, index);
vring_del_virtqueue(vq); vring_del_virtqueue(vq);
size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN));
free_pages_exact(info->queue, size);
kfree(info->info_block); kfree(info->info_block);
kfree(info); kfree(info);
} }
...@@ -494,8 +490,9 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, ...@@ -494,8 +490,9 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
int err; int err;
struct virtqueue *vq = NULL; struct virtqueue *vq = NULL;
struct virtio_ccw_vq_info *info; struct virtio_ccw_vq_info *info;
unsigned long size = 0; /* silence the compiler */ u64 queue;
unsigned long flags; unsigned long flags;
bool may_reduce;
/* Allocate queue. */ /* Allocate queue. */
info = kzalloc(sizeof(struct virtio_ccw_vq_info), GFP_KERNEL); info = kzalloc(sizeof(struct virtio_ccw_vq_info), GFP_KERNEL);
...@@ -516,33 +513,30 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, ...@@ -516,33 +513,30 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
err = info->num; err = info->num;
goto out_err; goto out_err;
} }
size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN)); may_reduce = vcdev->revision > 0;
info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); vq = vring_create_virtqueue(i, info->num, KVM_VIRTIO_CCW_RING_ALIGN,
if (info->queue == NULL) { vdev, true, may_reduce, ctx,
dev_warn(&vcdev->cdev->dev, "no queue\n"); virtio_ccw_kvm_notify, callback, name);
err = -ENOMEM;
goto out_err;
}
vq = vring_new_virtqueue(i, info->num, KVM_VIRTIO_CCW_RING_ALIGN, vdev,
true, ctx, info->queue, virtio_ccw_kvm_notify,
callback, name);
if (!vq) { if (!vq) {
/* For now, we fail if we can't get the requested size. */ /* For now, we fail if we can't get the requested size. */
dev_warn(&vcdev->cdev->dev, "no vq\n"); dev_warn(&vcdev->cdev->dev, "no vq\n");
err = -ENOMEM; err = -ENOMEM;
goto out_err; goto out_err;
} }
/* it may have been reduced */
info->num = virtqueue_get_vring_size(vq);
/* Register it with the host. */ /* Register it with the host. */
queue = virtqueue_get_desc_addr(vq);
if (vcdev->revision == 0) { if (vcdev->revision == 0) {
info->info_block->l.queue = (__u64)info->queue; info->info_block->l.queue = queue;
info->info_block->l.align = KVM_VIRTIO_CCW_RING_ALIGN; info->info_block->l.align = KVM_VIRTIO_CCW_RING_ALIGN;
info->info_block->l.index = i; info->info_block->l.index = i;
info->info_block->l.num = info->num; info->info_block->l.num = info->num;
ccw->count = sizeof(info->info_block->l); ccw->count = sizeof(info->info_block->l);
} else { } else {
info->info_block->s.desc = (__u64)info->queue; info->info_block->s.desc = queue;
info->info_block->s.index = i; info->info_block->s.index = i;
info->info_block->s.num = info->num; info->info_block->s.num = info->num;
info->info_block->s.avail = (__u64)virtqueue_get_avail(vq); info->info_block->s.avail = (__u64)virtqueue_get_avail(vq);
...@@ -572,8 +566,6 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, ...@@ -572,8 +566,6 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
if (vq) if (vq)
vring_del_virtqueue(vq); vring_del_virtqueue(vq);
if (info) { if (info) {
if (info->queue)
free_pages_exact(info->queue, size);
kfree(info->info_block); kfree(info->info_block);
} }
kfree(info); kfree(info);
......
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