All of lore.kernel.org
 help / color / mirror / Atom feed
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.


  reply	other threads:[~2009-05-17 21:31 UTC|newest]

Thread overview: 14+ 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 ` Michael S. Tsirkin
2009-05-14 10:55 ` [PATCHv6 2/4] virtio: find_vqs/del_vqs virtio operations Michael S. Tsirkin
2009-05-14 10:55 ` Michael S. Tsirkin
2009-05-15  4:50   ` Rusty Russell
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 ` Michael S. Tsirkin
2009-05-14 10:55 ` [PATCHv6 4/4] virtio_pci: optional MSI-X support Michael S. Tsirkin
2009-05-14 10:55 ` Michael S. Tsirkin
2009-05-17 21:30   ` Avi Kivity [this message]
2009-05-18 11:01     ` Michael S. Tsirkin
2009-05-18 11:01     ` Michael S. Tsirkin
2009-05-17 21:30   ` Avi Kivity

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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.