]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
virtio/s390: use vring_create_virtqueue
authorHalil Pasic <pasic@linux.ibm.com>
Fri, 26 Apr 2019 18:32:36 +0000 (20:32 +0200)
committerMichael S. Tsirkin <mst@redhat.com>
Sun, 12 May 2019 17:11:36 +0000 (13:11 -0400)
The commit 2a2d1382fe9d ("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: Halil Pasic <pasic@linux.ibm.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
drivers/s390/virtio/virtio_ccw.c

index 74c328321889b1fa3265385ebe9d0a201a031b90..2c66941ef3d0426ba7d11783302be3160726afab 100644 (file)
@@ -108,7 +108,6 @@ struct virtio_rev_info {
 struct virtio_ccw_vq_info {
        struct virtqueue *vq;
        int num;
-       void *queue;
        union {
                struct vq_info_block s;
                struct vq_info_block_legacy l;
@@ -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_vq_info *info = vq->priv;
        unsigned long flags;
-       unsigned long size;
        int ret;
        unsigned int index = vq->index;
 
@@ -461,8 +459,6 @@ static void virtio_ccw_del_vq(struct virtqueue *vq, struct ccw1 *ccw)
                         ret, index);
 
        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);
 }
@@ -494,8 +490,9 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
        int err;
        struct virtqueue *vq = NULL;
        struct virtio_ccw_vq_info *info;
-       unsigned long size = 0; /* silence the compiler */
+       u64 queue;
        unsigned long flags;
+       bool may_reduce;
 
        /* Allocate queue. */
        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,
                err = info->num;
                goto out_err;
        }
-       size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN));
-       info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
-       if (info->queue == NULL) {
-               dev_warn(&vcdev->cdev->dev, "no queue\n");
-               err = -ENOMEM;
-               goto out_err;
-       }
+       may_reduce = vcdev->revision > 0;
+       vq = vring_create_virtqueue(i, info->num, KVM_VIRTIO_CCW_RING_ALIGN,
+                                   vdev, true, may_reduce, ctx,
+                                   virtio_ccw_kvm_notify, callback, name);
 
-       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) {
                /* For now, we fail if we can't get the requested size. */
                dev_warn(&vcdev->cdev->dev, "no vq\n");
                err = -ENOMEM;
                goto out_err;
        }
+       /* it may have been reduced */
+       info->num = virtqueue_get_vring_size(vq);
 
        /* Register it with the host. */
+       queue = virtqueue_get_desc_addr(vq);
        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.index = i;
                info->info_block->l.num = info->num;
                ccw->count = sizeof(info->info_block->l);
        } 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.num = info->num;
                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,
        if (vq)
                vring_del_virtqueue(vq);
        if (info) {
-               if (info->queue)
-                       free_pages_exact(info->queue, size);
                kfree(info->info_block);
        }
        kfree(info);