From: Avi Kivity <avi@redhat.com>
To: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>,
virtualization@lists.linux-foundation.org,
Anthony Liguori <anthony@codemonkey.ws>,
kvm@vger.kernel.org, Carsten Otte <cotte@de.ibm.com>
Subject: Re: [PATCHv6 4/4] virtio_pci: optional MSI-X support
Date: Mon, 18 May 2009 00:30:49 +0300 [thread overview]
Message-ID: <4A108209.4070805@redhat.com> (raw)
In-Reply-To: <20090514105541.GE3120@redhat.com>
Michael S. Tsirkin wrote:
> This implements optional MSI-X support in virtio_pci.
> MSI-X is used whenever the host supports at least 2 MSI-X
> vectors: 1 for configuration changes and 1 for virtqueues.
> Per-virtqueue vectors are allocated if enough vectors
> available.
>
> +static int vp_request_vectors(struct virtio_device *vdev, unsigned max_vqs)
> +{
> + struct virtio_pci_device *vp_dev = to_vp_device(vdev);
> + const char *name = dev_name(&vp_dev->vdev.dev);
> + unsigned i, v;
> + int err = -ENOMEM;
> + /* We want at most one vector per queue and one for config changes.
> + * Fallback to separate vectors for config and a shared for queues.
> + * Finally fall back to regular interrupts. */
> + int options[] = { max_vqs + 1, 2 };
> + int nvectors = max(options[0], options[1]);
> +
> + vp_dev->msix_entries = kmalloc(nvectors * sizeof *vp_dev->msix_entries,
> + GFP_KERNEL);
> + if (!vp_dev->msix_entries)
> + goto error_entries;
> + vp_dev->msix_names = kmalloc(nvectors * sizeof *vp_dev->msix_names,
> + GFP_KERNEL);
> + if (!vp_dev->msix_names)
> + goto error_names;
> +
> + for (i = 0; i < nvectors; ++i)
> + vp_dev->msix_entries[i].entry = i;
> +
> + err = vp_enable_msix(vp_dev->pci_dev, vp_dev->msix_entries,
> + options, ARRAY_SIZE(options));
> + if (err < 0) {
> + /* Can't allocate enough MSI-X vectors, use regular interrupt */
> + vp_dev->msix_vectors = 0;
> + err = request_irq(vp_dev->pci_dev->irq, vp_interrupt,
> + IRQF_SHARED, name, vp_dev);
> + if (err)
> + goto error_irq;
> + vp_dev->intx_enabled = 1;
> + } else {
> + vp_dev->msix_vectors = err;
> + vp_dev->msix_enabled = 1;
> +
> + /* Set the vector used for configuration */
> + v = vp_dev->msix_used_vectors;
> + snprintf(vp_dev->msix_names[v], sizeof *vp_dev->msix_names,
> + "%s-config", name);
> + err = request_irq(vp_dev->msix_entries[v].vector,
> + vp_config_changed, 0, vp_dev->msix_names[v],
> + vp_dev);
> + if (err)
> + goto error_irq;
> + ++vp_dev->msix_used_vectors;
> +
> + iowrite16(v, vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR);
> + /* Verify we had enough resources to assign the vector */
> + v = ioread16(vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR);
> + if (v == VIRTIO_MSI_NO_VECTOR) {
> + err = -EBUSY;
> + goto error_irq;
> + }
> + }
> +
> + if (vp_dev->msix_vectors && vp_dev->msix_vectors != max_vqs + 1) {
> + /* Shared vector for all VQs */
> + v = vp_dev->msix_used_vectors;
> + snprintf(vp_dev->msix_names[v], sizeof *vp_dev->msix_names,
> + "%s-virtqueues", name);
> + err = request_irq(vp_dev->msix_entries[v].vector,
> + vp_vring_interrupt, 0, vp_dev->msix_names[v],
> + vp_dev);
> + if (err)
> + goto error_irq;
> + ++vp_dev->msix_used_vectors;
> + }
> + return 0;
> +error_irq:
> + vp_free_vectors(vdev);
> + kfree(vp_dev->msix_names);
> +error_names:
> + kfree(vp_dev->msix_entries);
> +error_entries:
> + return err;
> +}
> +
> @@ -272,12 +412,43 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index,
> vq->priv = info;
> info->vq = vq;
>
> + /* allocate per-vq vector if available and necessary */
> + if (callback && vp_dev->msix_used_vectors < vp_dev->msix_vectors) {
> + vector = vp_dev->msix_used_vectors;
> + snprintf(vp_dev->msix_names[vector], sizeof *vp_dev->msix_names,
> + "%s-%s", dev_name(&vp_dev->vdev.dev), name);
> + err = request_irq(vp_dev->msix_entries[vector].vector,
> + vring_interrupt, 0,
> + vp_dev->msix_names[vector], vq);
> + if (err)
> + goto out_request_irq;
> + info->vector = vector;
> + ++vp_dev->msix_used_vectors;
> + } else
> + vector = VP_MSIX_VQ_VECTOR;
> +
> + if (callback && vp_dev->msix_enabled) {
> + iowrite16(vector, vp_dev->ioaddr + VIRTIO_MSI_QUEUE_VECTOR);
> + vector = ioread16(vp_dev->ioaddr + VIRTIO_MSI_QUEUE_VECTOR);
> + if (vector == VIRTIO_MSI_NO_VECTOR) {
> + err = -EBUSY;
> + goto out_assign;
> + }
> + }
> +
>
I'm not sure I understand how the vq -> msi mapping works. Do we
actually support an arbitrary mapping, or just either linear or n:1?
I don't mind the driver being limited, but the device interface should
be flexible. We'll want to deal with limited vector availability soon.
--
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
next prev parent reply other threads:[~2009-05-17 21:31 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1242297977.git.mst@redhat.com>
2009-05-14 10:55 ` [PATCHv6 1/4] virtio: add names to virtqueue struct, mapping from devices to queues Michael S. Tsirkin
2009-05-14 10:55 ` [PATCHv6 2/4] virtio: find_vqs/del_vqs virtio operations Michael S. Tsirkin
2009-05-15 4:50 ` Rusty Russell
2009-05-14 10:55 ` [PATCHv6 3/4] virtio_pci: split up vp_interrupt Michael S. Tsirkin
2009-05-14 10:55 ` [PATCHv6 4/4] virtio_pci: optional MSI-X support Michael S. Tsirkin
2009-05-17 21:30 ` Avi Kivity [this message]
2009-05-18 11:01 ` Michael S. Tsirkin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4A108209.4070805@redhat.com \
--to=avi@redhat.com \
--cc=anthony@codemonkey.ws \
--cc=borntraeger@de.ibm.com \
--cc=cotte@de.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=mst@redhat.com \
--cc=virtualization@lists.linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox