virtio: find_vqs/del_vqs virtio operations

This replaces find_vq/del_vq with find_vqs/del_vqs virtio operations,
and updates all drivers. This is needed for MSI support, because MSI
needs to know the total number of vectors upfront.

Signed-off-by: Michael S. Tsirkin <[email protected]>
Signed-off-by: Rusty Russell <[email protected]> (+ lguest/9p compile fixes)
This commit is contained in:
Michael S. Tsirkin 2009-06-12 22:16:36 -06:00 • committed by Rusty Russell
commit d2a7ddda9f
10 changed files with 183 additions and 89 deletions

View file

@ -204,6 +204,9 @@ static int balloon(void *_vballoon)
static int virtballoon_probe(struct virtio_device *vdev)
{
struct virtio_balloon *vb;
struct virtqueue *vqs[2];
vq_callback_t *callbacks[] = { balloon_ack, balloon_ack };
const char *names[] = { "inflate", "deflate" };
int err;
vdev->priv = vb = kmalloc(sizeof(*vb), GFP_KERNEL);
@ -218,22 +221,17 @@ static int virtballoon_probe(struct virtio_device *vdev)
vb->vdev = vdev;
/* We expect two virtqueues. */
vb->inflate_vq = vdev->config->find_vq(vdev, 0, balloon_ack, "inflate");
if (IS_ERR(vb->inflate_vq)) {
err = PTR_ERR(vb->inflate_vq);
err = vdev->config->find_vqs(vdev, 2, vqs, callbacks, names);
if (err)
goto out_free_vb;
}
vb->deflate_vq = vdev->config->find_vq(vdev, 1, balloon_ack, "deflate");
if (IS_ERR(vb->deflate_vq)) {
err = PTR_ERR(vb->deflate_vq);
goto out_del_inflate_vq;
}
vb->inflate_vq = vqs[0];
vb->deflate_vq = vqs[1];
vb->thread = kthread_run(balloon, vb, "vballoon");
if (IS_ERR(vb->thread)) {
err = PTR_ERR(vb->thread);
goto out_del_deflate_vq;
goto out_del_vqs;
}
vb->tell_host_first
@ -241,10 +239,8 @@ static int virtballoon_probe(struct virtio_device *vdev)
return 0;
out_del_deflate_vq:
vdev->config->del_vq(vb->deflate_vq);
out_del_inflate_vq:
vdev->config->del_vq(vb->inflate_vq);
out_del_vqs:
vdev->config->del_vqs(vdev);
out_free_vb:
kfree(vb);
out:
@ -264,8 +260,7 @@ static void virtballoon_remove(struct virtio_device *vdev)
/* Now we reset the device so we can clean up the queues. */
vdev->config->reset(vdev);
vdev->config->del_vq(vb->deflate_vq);
vdev->config->del_vq(vb->inflate_vq);
vdev->config->del_vqs(vdev);
kfree(vb);
}

View file

@ -276,11 +276,7 @@ static void vp_del_vq(struct virtqueue *vq)
{
struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
struct virtio_pci_vq_info *info = vq->priv;
unsigned long flags, size;
spin_lock_irqsave(&vp_dev->lock, flags);
list_del(&info->node);
spin_unlock_irqrestore(&vp_dev->lock, flags);
unsigned long size;
vring_del_virtqueue(vq);
@ -293,14 +289,41 @@ static void vp_del_vq(struct virtqueue *vq)
kfree(info);
}
static void vp_del_vqs(struct virtio_device *vdev)
{
struct virtqueue *vq, *n;
list_for_each_entry_safe(vq, n, &vdev->vqs, list)
vp_del_vq(vq);
}
static int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs,
struct virtqueue *vqs[],
vq_callback_t *callbacks[],
const char *names[])
{
int i;
for (i = 0; i < nvqs; ++i) {
vqs[i] = vp_find_vq(vdev, i, callbacks[i], names[i]);
if (IS_ERR(vqs[i]))
goto error;
}
return 0;
error:
vp_del_vqs(vdev);
return PTR_ERR(vqs[i]);
}
static struct virtio_config_ops virtio_pci_config_ops = {
.get = vp_get,
.set = vp_set,
.get_status = vp_get_status,
.set_status = vp_set_status,
.reset = vp_reset,
.find_vq = vp_find_vq,
.del_vq = vp_del_vq,
.find_vqs = vp_find_vqs,
.del_vqs = vp_del_vqs,
.get_features = vp_get_features,
.finalize_features = vp_finalize_features,
};