Linux virtualization list
 help / color / mirror / Atom feed
* RFT: virtio_net: limit xmit polling
From: Michael S. Tsirkin @ 2011-06-19 10:27 UTC (permalink / raw)
  To: Krishna Kumar2
  Cc: habanero, lguest, Shirley Ma, kvm, Carsten Otte, linux-s390,
	Heiko Carstens, linux-kernel, virtualization, steved,
	Christian Borntraeger, Tom Lendacky, netdev, Martin Schwidefsky,
	linux390

OK, different people seem to test different trees.  In the hope to get
everyone on the same page, I created several variants of this patch so
they can be compared. Whoever's interested, please check out the
following, and tell me how these compare:

kernel:

git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git

virtio-net-limit-xmit-polling/base - this is net-next baseline to test against
virtio-net-limit-xmit-polling/v0 - fixes checks on out of capacity
virtio-net-limit-xmit-polling/v1 - previous revision of the patch
		this does xmit,free,xmit,2*free,free
virtio-net-limit-xmit-polling/v2 - new revision of the patch
		this does free,xmit,2*free,free

There's also this on top:
virtio-net-limit-xmit-polling/v3 -> don't delay avail index update
I don't think it's important to test this one, yet

Userspace to use: event index work is not yet merged upstream
so the revision to use is still this:
git://git.kernel.org/pub/scm/linux/kernel/git/mst/qemu-kvm.git
virtio-net-event-idx-v3

-- 
MST

^ permalink raw reply

* Re: [RFC] virtio: Support releasing lock during kick
From: Christoph Hellwig @ 2011-06-19 13:55 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: axboe, Stefan Hajnoczi, kvm, linux-kernel, virtualization, hch
In-Reply-To: <20110619074841.GA8613@redhat.com>

On Sun, Jun 19, 2011 at 10:48:41AM +0300, Michael S. Tsirkin wrote:
> diff --git a/block/blk-core.c b/block/blk-core.c
> index 4ce953f..a8672ec 100644
> --- a/block/blk-core.c
> +++ b/block/blk-core.c
> @@ -433,6 +433,8 @@ void blk_run_queue(struct request_queue *q)
>  	spin_lock_irqsave(q->queue_lock, flags);
>  	__blk_run_queue(q);
>  	spin_unlock_irqrestore(q->queue_lock, flags);
> +	if (q->request_done)
> +		q->request_done(q);

We have quite a few cases where __blk_run_queue is called directly, and
one more (although not applicable to virtio-blk) that calls ->request_fn
directly.

I think Stefan's way is the way to go for now, releasing and reacquiring
the queue lock once in ->request_fn is much less than the common IDE and
SCSI setups do today.

Eventually ->queue_lock should be split from the driver-internal lock,
and we could do a more efficient calling convention than the one per
request blk_peek_request.  I've started looking into that, but it's
going to take a while.

^ permalink raw reply

* Make virtio vq size configurable by a guest.
From: Gleb Natapov @ 2011-06-20 13:16 UTC (permalink / raw)
  To: virtualization; +Cc: mst

Hi,

Currently in virtio host dictates the size and layout of vq that should
be used.  To talk to a device that has one vq with 128 elements guest
needs to allocate at least 2 pages. Usually this is not a problem, but
sometimes guest runs in a resource restricted environment and then it may
not have enough memory to initialize all virtio devices present in the
system. One such environment is a BIOS. Seabios currently has virtio block
support. Since the BIOS should be able to access the disk even after OS
is launched vq should be allocated from a special memory region that will
be marked as unavailable to an OS, but such memory is scarce. Because vq
is so huge only a couple of virtio disks can be initialized by the BIOS.

It would be nice if a guest will be able to tell to a host what vq size
should be used instead. BIOS issues only one request at a time anyway,
so it needs only one element in vq. It does not care about performance
to much either, so it can tell to a host to not align used index to a
page boundary. This way vq of one element shouldn't take more then a couple
hundreds of bytes.

--
			Gleb.

^ permalink raw reply

* Re: [RFC] virtio: Support releasing lock during kick
From: Stefan Hajnoczi @ 2011-06-20 15:27 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: Stefan Hajnoczi, kvm, virtualization
In-Reply-To: <20110619071452.GA7930@redhat.com>

On Sun, Jun 19, 2011 at 8:14 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
> On Wed, Jun 23, 2010 at 10:24:02PM +0100, Stefan Hajnoczi wrote:
>> The virtio block device holds a lock during I/O request processing.
>> Kicking the virtqueue while the lock is held results in long lock hold
>> times and increases contention for the lock.
>>
>> This patch modifies virtqueue_kick() to optionally release a lock while
>> notifying the host.  Virtio block is modified to pass in its lock.  This
>> allows other vcpus to queue I/O requests during the time spent servicing
>> the virtqueue notify in the host.
>>
>> The virtqueue_kick() function is modified to know about locking because
>> it changes the state of the virtqueue and should execute with the lock
>> held (it would not be correct for virtio block to release the lock
>> before calling virtqueue_kick()).
>>
>> Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>
> While the optimization makes sense, the API's pretty hairy IMHO.
> Why don't we split the kick functionality instead?
> E.g.
>        /* Report whether host notification is necessary. */
>        bool virtqueue_kick_prepare(struct virtqueue *vq)
>        /* Can be done in parallel with add_buf/get_buf */
>        void virtqueue_kick_notify(struct virtqueue *vq)

This is a nice idea, it makes the code cleaner.  I am testing patches
that implement this and after Khoa has measured the performance I will
send them out.

Stefan

^ permalink raw reply

* Re: Request for review on Hyper-V virtual network driver
From: K. Y. Srinivasan @ 2011-06-20 15:29 UTC (permalink / raw)
  To: gregkh, davem, shemminger, haiyangz, hjanssen, "netdev

Couple of weeks ago, we posted Hyper-V network front-end driver (netvsc)
for review. We got some initial feedback and we have already submitted
patches to address that feedback.

What are the next steps with regards to exiting
staging - we are committed to addressing all legitimate issues in a very 
timely fashion. Your guidance on this issue will be greatly
appreciated. 

Regards,

K. Y

^ permalink raw reply

* Re: Make virtio vq size configurable by a guest.
From: Rusty Russell @ 2011-06-21  2:02 UTC (permalink / raw)
  To: Gleb Natapov, virtualization; +Cc: mst
In-Reply-To: <20110620131624.GZ491@redhat.com>

On Mon, 20 Jun 2011 16:16:24 +0300, Gleb Natapov <gleb@redhat.com> wrote:
> Hi,
> 
> Currently in virtio host dictates the size and layout of vq that should
> be used.  To talk to a device that has one vq with 128 elements guest
> needs to allocate at least 2 pages. Usually this is not a problem, but
> sometimes guest runs in a resource restricted environment and then it may
> not have enough memory to initialize all virtio devices present in the
> system. One such environment is a BIOS. Seabios currently has virtio block
> support. Since the BIOS should be able to access the disk even after OS
> is launched vq should be allocated from a special memory region that will
> be marked as unavailable to an OS, but such memory is scarce. Because vq
> is so huge only a couple of virtio disks can be initialized by the BIOS.
> 
> It would be nice if a guest will be able to tell to a host what vq size
> should be used instead. BIOS issues only one request at a time anyway,
> so it needs only one element in vq. It does not care about performance
> to much either, so it can tell to a host to not align used index to a
> page boundary. This way vq of one element shouldn't take more then a couple
> hundreds of bytes.

Unfortunately, a virtqueue *always* takes at least 2 pages.  That's
because we split the host/guest part on page boundaries.  (2 pages per
disk is "huge"?  Really?)

So really, you want to negotiate the ring size and the 'align'
parameter.  A new feature could allow this, but there may be valid
reasons for a host to want to place an upper limit, too.

Thanks,
Rusty.

^ permalink raw reply

* [PATCH 1/2] vhost: init used ring after backend was set
From: Jason Wang @ 2011-06-21 10:04 UTC (permalink / raw)
  To: netdev, virtualization, linux-kernel, kvm, mst

This patch move the used ring initialization after backend was set. This make us
possible to disable the backend and tweak the used ring then restart. And it's
also useful for log setting as used ring have been checked then.

Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 drivers/vhost/net.c   |    4 ++++
 drivers/vhost/vhost.c |   11 +++--------
 drivers/vhost/vhost.h |    1 +
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index e224a92..957421b 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -637,6 +637,10 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
 		vhost_net_enable_vq(n, vq);
 	}
 
+	r = init_used(vq);
+	if (r)
+		goto err_vq;
+
 	mutex_unlock(&vq->mutex);
 
 	if (oldsock) {
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 2a10786..43a3fc6 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -578,15 +578,14 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
 	return 0;
 }
 
-static int init_used(struct vhost_virtqueue *vq,
-		     struct vring_used __user *used)
+int init_used(struct vhost_virtqueue *vq)
 {
-	int r = put_user(vq->used_flags, &used->flags);
+	int r = put_user(vq->used_flags, &vq->used->flags);
 
 	if (r)
 		return r;
 	vq->signalled_used_valid = false;
-	return get_user(vq->last_used_idx, &used->idx);
+	return get_user(vq->last_used_idx, &vq->used->idx);
 }
 
 static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
@@ -701,10 +700,6 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
 			}
 		}
 
-		r = init_used(vq, (struct vring_used __user *)(unsigned long)
-			      a.used_user_addr);
-		if (r)
-			break;
 		vq->log_used = !!(a.flags & (0x1 << VHOST_VRING_F_LOG));
 		vq->desc = (void __user *)(unsigned long)a.desc_user_addr;
 		vq->avail = (void __user *)(unsigned long)a.avail_user_addr;
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 64889d2..bd9f196 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -147,6 +147,7 @@ int vhost_get_vq_desc(struct vhost_dev *, struct vhost_virtqueue *,
 		      struct vhost_log *log, unsigned int *log_num);
 void vhost_discard_vq_desc(struct vhost_virtqueue *, int n);
 
+int init_used(struct vhost_virtqueue *);
 int vhost_add_used(struct vhost_virtqueue *, unsigned int head, int len);
 int vhost_add_used_n(struct vhost_virtqueue *, struct vring_used_elem *heads,
 		     unsigned count);

^ permalink raw reply related

* [PATCH 2/2] vhost: set log when updating used flags or avail event
From: Jason Wang @ 2011-06-21 10:04 UTC (permalink / raw)
  To: netdev, virtualization, linux-kernel, kvm, mst
In-Reply-To: <20110621100426.6777.68855.stgit@dhcp-91-7.nay.redhat.com.englab.nay.redhat.com>

We need set log when updating used flags and avail event. Otherwise guest may
see stale values after migration and then do not exit or exit unexpectedly.

Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 drivers/vhost/vhost.c |   61 +++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 48 insertions(+), 13 deletions(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 43a3fc6..c344d4f 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -578,16 +578,6 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
 	return 0;
 }
 
-int init_used(struct vhost_virtqueue *vq)
-{
-	int r = put_user(vq->used_flags, &vq->used->flags);
-
-	if (r)
-		return r;
-	vq->signalled_used_valid = false;
-	return get_user(vq->last_used_idx, &vq->used->idx);
-}
-
 static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
 {
 	struct file *eventfp, *filep = NULL,
@@ -954,6 +944,51 @@ int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log,
 	return 0;
 }
 
+static int vhost_update_used_flags(struct vhost_virtqueue *vq)
+{
+	if (put_user(vq->used_flags, &vq->used->flags) < 0)
+		return -EFAULT;
+	if (unlikely(vq->log_used)) {
+		/* Make sure the flag is seen before log. */
+		smp_wmb();
+		/* Log used flag write. */
+		log_write(vq->log_base,
+			  vq->log_addr + offsetof(struct vring_used, flags),
+			  sizeof vq->used->flags);
+		if (vq->log_ctx)
+			eventfd_signal(vq->log_ctx, 1);
+	}
+	return 0;
+}
+
+static int vhost_update_avail_event(struct vhost_virtqueue *vq, u16 avail_event)
+{
+	if (put_user(vq->avail_idx, vhost_avail_event(vq)))
+		return -EFAULT;
+	if (unlikely(vq->log_used)) {
+		/* Make sure the event is seen before log. */
+		smp_wmb();
+		/* Log avail event write */
+		log_write(vq->log_base,
+			  vq->log_addr + offsetof(struct vring_used,
+						  ring[vq->num]),
+			  sizeof avail_event);
+		if (vq->log_ctx)
+			eventfd_signal(vq->log_ctx, 1);
+	}
+	return 0;
+}
+
+int init_used(struct vhost_virtqueue *vq)
+{
+	int r = vhost_update_used_flags(vq);
+
+	if (r)
+		return r;
+	vq->signalled_used_valid = false;
+	return get_user(vq->last_used_idx, &vq->used->idx);
+}
+
 static int translate_desc(struct vhost_dev *dev, u64 addr, u32 len,
 			  struct iovec iov[], int iov_size)
 {
@@ -1425,14 +1460,14 @@ bool vhost_enable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
 		return false;
 	vq->used_flags &= ~VRING_USED_F_NO_NOTIFY;
 	if (!vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) {
-		r = put_user(vq->used_flags, &vq->used->flags);
+		r = vhost_update_used_flags(vq);
 		if (r) {
 			vq_err(vq, "Failed to enable notification at %p: %d\n",
 			       &vq->used->flags, r);
 			return false;
 		}
 	} else {
-		r = put_user(vq->avail_idx, vhost_avail_event(vq));
+		r = vhost_update_avail_event(vq, vq->avail_idx);
 		if (r) {
 			vq_err(vq, "Failed to update avail event index at %p: %d\n",
 			       vhost_avail_event(vq), r);
@@ -1475,7 +1510,7 @@ void vhost_disable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
 		return;
 	vq->used_flags |= VRING_USED_F_NO_NOTIFY;
 	if (!vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) {
-		r = put_user(vq->used_flags, &vq->used->flags);
+		r = vhost_update_used_flags(vq);
 		if (r)
 			vq_err(vq, "Failed to enable notification at %p: %d\n",
 			       &vq->used->flags, r);

^ permalink raw reply related

* [PATCH 00/02][RESEND] virtio: Virtio platform driver
From: Magnus Damm @ 2011-06-21 10:26 UTC (permalink / raw)
  To: linux-kernel; +Cc: vapier, mst, linux-sh, Magnus Damm, virtualization

virtio: Virtio platform driver

[PATCH 01/02] virtio: Break out lguest virtio code to virtio_lguest.c
[PATCH 02/02] virtio: Add virtio platform driver

These patches add a virtio platform driver to the Linux kernel. This
platform driver has the same role as the virtio_pci driver, but instead
of building on top of emulated PCI this driver is making use of the
platform bus together with driver specific callbacks.

The virtio platform driver can be seen as a reusable implementation of
the lguest virtio driver - in fact, most code is just taken directly
from lguest_device.c and reworked to fit the platform device driver
abstraction. The first patch breaks out code that can be shared between
lguest and the virtio platform driver.

This code has been used to implement a mailbox interface between the
two processor cores included in the sh7372 SoC. The sh7372 contains
one ARM Cortex-A8 and one SH4AL-DSP core, and in the prototype two
Linux kernels are running in parallel on the same chip. Virtio serves
as a communication link between the two cores.

These patches have not been updated since last time they were posted
20110310, but are known to apply and compile against linux-3.0-rc.

For a full source release, have a look at SH Core Linux 20110317:
http://www.spinics.net/lists/linux-sh/msg07188.html

The SH kernel patch shows how to make use of the virtio platform driver.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 arch/x86/lguest/Kconfig          |    1 
 drivers/lguest/lguest_device.c   |  209 ----------------------------
 drivers/virtio/Kconfig           |   13 +
 drivers/virtio/Makefile          |    2 
 drivers/virtio/virtio_lguest.c   |  205 ++++++++++++++++++++++++++++
 drivers/virtio/virtio_platform.c |  282 +++++++++++++++++++++++++++++++++++++++
 include/linux/lguest.h           |    1 
 include/linux/lguest_device.h    |   46 ++++++
 include/linux/virtio_platform.h  |   12 +
 9 files changed, 564 insertions(+), 207 deletions(-)

^ permalink raw reply

* [PATCH 01/02] virtio: Break out lguest virtio code to virtio_lguest.c
From: Magnus Damm @ 2011-06-21 10:26 UTC (permalink / raw)
  To: linux-kernel; +Cc: vapier, linux-sh, Magnus Damm, virtualization, mst
In-Reply-To: <20110621102605.1382.90232.sendpatchset@t400s>

From: Magnus Damm <damm@opensource.se>

This patch breaks out code from lguest_device.c to the new file
virtio_lguest.c. The new file is built when CONFIG_VIRTIO_LGUEST
is selected. The x86 architecture is updated to select this kconfig
variable in the case of lguest.

Needed by the virtio platform driver that shares configuration data
structures with lguest.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 arch/x86/lguest/Kconfig        |    1 
 drivers/lguest/lguest_device.c |  209 ----------------------------------------
 drivers/virtio/Kconfig         |    2 
 drivers/virtio/Makefile        |    1 
 drivers/virtio/virtio_lguest.c |  205 +++++++++++++++++++++++++++++++++++++++
 include/linux/lguest.h         |    1 
 include/linux/lguest_device.h  |   46 ++++++++
 7 files changed, 258 insertions(+), 207 deletions(-)

--- 0001/arch/x86/lguest/Kconfig
+++ work/arch/x86/lguest/Kconfig	2011-03-03 10:16:11.000000000 +0900
@@ -4,6 +4,7 @@ config LGUEST_GUEST
 	depends on X86_32
 	select VIRTUALIZATION
 	select VIRTIO
+	select VIRTIO_LGUEST
 	select VIRTIO_RING
 	select VIRTIO_CONSOLE
 	help
--- 0001/drivers/lguest/lguest_device.c
+++ work/drivers/lguest/lguest_device.c	2011-03-03 10:16:11.000000000 +0900
@@ -14,6 +14,7 @@
 #include <linux/virtio_config.h>
 #include <linux/interrupt.h>
 #include <linux/virtio_ring.h>
+#include <linux/lguest_device.h>
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <asm/io.h>
@@ -37,137 +38,6 @@ static inline void lguest_unmap(void *ad
 	iounmap((__force void __iomem *)addr);
 }
 
-/*D:100
- * Each lguest device is just a virtio device plus a pointer to its entry
- * in the lguest_devices page.
- */
-struct lguest_device {
-	struct virtio_device vdev;
-
-	/* The entry in the lguest_devices page for this device. */
-	struct lguest_device_desc *desc;
-};
-
-/*
- * Since the virtio infrastructure hands us a pointer to the virtio_device all
- * the time, it helps to have a curt macro to get a pointer to the struct
- * lguest_device it's enclosed in.
- */
-#define to_lgdev(vd) container_of(vd, struct lguest_device, vdev)
-
-/*D:130
- * Device configurations
- *
- * The configuration information for a device consists of one or more
- * virtqueues, a feature bitmap, and some configuration bytes.  The
- * configuration bytes don't really matter to us: the Launcher sets them up, and
- * the driver will look at them during setup.
- *
- * A convenient routine to return the device's virtqueue config array:
- * immediately after the descriptor.
- */
-static struct lguest_vqconfig *lg_vq(const struct lguest_device_desc *desc)
-{
-	return (void *)(desc + 1);
-}
-
-/* The features come immediately after the virtqueues. */
-static u8 *lg_features(const struct lguest_device_desc *desc)
-{
-	return (void *)(lg_vq(desc) + desc->num_vq);
-}
-
-/* The config space comes after the two feature bitmasks. */
-static u8 *lg_config(const struct lguest_device_desc *desc)
-{
-	return lg_features(desc) + desc->feature_len * 2;
-}
-
-/* The total size of the config page used by this device (incl. desc) */
-static unsigned desc_size(const struct lguest_device_desc *desc)
-{
-	return sizeof(*desc)
-		+ desc->num_vq * sizeof(struct lguest_vqconfig)
-		+ desc->feature_len * 2
-		+ desc->config_len;
-}
-
-/* This gets the device's feature bits. */
-static u32 lg_get_features(struct virtio_device *vdev)
-{
-	unsigned int i;
-	u32 features = 0;
-	struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
-	u8 *in_features = lg_features(desc);
-
-	/* We do this the slow but generic way. */
-	for (i = 0; i < min(desc->feature_len * 8, 32); i++)
-		if (in_features[i / 8] & (1 << (i % 8)))
-			features |= (1 << i);
-
-	return features;
-}
-
-/*
- * The virtio core takes the features the Host offers, and copies the ones
- * supported by the driver into the vdev->features array.  Once that's all
- * sorted out, this routine is called so we can tell the Host which features we
- * understand and accept.
- */
-static void lg_finalize_features(struct virtio_device *vdev)
-{
-	unsigned int i, bits;
-	struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
-	/* Second half of bitmap is features we accept. */
-	u8 *out_features = lg_features(desc) + desc->feature_len;
-
-	/* Give virtio_ring a chance to accept features. */
-	vring_transport_features(vdev);
-
-	/*
-	 * The vdev->feature array is a Linux bitmask: this isn't the same as a
-	 * the simple array of bits used by lguest devices for features.  So we
-	 * do this slow, manual conversion which is completely general.
-	 */
-	memset(out_features, 0, desc->feature_len);
-	bits = min_t(unsigned, desc->feature_len, sizeof(vdev->features)) * 8;
-	for (i = 0; i < bits; i++) {
-		if (test_bit(i, vdev->features))
-			out_features[i / 8] |= (1 << (i % 8));
-	}
-}
-
-/* Once they've found a field, getting a copy of it is easy. */
-static void lg_get(struct virtio_device *vdev, unsigned int offset,
-		   void *buf, unsigned len)
-{
-	struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
-
-	/* Check they didn't ask for more than the length of the config! */
-	BUG_ON(offset + len > desc->config_len);
-	memcpy(buf, lg_config(desc) + offset, len);
-}
-
-/* Setting the contents is also trivial. */
-static void lg_set(struct virtio_device *vdev, unsigned int offset,
-		   const void *buf, unsigned len)
-{
-	struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
-
-	/* Check they didn't ask for more than the length of the config! */
-	BUG_ON(offset + len > desc->config_len);
-	memcpy(lg_config(desc) + offset, buf, len);
-}
-
-/*
- * The operations to get and set the status word just access the status field
- * of the device descriptor.
- */
-static u8 lg_get_status(struct virtio_device *vdev)
-{
-	return to_lgdev(vdev)->desc->status;
-}
-
 /*
  * To notify on status updates, we (ab)use the NOTIFY hypercall, with the
  * descriptor address of the device.  A zero status means "reset".
@@ -392,81 +262,6 @@ static struct virtio_config_ops lguest_c
  */
 static struct device *lguest_root;
 
-/*D:120
- * This is the core of the lguest bus: actually adding a new device.
- * It's a separate function because it's neater that way, and because an
- * earlier version of the code supported hotplug and unplug.  They were removed
- * early on because they were never used.
- *
- * As Andrew Tridgell says, "Untested code is buggy code".
- *
- * It's worth reading this carefully: we start with a pointer to the new device
- * descriptor in the "lguest_devices" page, and the offset into the device
- * descriptor page so we can uniquely identify it if things go badly wrong.
- */
-static void add_lguest_device(struct lguest_device_desc *d,
-			      unsigned int offset)
-{
-	struct lguest_device *ldev;
-
-	/* Start with zeroed memory; Linux's device layer counts on it. */
-	ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
-	if (!ldev) {
-		printk(KERN_EMERG "Cannot allocate lguest dev %u type %u\n",
-		       offset, d->type);
-		return;
-	}
-
-	/* This devices' parent is the lguest/ dir. */
-	ldev->vdev.dev.parent = lguest_root;
-	/*
-	 * The device type comes straight from the descriptor.  There's also a
-	 * device vendor field in the virtio_device struct, which we leave as
-	 * 0.
-	 */
-	ldev->vdev.id.device = d->type;
-	/*
-	 * We have a simple set of routines for querying the device's
-	 * configuration information and setting its status.
-	 */
-	ldev->vdev.config = &lguest_config_ops;
-	/* And we remember the device's descriptor for lguest_config_ops. */
-	ldev->desc = d;
-
-	/*
-	 * register_virtio_device() sets up the generic fields for the struct
-	 * virtio_device and calls device_register().  This makes the bus
-	 * infrastructure look for a matching driver.
-	 */
-	if (register_virtio_device(&ldev->vdev) != 0) {
-		printk(KERN_ERR "Failed to register lguest dev %u type %u\n",
-		       offset, d->type);
-		kfree(ldev);
-	}
-}
-
-/*D:110
- * scan_devices() simply iterates through the device page.  The type 0 is
- * reserved to mean "end of devices".
- */
-static void scan_devices(void)
-{
-	unsigned int i;
-	struct lguest_device_desc *d;
-
-	/* We start at the page beginning, and skip over each entry. */
-	for (i = 0; i < PAGE_SIZE; i += desc_size(d)) {
-		d = lguest_devices + i;
-
-		/* Once we hit a zero, stop. */
-		if (d->type == 0)
-			break;
-
-		printk("Device at %i has size %u\n", i, desc_size(d));
-		add_lguest_device(d, i);
-	}
-}
-
 /*D:105
  * Fairly early in boot, lguest_devices_init() is called to set up the
  * lguest device infrastructure.  We check that we are a Guest by checking
@@ -493,7 +288,7 @@ static int __init lguest_devices_init(vo
 	/* Devices are in a single page above top of "normal" mem */
 	lguest_devices = lguest_map(max_pfn<<PAGE_SHIFT, 1);
 
-	scan_devices();
+	lg_scan_devices(lguest_devices, lguest_root, &lguest_config_ops);
 	return 0;
 }
 /* We do this after core stuff, but before the drivers. */
--- 0001/drivers/virtio/Kconfig
+++ work/drivers/virtio/Kconfig	2011-03-03 10:16:11.000000000 +0900
@@ -33,3 +33,5 @@ config VIRTIO_BALLOON
 
 	 If unsure, say M.
 
+config VIRTIO_LGUEST
+	tristate
--- 0001/drivers/virtio/Makefile
+++ work/drivers/virtio/Makefile	2011-03-03 10:16:11.000000000 +0900
@@ -2,3 +2,4 @@ obj-$(CONFIG_VIRTIO) += virtio.o
 obj-$(CONFIG_VIRTIO_RING) += virtio_ring.o
 obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o
 obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o
+obj-$(CONFIG_VIRTIO_LGUEST) += virtio_lguest.o
--- /dev/null
+++ work/drivers/virtio/virtio_lguest.c	2011-03-03 10:16:12.000000000 +0900
@@ -0,0 +1,205 @@
+/*P:050
+ * Lguest guests use a very simple method to describe devices.  It's a
+ * series of device descriptors contained just above the top of normal Guest
+ * memory.
+ *
+ * We use the standard "virtio" device infrastructure, which provides us with a
+ * console, a network and a block driver.  Each one expects some configuration
+ * information and a "virtqueue" or two to send and receive data.
+:*/
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/lguest_launcher.h>
+#include <linux/virtio.h>
+#include <linux/virtio_config.h>
+#include <linux/interrupt.h>
+#include <linux/virtio_ring.h>
+#include <linux/lguest_device.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+
+/*D:130
+ * Device configurations
+ *
+ * The configuration information for a device consists of one or more
+ * virtqueues, a feature bitmap, and some configuration bytes.  The
+ * configuration bytes don't really matter to us: the Launcher sets them up, and
+ * the driver will look at them during setup.
+ */
+
+/* The features come immediately after the virtqueues. */
+static u8 *lg_features(const struct lguest_device_desc *desc)
+{
+	return (void *)(lg_vq(desc) + desc->num_vq);
+}
+
+/* The config space comes after the two feature bitmasks. */
+static u8 *lg_config(const struct lguest_device_desc *desc)
+{
+	return lg_features(desc) + desc->feature_len * 2;
+}
+
+/* The total size of the config page used by this device (incl. desc) */
+static unsigned desc_size(const struct lguest_device_desc *desc)
+{
+	return sizeof(*desc)
+		+ desc->num_vq * sizeof(struct lguest_vqconfig)
+		+ desc->feature_len * 2
+		+ desc->config_len;
+}
+
+/* This gets the device's feature bits. */
+u32 lg_get_features(struct virtio_device *vdev)
+{
+	unsigned int i;
+	u32 features = 0;
+	struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
+	u8 *in_features = lg_features(desc);
+
+	/* We do this the slow but generic way. */
+	for (i = 0; i < min(desc->feature_len * 8, 32); i++)
+		if (in_features[i / 8] & (1 << (i % 8)))
+			features |= (1 << i);
+
+	return features;
+}
+
+/*
+ * The virtio core takes the features the Host offers, and copies the ones
+ * supported by the driver into the vdev->features array.  Once that's all
+ * sorted out, this routine is called so we can tell the Host which features we
+ * understand and accept.
+ */
+void lg_finalize_features(struct virtio_device *vdev)
+{
+	unsigned int i, bits;
+	struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
+	/* Second half of bitmap is features we accept. */
+	u8 *out_features = lg_features(desc) + desc->feature_len;
+
+	/* Give virtio_ring a chance to accept features. */
+	vring_transport_features(vdev);
+
+	/*
+	 * The vdev->feature array is a Linux bitmask: this isn't the same as a
+	 * the simple array of bits used by lguest devices for features.  So we
+	 * do this slow, manual conversion which is completely general.
+	 */
+	memset(out_features, 0, desc->feature_len);
+	bits = min_t(unsigned, desc->feature_len, sizeof(vdev->features)) * 8;
+	for (i = 0; i < bits; i++) {
+		if (test_bit(i, vdev->features))
+			out_features[i / 8] |= (1 << (i % 8));
+	}
+}
+
+/* Once they've found a field, getting a copy of it is easy. */
+void lg_get(struct virtio_device *vdev, unsigned int offset,
+	    void *buf, unsigned len)
+{
+	struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
+
+	/* Check they didn't ask for more than the length of the config! */
+	BUG_ON(offset + len > desc->config_len);
+	memcpy(buf, lg_config(desc) + offset, len);
+}
+
+/* Setting the contents is also trivial. */
+void lg_set(struct virtio_device *vdev, unsigned int offset,
+	    const void *buf, unsigned len)
+{
+	struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
+
+	/* Check they didn't ask for more than the length of the config! */
+	BUG_ON(offset + len > desc->config_len);
+	memcpy(lg_config(desc) + offset, buf, len);
+}
+
+/*
+ * The operations to get and set the status word just access the status field
+ * of the device descriptor.
+ */
+u8 lg_get_status(struct virtio_device *vdev)
+{
+	return to_lgdev(vdev)->desc->status;
+}
+
+/*D:120
+ * This is the core of the lguest bus: actually adding a new device.
+ * It's a separate function because it's neater that way, and because an
+ * earlier version of the code supported hotplug and unplug.  They were removed
+ * early on because they were never used.
+ *
+ * As Andrew Tridgell says, "Untested code is buggy code".
+ *
+ * It's worth reading this carefully: we start with a pointer to the new device
+ * descriptor in the "lguest_devices" page, and the offset into the device
+ * descriptor page so we can uniquely identify it if things go badly wrong.
+ */
+static void add_lguest_device(struct lguest_device_desc *d,
+			      unsigned int offset,
+			      struct device *root,
+			      struct virtio_config_ops *ops)
+{
+	struct lguest_device *ldev;
+
+	/* Start with zeroed memory; Linux's device layer counts on it. */
+	ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
+	if (!ldev) {
+		printk(KERN_EMERG "Cannot allocate lguest dev %u type %u\n",
+		       offset, d->type);
+		return;
+	}
+
+	/* This devices' parent is the lguest/ dir. */
+	ldev->vdev.dev.parent = root;
+	/*
+	 * The device type comes straight from the descriptor.  There's also a
+	 * device vendor field in the virtio_device struct, which we leave as
+	 * 0.
+	 */
+	ldev->vdev.id.device = d->type;
+	/*
+	 * We have a simple set of routines for querying the device's
+	 * configuration information and setting its status.
+	 */
+	ldev->vdev.config = ops;
+	/* And we remember the device's descriptor. */
+	ldev->desc = d;
+
+	/*
+	 * register_virtio_device() sets up the generic fields for the struct
+	 * virtio_device and calls device_register().  This makes the bus
+	 * infrastructure look for a matching driver.
+	 */
+	if (register_virtio_device(&ldev->vdev) != 0) {
+		printk(KERN_ERR "Failed to register lguest dev %u type %u\n",
+		       offset, d->type);
+		kfree(ldev);
+	}
+}
+
+/*D:110
+ * lg_scan_devices() simply iterates through the device page.  The type 0 is
+ * reserved to mean "end of devices".
+ */
+void lg_scan_devices(void *lguest_devices,
+		     struct device *root,
+		     struct virtio_config_ops *ops)
+{
+	unsigned int i;
+	struct lguest_device_desc *d;
+
+	/* We start at the page beginning, and skip over each entry. */
+	for (i = 0; i < PAGE_SIZE; i += desc_size(d)) {
+		d = lguest_devices + i;
+
+		/* Once we hit a zero, stop. */
+		if (d->type == 0)
+			break;
+
+		printk("Device at %i has size %u\n", i, desc_size(d));
+		add_lguest_device(d, i, root, ops);
+	}
+}
--- 0001/include/linux/lguest.h
+++ work/include/linux/lguest.h	2011-03-03 10:16:11.000000000 +0900
@@ -71,5 +71,6 @@ struct lguest_data {
 	unsigned int syscall_vec;
 };
 extern struct lguest_data lguest_data;
+
 #endif /* __ASSEMBLY__ */
 #endif	/* _LINUX_LGUEST_H */
--- /dev/null
+++ work/include/linux/lguest_device.h	2011-03-03 16:07:51.000000000 +0900
@@ -0,0 +1,46 @@
+#ifndef _LINUX_LGUEST_DEVICE_H
+#define _LINUX_LGUEST_DEVICE_H
+
+#include <linux/virtio.h>
+#include <linux/lguest_launcher.h>
+
+/*D:100
+ * Each lguest device is just a virtio device plus a pointer to its entry
+ * in the lguest_devices page.
+ */
+struct lguest_device {
+	struct virtio_device vdev;
+
+	/* The entry in the lguest_devices page for this device. */
+	struct lguest_device_desc *desc;
+};
+
+u32 lg_get_features(struct virtio_device *vdev);
+void lg_finalize_features(struct virtio_device *vdev);
+void lg_get(struct virtio_device *vdev, unsigned int offset,
+	    void *buf, unsigned len);
+void lg_set(struct virtio_device *vdev, unsigned int offset,
+	    const void *buf, unsigned len);
+u8 lg_get_status(struct virtio_device *vdev);
+void lg_scan_devices(void *lguest_devices,
+		     struct device *root,
+		     struct virtio_config_ops *ops);
+
+/*
+ * A convenient routine to return the device's virtqueue config array:
+ * immediately after the descriptor.
+ */
+static inline struct lguest_vqconfig *
+lg_vq(const struct lguest_device_desc *desc)
+{
+	return (void *)(desc + 1);
+}
+
+/*
+ * Since the virtio infrastructure hands us a pointer to the virtio_device all
+ * the time, it helps to have a curt macro to get a pointer to the struct
+ * lguest_device it's enclosed in.
+ */
+#define to_lgdev(vd) container_of(vd, struct lguest_device, vdev)
+
+#endif	/* _LINUX_LGUEST_DEVICE_H */

^ permalink raw reply

* [PATCH 02/02] virtio: Add virtio platform driver
From: Magnus Damm @ 2011-06-21 10:26 UTC (permalink / raw)
  To: linux-kernel; +Cc: vapier, mst, linux-sh, Magnus Damm, virtualization
In-Reply-To: <20110621102605.1382.90232.sendpatchset@t400s>

From: Magnus Damm <damm@opensource.se>

This patch adds a virtio platform driver. The code is based on
the lguest implementation available in drivers/lguest/lguest_device.c

The iomem resource is used to point out the lguest device descriptor,
and the platform data contains two separate callbacks for notification.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/virtio/Kconfig           |   11 +
 drivers/virtio/Makefile          |    1 
 drivers/virtio/virtio_platform.c |  282 ++++++++++++++++++++++++++++++++++++++
 include/linux/virtio_platform.h  |   12 +
 4 files changed, 306 insertions(+)

--- 0002/drivers/virtio/Kconfig
+++ work/drivers/virtio/Kconfig	2011-03-03 15:56:53.000000000 +0900
@@ -35,3 +35,14 @@ config VIRTIO_BALLOON
 
 config VIRTIO_LGUEST
 	tristate
+
+config VIRTIO_PLATFORM
+	tristate "Platform driver for virtio devices (EXPERIMENTAL)"
+	select VIRTIO
+	select VIRTIO_RING
+	select VIRTIO_LGUEST
+	---help---
+	 This drivers provides support for virtio based paravirtual device
+	 drivers over a platform bus.
+
+	 If unsure, say N.
--- 0002/drivers/virtio/Makefile
+++ work/drivers/virtio/Makefile	2011-03-03 15:56:53.000000000 +0900
@@ -3,3 +3,4 @@ obj-$(CONFIG_VIRTIO_RING) += virtio_ring
 obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o
 obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o
 obj-$(CONFIG_VIRTIO_LGUEST) += virtio_lguest.o
+obj-$(CONFIG_VIRTIO_PLATFORM) += virtio_platform.o
--- /dev/null
+++ work/drivers/virtio/virtio_platform.c	2011-03-03 16:07:31.000000000 +0900
@@ -0,0 +1,282 @@
+#include <linux/init.h>
+#include <linux/virtio.h>
+#include <linux/virtio_config.h>
+#include <linux/virtio_ring.h>
+#include <linux/lguest_device.h>
+#include <linux/lguest_launcher.h>
+#include <linux/virtio_platform.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+static void __iomem *virtio_map(unsigned long phys_addr, unsigned long pages)
+{
+	return ioremap_nocache(phys_addr, PAGE_SIZE*pages);
+}
+
+static void virtio_unmap(void __iomem *addr)
+{
+	iounmap(addr);
+}
+
+static void set_status(struct virtio_device *vdev, u8 status)
+{
+	struct platform_device *pdev = to_platform_device(vdev->dev.parent);
+	struct virtio_platform_data *pdata = pdev->dev.platform_data;
+
+	to_lgdev(vdev)->desc->status = status;
+	pdata->notify_virtio(pdev);
+}
+
+static void lg_set_status(struct virtio_device *vdev, u8 status)
+{
+	BUG_ON(!status);
+	set_status(vdev, status);
+}
+
+static void lg_reset(struct virtio_device *vdev)
+{
+	set_status(vdev, 0);
+}
+
+/*
+ * Virtqueues
+ *
+ * The other piece of infrastructure virtio needs is a "virtqueue": a way of
+ * the Guest device registering buffers for the other side to read from or
+ * write into (ie. send and receive buffers).  Each device can have multiple
+ * virtqueues: for example the console driver uses one queue for sending and
+ * another for receiving.
+ *
+ * Fortunately for us, a very fast shared-memory-plus-descriptors virtqueue
+ * already exists in virtio_ring.c.  We just need to connect it up.
+ *
+ * We start with the information we need to keep about each virtqueue.
+ */
+
+/*D:140 This is the information we remember about each virtqueue. */
+struct lguest_vq_info {
+	/* A copy of the information contained in the device config. */
+	struct lguest_vqconfig config;
+
+	/* The address where we mapped the virtio ring, so we can unmap it. */
+	void __iomem *pages;
+};
+
+/*
+ * When the virtio_ring code wants to prod the Host, it calls us here and we
+ * call the board specific callback.  We hand a pointer to the configuration
+ * so the board code knows which virtqueue we're talking about.
+ */
+static void lg_notify(struct virtqueue *vq)
+{
+	struct platform_device *pdev = to_platform_device(vq->vdev->dev.parent);
+	struct virtio_platform_data *pdata = pdev->dev.platform_data;
+	struct lguest_vq_info *lvq = vq->priv;
+
+	pdata->notify_virtqueue(pdev, &lvq->config);
+}
+
+/*
+ * This routine finds the Nth virtqueue described in the configuration of
+ * this device and sets it up.
+ *
+ * This is kind of an ugly duckling.  It'd be nicer to have a standard
+ * representation of a virtqueue in the configuration space, but it seems that
+ * everyone wants to do it differently.  The KVM coders want the Guest to
+ * allocate its own pages and tell the Host where they are, but for lguest it's
+ * simpler for the Host to simply tell us where the pages are.
+ */
+static struct virtqueue *lg_find_vq(struct virtio_device *vdev,
+				    unsigned index,
+				    void (*callback)(struct virtqueue *vq),
+				    const char *name)
+{
+	struct lguest_device *ldev = to_lgdev(vdev);
+	struct lguest_vq_info *lvq;
+	struct virtqueue *vq;
+	int err;
+
+	/* We must have this many virtqueues. */
+	if (index >= ldev->desc->num_vq)
+		return ERR_PTR(-ENOENT);
+
+	lvq = kmalloc(sizeof(*lvq), GFP_KERNEL);
+	if (!lvq)
+		return ERR_PTR(-ENOMEM);
+
+	/*
+	 * Make a copy of the "struct lguest_vqconfig" entry, which sits after
+	 * the descriptor.  We need a copy because the config space might not
+	 * be aligned correctly.
+	 */
+	memcpy(&lvq->config, lg_vq(ldev->desc)+index, sizeof(lvq->config));
+
+	dev_info(&vdev->dev, "Mapping virtqueue %i addr %lx\n", index,
+		 (unsigned long)lvq->config.pfn << PAGE_SHIFT);
+	/* Figure out how many pages the ring will take, and map that memory */
+	lvq->pages = virtio_map((unsigned long)lvq->config.pfn << PAGE_SHIFT,
+				DIV_ROUND_UP(vring_size(lvq->config.num,
+							LGUEST_VRING_ALIGN),
+					     PAGE_SIZE));
+	if (!lvq->pages) {
+		err = -ENOMEM;
+		goto free_lvq;
+	}
+
+	/*
+	 * OK, tell virtio_ring.c to set up a virtqueue now we know its size
+	 * and we've got a pointer to its pages.
+	 */
+	vq = vring_new_virtqueue(lvq->config.num, LGUEST_VRING_ALIGN,
+				 vdev, lvq->pages, lg_notify, callback, name);
+	if (!vq) {
+		err = -ENOMEM;
+		goto unmap;
+	}
+
+	/*
+	 * Tell the interrupt for this virtqueue to go to the virtio_ring
+	 * interrupt handler.
+	 *
+	 * FIXME: We used to have a flag for the Host to tell us we could use
+	 * the interrupt as a source of randomness: it'd be nice to have that
+	 * back.
+	 */
+	err = request_irq(lvq->config.irq, vring_interrupt, IRQF_SHARED,
+			  dev_name(&vdev->dev), vq);
+	if (err)
+		goto destroy_vring;
+
+	/*
+	 * Last of all we hook up our 'struct lguest_vq_info" to the
+	 * virtqueue's priv pointer.
+	 */
+	vq->priv = lvq;
+	return vq;
+
+destroy_vring:
+	vring_del_virtqueue(vq);
+unmap:
+	virtio_unmap(lvq->pages);
+free_lvq:
+	kfree(lvq);
+	return ERR_PTR(err);
+}
+/*:*/
+
+/* Cleaning up a virtqueue is easy */
+static void lg_del_vq(struct virtqueue *vq)
+{
+	struct lguest_vq_info *lvq = vq->priv;
+
+	/* Release the interrupt */
+	free_irq(lvq->config.irq, vq);
+	/* Tell virtio_ring.c to free the virtqueue. */
+	vring_del_virtqueue(vq);
+	/* Unmap the pages containing the ring. */
+	virtio_unmap(lvq->pages);
+	/* Free our own queue information. */
+	kfree(lvq);
+}
+
+static void lg_del_vqs(struct virtio_device *vdev)
+{
+	struct virtqueue *vq, *n;
+
+	list_for_each_entry_safe(vq, n, &vdev->vqs, list)
+		lg_del_vq(vq);
+}
+
+static int lg_find_vqs(struct virtio_device *vdev, unsigned nvqs,
+		       struct virtqueue *vqs[],
+		       vq_callback_t *callbacks[],
+		       const char *names[])
+{
+	struct lguest_device *ldev = to_lgdev(vdev);
+	int i;
+
+	/* We must have this many virtqueues. */
+	if (nvqs > ldev->desc->num_vq)
+		return -ENOENT;
+
+	for (i = 0; i < nvqs; ++i) {
+		vqs[i] = lg_find_vq(vdev, i, callbacks[i], names[i]);
+		if (IS_ERR(vqs[i]))
+			goto error;
+	}
+	return 0;
+
+error:
+	lg_del_vqs(vdev);
+	return PTR_ERR(vqs[i]);
+}
+
+/* The ops structure which hooks everything together. */
+static struct virtio_config_ops lguest_config_ops = {
+	.get_features = lg_get_features,
+	.finalize_features = lg_finalize_features,
+	.get = lg_get,
+	.set = lg_set,
+	.get_status = lg_get_status,
+	.set_status = lg_set_status,
+	.reset = lg_reset,
+	.find_vqs = lg_find_vqs,
+	.del_vqs = lg_del_vqs,
+};
+
+static int virtio_platform_probe(struct platform_device *pdev)
+{
+	struct virtio_platform_data *pdata = pdev->dev.platform_data;
+	struct resource *res;
+	void *devices;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "no platform data defined\n");
+		return -EINVAL;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "cannot find IO resource\n");
+		return -ENOENT;
+	}
+
+	/* Devices are pointed out using struct resource */
+	devices = virtio_map(res->start, resource_size(res) >> PAGE_SHIFT);
+	lg_scan_devices(devices, &pdev->dev, &lguest_config_ops);
+	return 0;
+}
+
+static int virtio_platform_remove(struct platform_device *pdev)
+{
+	return -ENOTSUPP;
+}
+
+static struct platform_driver virtio_platform_driver = {
+	.driver		= {
+		.name		= "virtio-platform",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= virtio_platform_probe,
+	.remove		= virtio_platform_remove,
+};
+
+static int __init virtio_platform_init(void)
+{
+	return platform_driver_register(&virtio_platform_driver);
+}
+
+static void __exit virtio_platform_exit(void)
+{
+	platform_driver_unregister(&virtio_platform_driver);
+}
+
+module_init(virtio_platform_init);
+module_exit(virtio_platform_exit);
+
+MODULE_DESCRIPTION("VirtIO Platform Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:virtio-platform");
--- /dev/null
+++ work/include/linux/virtio_platform.h	2011-03-03 15:56:54.000000000 +0900
@@ -0,0 +1,12 @@
+#ifndef _LINUX_VIRTIO_PLATFORM_H
+#define _LINUX_VIRTIO_PLATFORM_H
+#include <linux/platform_device.h>
+#include <linux/lguest_launcher.h>
+
+struct virtio_platform_data {
+	void (*notify_virtio)(struct platform_device *pdev);
+	void (*notify_virtqueue)(struct platform_device *pdev,
+				 struct lguest_vqconfig *config);
+};
+
+#endif /* _LINUX_VIRTIO_PLATFORM_H */

^ permalink raw reply

* Re: RFT: virtio_net: limit xmit polling
From: Tom Lendacky @ 2011-06-21 15:23 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Krishna Kumar2, habanero, lguest, Shirley Ma, kvm, Carsten Otte,
	linux-s390, Heiko Carstens, linux-kernel, virtualization, steved,
	Christian Borntraeger, netdev, Martin Schwidefsky, linux390
In-Reply-To: <20110619102700.GA11198@redhat.com>

On Sunday, June 19, 2011 05:27:00 AM Michael S. Tsirkin wrote:
> OK, different people seem to test different trees.  In the hope to get
> everyone on the same page, I created several variants of this patch so
> they can be compared. Whoever's interested, please check out the
> following, and tell me how these compare:

I'm in the process of testing these patches.  Base and v0 are complete
and v1 is near complete with v2 to follow.  I'm testing with a variety
of TCP_RR and TCP_STREAM/TCP_MAERTS tests involving local guest-to-guest
tests and remote host-to-guest tests.  I'll post the results in the next
day or two when the tests finish.

Thanks,
Tom

> 
> kernel:
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git
> 
> virtio-net-limit-xmit-polling/base - this is net-next baseline to test
> against virtio-net-limit-xmit-polling/v0 - fixes checks on out of capacity
> virtio-net-limit-xmit-polling/v1 - previous revision of the patch
> 		this does xmit,free,xmit,2*free,free
> virtio-net-limit-xmit-polling/v2 - new revision of the patch
> 		this does free,xmit,2*free,free
> 
> There's also this on top:
> virtio-net-limit-xmit-polling/v3 -> don't delay avail index update
> I don't think it's important to test this one, yet
> 
> Userspace to use: event index work is not yet merged upstream
> so the revision to use is still this:
> git://git.kernel.org/pub/scm/linux/kernel/git/mst/qemu-kvm.git
> virtio-net-event-idx-v3

^ permalink raw reply

* Re: [PATCH 02/02] virtio: Add virtio platform driver
From: Mike Frysinger @ 2011-06-21 18:27 UTC (permalink / raw)
  To: Magnus Damm; +Cc: mst, linux-sh, linux-kernel, virtualization
In-Reply-To: <20110621102623.1382.71841.sendpatchset@t400s>

On Tue, Jun 21, 2011 at 06:26, Magnus Damm wrote:
> +config VIRTIO_PLATFORM
> +       tristate "Platform driver for virtio devices (EXPERIMENTAL)"
> +       select VIRTIO
> +       select VIRTIO_RING
> +       select VIRTIO_LGUEST
> +       ---help---
> +        This drivers provides support for virtio based paravirtual device
> +        drivers over a platform bus.
> +
> +        If unsure, say N.

be nice to add a note as to the name of the module if the user selects "M"

> --- /dev/null
> +++ work/drivers/virtio/virtio_platform.c       2011-03-03 16:07:31.000000000 +0900
> --- /dev/null
> +++ work/include/linux/virtio_platform.h        2011-03-03 15:56:54.000000000 +0900

both files lack a comment block at the top
/*
 * one line desc of file
 *
 * copyright
 *
 * license blurb
 */
-mike
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization

^ permalink raw reply

* Re: [PATCH 00/02][RESEND] virtio: Virtio platform driver
From: Rusty Russell @ 2011-06-22  2:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: vapier, mst, linux-sh, Magnus Damm, virtualization,
	Christian Borntraeger
In-Reply-To: <20110621102605.1382.90232.sendpatchset@t400s>

On Tue, 21 Jun 2011 19:26:05 +0900, Magnus Damm <magnus.damm@gmail.com> wrote:
> virtio: Virtio platform driver
> 
> [PATCH 01/02] virtio: Break out lguest virtio code to virtio_lguest.c
> [PATCH 02/02] virtio: Add virtio platform driver
> 
> These patches add a virtio platform driver to the Linux kernel. This
> platform driver has the same role as the virtio_pci driver, but instead
> of building on top of emulated PCI this driver is making use of the
> platform bus together with driver specific callbacks.
> 
> The virtio platform driver can be seen as a reusable implementation of
> the lguest virtio driver - in fact, most code is just taken directly
> from lguest_device.c and reworked to fit the platform device driver
> abstraction. The first patch breaks out code that can be shared between
> lguest and the virtio platform driver.
> 
> This code has been used to implement a mailbox interface between the
> two processor cores included in the sh7372 SoC. The sh7372 contains
> one ARM Cortex-A8 and one SH4AL-DSP core, and in the prototype two
> Linux kernels are running in parallel on the same chip. Virtio serves
> as a communication link between the two cores.

OK, this seems pretty neat, but I have three questions before we nail this
down (note that lguest doesn't have an ABI, so we can change it as much
as we want).

1) The lguest bus is dumb, and I never thought about device hotplug, for
   example.  It would be nice to handle that somehow.  Is it possible?
   Is this something you care about?

2) Have you seen the '[RFC 0/8] Introducing a generic AMP/IPC framework'
   patches?  Seems to overlap with what you're doing after these patches.

3) The S/390 layout is identical, except their struct kvm_vqconfig is a
   bit different.  Perhaps we should just use theirs (they use a 64-bit
   token instead of an interrupt number).

Christian?

Thanks,
Rusty.

^ permalink raw reply

* Re: Make virtio vq size configurable by a guest.
From: Gleb Natapov @ 2011-06-22 10:21 UTC (permalink / raw)
  To: Rusty Russell; +Cc: mst, virtualization
In-Reply-To: <878vswhrhf.fsf@rustcorp.com.au>

On Tue, Jun 21, 2011 at 11:32:04AM +0930, Rusty Russell wrote:
> On Mon, 20 Jun 2011 16:16:24 +0300, Gleb Natapov <gleb@redhat.com> wrote:
> > Hi,
> > 
> > Currently in virtio host dictates the size and layout of vq that should
> > be used.  To talk to a device that has one vq with 128 elements guest
> > needs to allocate at least 2 pages. Usually this is not a problem, but
> > sometimes guest runs in a resource restricted environment and then it may
> > not have enough memory to initialize all virtio devices present in the
> > system. One such environment is a BIOS. Seabios currently has virtio block
> > support. Since the BIOS should be able to access the disk even after OS
> > is launched vq should be allocated from a special memory region that will
> > be marked as unavailable to an OS, but such memory is scarce. Because vq
> > is so huge only a couple of virtio disks can be initialized by the BIOS.
> > 
> > It would be nice if a guest will be able to tell to a host what vq size
> > should be used instead. BIOS issues only one request at a time anyway,
> > so it needs only one element in vq. It does not care about performance
> > to much either, so it can tell to a host to not align used index to a
> > page boundary. This way vq of one element shouldn't take more then a couple
> > hundreds of bytes.
> 
> Unfortunately, a virtqueue *always* takes at least 2 pages.  That's
> because we split the host/guest part on page boundaries.  (2 pages per
> disk is "huge"?  Really?)
> 
"Huge" only for a BIOS environment, not when normal guest is running. The
problem is those two pages should be allocated from a memory that is
marked as reserved in e820 map since the queue has to be active after
BIOS passes control to an OS. Currently Seabios reserve up to 64K for this
memory pool (memory that is not actually allocated is not marked as
reserved in e820).

> So really, you want to negotiate the ring size and the 'align'
> parameter.  A new feature could allow this, but there may be valid
> reasons for a host to want to place an upper limit, too.
> 
What kind of reason can it be except performance? AFAIK KVM does not have such
restrictions.

--
			Gleb.

^ permalink raw reply

* Re: Make virtio vq size configurable by a guest.
From: Rusty Russell @ 2011-06-23  0:48 UTC (permalink / raw)
  To: Gleb Natapov; +Cc: Anthony Liguori, mst, virtualization
In-Reply-To: <20110622102123.GG491@redhat.com>

On Wed, 22 Jun 2011 13:21:23 +0300, Gleb Natapov <gleb@redhat.com> wrote:
> On Tue, Jun 21, 2011 at 11:32:04AM +0930, Rusty Russell wrote:
> > On Mon, 20 Jun 2011 16:16:24 +0300, Gleb Natapov <gleb@redhat.com> wrote:
> > > Hi,
> > > 
> > > Currently in virtio host dictates the size and layout of vq that should
> > > be used.  To talk to a device that has one vq with 128 elements guest
> > > needs to allocate at least 2 pages. Usually this is not a problem, but
> > > sometimes guest runs in a resource restricted environment and then it may
> > > not have enough memory to initialize all virtio devices present in the
> > > system. One such environment is a BIOS. Seabios currently has virtio block
> > > support. Since the BIOS should be able to access the disk even after OS
> > > is launched vq should be allocated from a special memory region that will
> > > be marked as unavailable to an OS, but such memory is scarce. Because vq
> > > is so huge only a couple of virtio disks can be initialized by the BIOS.
> > > 
> > > It would be nice if a guest will be able to tell to a host what vq size
> > > should be used instead. BIOS issues only one request at a time anyway,
> > > so it needs only one element in vq. It does not care about performance
> > > to much either, so it can tell to a host to not align used index to a
> > > page boundary. This way vq of one element shouldn't take more then a couple
> > > hundreds of bytes.
> > 
> > Unfortunately, a virtqueue *always* takes at least 2 pages.  That's
> > because we split the host/guest part on page boundaries.  (2 pages per
> > disk is "huge"?  Really?)
> > 
> "Huge" only for a BIOS environment, not when normal guest is running. The
> problem is those two pages should be allocated from a memory that is
> marked as reserved in e820 map since the queue has to be active after
> BIOS passes control to an OS. Currently Seabios reserve up to 64K for this
> memory pool (memory that is not actually allocated is not marked as
> reserved in e820).
> 
> > So really, you want to negotiate the ring size and the 'align'
> > parameter.  A new feature could allow this, but there may be valid
> > reasons for a host to want to place an upper limit, too.
> > 
> What kind of reason can it be except performance? AFAIK KVM does not have such
> restrictions.

MST might be able to tell us.  Does vhost pin the ring or anything like
that?

Anyway, we could use feature bit 25 to mean "guest will set queue size
and alignment".  VIRTIO_PCI_F_SET_VQ_SIZE?  And add an alignment field
if that feature is negotiated.

Our other problem is that we use 32 bits to indicate the vq physical
address in VIRTIO_PCI_QUEUE_PFN.  We could change that to be "shift by
the alignment" but that would restrict where you can put your vqs to
physical addresses below 256G (64 is the lowest sensible alignment).
Maybe we need a new/additional field for this?

Thanks,
Rusty.

^ permalink raw reply

* Re: [PATCH 02/02] virtio: Add virtio platform driver
From: Magnus Damm @ 2011-06-23  2:26 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: mst, linux-sh, linux-kernel, virtualization
In-Reply-To: <BANLkTi=tut=Y4fc4tkT8wt_q1azJOYaDoQ@mail.gmail.com>

Hi Mike,

On Wed, Jun 22, 2011 at 3:27 AM, Mike Frysinger <vapier@gentoo.org> wrote:
> On Tue, Jun 21, 2011 at 06:26, Magnus Damm wrote:
>> +config VIRTIO_PLATFORM
>> +       tristate "Platform driver for virtio devices (EXPERIMENTAL)"
>> +       select VIRTIO
>> +       select VIRTIO_RING
>> +       select VIRTIO_LGUEST
>> +       ---help---
>> +        This drivers provides support for virtio based paravirtual device
>> +        drivers over a platform bus.
>> +
>> +        If unsure, say N.
>
> be nice to add a note as to the name of the module if the user selects "M"

Yes, good idea!

>> --- /dev/null
>> +++ work/drivers/virtio/virtio_platform.c       2011-03-03 16:07:31.000000000 +0900
>> --- /dev/null
>> +++ work/include/linux/virtio_platform.h        2011-03-03 15:56:54.000000000 +0900
>
> both files lack a comment block at the top
> /*
>  * one line desc of file
>  *
>  * copyright
>  *
>  * license blurb
>  */

Sure! I will include these changes in the next version!

Thank you!

/ magnus

^ permalink raw reply

* RE: [PATCH 02/02] virtio: Add virtio platform driver
From: Bhushan Bharat-R65777 @ 2011-06-23  8:54 UTC (permalink / raw)
  To: Magnus Damm, linux-kernel@vger.kernel.org
  Cc: linux-sh@vger.kernel.org, vapier@gentoo.org,
	virtualization@lists.linux-foundation.org, mst@redhat.com
In-Reply-To: <20110621102623.1382.71841.sendpatchset@t400s>

What purpose this virtio platform driver serves? Are you trying to make driver layers here and each virtio device driver can hook up into this platform driver. Is that correct ?

Thanks
-Bharat


> -----Original Message-----
> From: virtualization-bounces@lists.linux-foundation.org
> [mailto:virtualization-bounces@lists.linux-foundation.org] On Behalf Of
> Magnus Damm
> Sent: Tuesday, June 21, 2011 3:56 PM
> To: linux-kernel@vger.kernel.org
> Cc: vapier@gentoo.org; mst@redhat.com; linux-sh@vger.kernel.org; Magnus
> Damm; virtualization@lists.linux-foundation.org
> Subject: [PATCH 02/02] virtio: Add virtio platform driver
> 
> From: Magnus Damm <damm@opensource.se>
> 
> This patch adds a virtio platform driver. The code is based on the lguest
> implementation available in drivers/lguest/lguest_device.c
> 
> The iomem resource is used to point out the lguest device descriptor, and
> the platform data contains two separate callbacks for notification.
> 
> Signed-off-by: Magnus Damm <damm@opensource.se>
> ---
> 
>  drivers/virtio/Kconfig           |   11 +
>  drivers/virtio/Makefile          |    1
>  drivers/virtio/virtio_platform.c |  282
> ++++++++++++++++++++++++++++++++++++++
>  include/linux/virtio_platform.h  |   12 +
>  4 files changed, 306 insertions(+)
> 
> --- 0002/drivers/virtio/Kconfig
> +++ work/drivers/virtio/Kconfig	2011-03-03 15:56:53.000000000 +0900
> @@ -35,3 +35,14 @@ config VIRTIO_BALLOON
> 
>  config VIRTIO_LGUEST
>  	tristate
> +
> +config VIRTIO_PLATFORM
> +	tristate "Platform driver for virtio devices (EXPERIMENTAL)"
> +	select VIRTIO
> +	select VIRTIO_RING
> +	select VIRTIO_LGUEST
> +	---help---
> +	 This drivers provides support for virtio based paravirtual device
> +	 drivers over a platform bus.
> +
> +	 If unsure, say N.
> --- 0002/drivers/virtio/Makefile
> +++ work/drivers/virtio/Makefile	2011-03-03 15:56:53.000000000 +0900
> @@ -3,3 +3,4 @@ obj-$(CONFIG_VIRTIO_RING) += virtio_ring
>  obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o
>  obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o
>  obj-$(CONFIG_VIRTIO_LGUEST) += virtio_lguest.o
> +obj-$(CONFIG_VIRTIO_PLATFORM) += virtio_platform.o
> --- /dev/null
> +++ work/drivers/virtio/virtio_platform.c	2011-03-03 16:07:31.000000000
> +0900
> @@ -0,0 +1,282 @@
> +#include <linux/init.h>
> +#include <linux/virtio.h>
> +#include <linux/virtio_config.h>
> +#include <linux/virtio_ring.h>
> +#include <linux/lguest_device.h>
> +#include <linux/lguest_launcher.h>
> +#include <linux/virtio_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/interrupt.h>
> +#include <linux/err.h>
> +#include <linux/slab.h>
> +#include <linux/io.h>
> +
> +static void __iomem *virtio_map(unsigned long phys_addr, unsigned long
> +pages) {
> +	return ioremap_nocache(phys_addr, PAGE_SIZE*pages); }
> +
> +static void virtio_unmap(void __iomem *addr) {
> +	iounmap(addr);
> +}
> +
> +static void set_status(struct virtio_device *vdev, u8 status) {
> +	struct platform_device *pdev = to_platform_device(vdev-
> >dev.parent);
> +	struct virtio_platform_data *pdata = pdev->dev.platform_data;
> +
> +	to_lgdev(vdev)->desc->status = status;
> +	pdata->notify_virtio(pdev);
> +}
> +
> +static void lg_set_status(struct virtio_device *vdev, u8 status) {
> +	BUG_ON(!status);
> +	set_status(vdev, status);
> +}
> +
> +static void lg_reset(struct virtio_device *vdev) {
> +	set_status(vdev, 0);
> +}
> +
> +/*
> + * Virtqueues
> + *
> + * The other piece of infrastructure virtio needs is a "virtqueue": a
> +way of
> + * the Guest device registering buffers for the other side to read from
> +or
> + * write into (ie. send and receive buffers).  Each device can have
> +multiple
> + * virtqueues: for example the console driver uses one queue for
> +sending and
> + * another for receiving.
> + *
> + * Fortunately for us, a very fast shared-memory-plus-descriptors
> +virtqueue
> + * already exists in virtio_ring.c.  We just need to connect it up.
> + *
> + * We start with the information we need to keep about each virtqueue.
> + */
> +
> +/*D:140 This is the information we remember about each virtqueue. */
> +struct lguest_vq_info {
> +	/* A copy of the information contained in the device config. */
> +	struct lguest_vqconfig config;
> +
> +	/* The address where we mapped the virtio ring, so we can unmap it.
> */
> +	void __iomem *pages;
> +};
> +
> +/*
> + * When the virtio_ring code wants to prod the Host, it calls us here
> +and we
> + * call the board specific callback.  We hand a pointer to the
> +configuration
> + * so the board code knows which virtqueue we're talking about.
> + */
> +static void lg_notify(struct virtqueue *vq) {
> +	struct platform_device *pdev = to_platform_device(vq->vdev-
> >dev.parent);
> +	struct virtio_platform_data *pdata = pdev->dev.platform_data;
> +	struct lguest_vq_info *lvq = vq->priv;
> +
> +	pdata->notify_virtqueue(pdev, &lvq->config); }
> +
> +/*
> + * This routine finds the Nth virtqueue described in the configuration
> +of
> + * this device and sets it up.
> + *
> + * This is kind of an ugly duckling.  It'd be nicer to have a standard
> + * representation of a virtqueue in the configuration space, but it
> +seems that
> + * everyone wants to do it differently.  The KVM coders want the Guest
> +to
> + * allocate its own pages and tell the Host where they are, but for
> +lguest it's
> + * simpler for the Host to simply tell us where the pages are.
> + */
> +static struct virtqueue *lg_find_vq(struct virtio_device *vdev,
> +				    unsigned index,
> +				    void (*callback)(struct virtqueue *vq),
> +				    const char *name)
> +{
> +	struct lguest_device *ldev = to_lgdev(vdev);
> +	struct lguest_vq_info *lvq;
> +	struct virtqueue *vq;
> +	int err;
> +
> +	/* We must have this many virtqueues. */
> +	if (index >= ldev->desc->num_vq)
> +		return ERR_PTR(-ENOENT);
> +
> +	lvq = kmalloc(sizeof(*lvq), GFP_KERNEL);
> +	if (!lvq)
> +		return ERR_PTR(-ENOMEM);
> +
> +	/*
> +	 * Make a copy of the "struct lguest_vqconfig" entry, which sits
> after
> +	 * the descriptor.  We need a copy because the config space might
> not
> +	 * be aligned correctly.
> +	 */
> +	memcpy(&lvq->config, lg_vq(ldev->desc)+index, sizeof(lvq->config));
> +
> +	dev_info(&vdev->dev, "Mapping virtqueue %i addr %lx\n", index,
> +		 (unsigned long)lvq->config.pfn << PAGE_SHIFT);
> +	/* Figure out how many pages the ring will take, and map that
> memory */
> +	lvq->pages = virtio_map((unsigned long)lvq->config.pfn <<
> PAGE_SHIFT,
> +				DIV_ROUND_UP(vring_size(lvq->config.num,
> +							LGUEST_VRING_ALIGN),
> +					     PAGE_SIZE));
> +	if (!lvq->pages) {
> +		err = -ENOMEM;
> +		goto free_lvq;
> +	}
> +
> +	/*
> +	 * OK, tell virtio_ring.c to set up a virtqueue now we know its
> size
> +	 * and we've got a pointer to its pages.
> +	 */
> +	vq = vring_new_virtqueue(lvq->config.num, LGUEST_VRING_ALIGN,
> +				 vdev, lvq->pages, lg_notify, callback, name);
> +	if (!vq) {
> +		err = -ENOMEM;
> +		goto unmap;
> +	}
> +
> +	/*
> +	 * Tell the interrupt for this virtqueue to go to the virtio_ring
> +	 * interrupt handler.
> +	 *
> +	 * FIXME: We used to have a flag for the Host to tell us we could
> use
> +	 * the interrupt as a source of randomness: it'd be nice to have
> that
> +	 * back.
> +	 */
> +	err = request_irq(lvq->config.irq, vring_interrupt, IRQF_SHARED,
> +			  dev_name(&vdev->dev), vq);
> +	if (err)
> +		goto destroy_vring;
> +
> +	/*
> +	 * Last of all we hook up our 'struct lguest_vq_info" to the
> +	 * virtqueue's priv pointer.
> +	 */
> +	vq->priv = lvq;
> +	return vq;
> +
> +destroy_vring:
> +	vring_del_virtqueue(vq);
> +unmap:
> +	virtio_unmap(lvq->pages);
> +free_lvq:
> +	kfree(lvq);
> +	return ERR_PTR(err);
> +}
> +/*:*/
> +
> +/* Cleaning up a virtqueue is easy */
> +static void lg_del_vq(struct virtqueue *vq) {
> +	struct lguest_vq_info *lvq = vq->priv;
> +
> +	/* Release the interrupt */
> +	free_irq(lvq->config.irq, vq);
> +	/* Tell virtio_ring.c to free the virtqueue. */
> +	vring_del_virtqueue(vq);
> +	/* Unmap the pages containing the ring. */
> +	virtio_unmap(lvq->pages);
> +	/* Free our own queue information. */
> +	kfree(lvq);
> +}
> +
> +static void lg_del_vqs(struct virtio_device *vdev) {
> +	struct virtqueue *vq, *n;
> +
> +	list_for_each_entry_safe(vq, n, &vdev->vqs, list)
> +		lg_del_vq(vq);
> +}
> +
> +static int lg_find_vqs(struct virtio_device *vdev, unsigned nvqs,
> +		       struct virtqueue *vqs[],
> +		       vq_callback_t *callbacks[],
> +		       const char *names[])
> +{
> +	struct lguest_device *ldev = to_lgdev(vdev);
> +	int i;
> +
> +	/* We must have this many virtqueues. */
> +	if (nvqs > ldev->desc->num_vq)
> +		return -ENOENT;
> +
> +	for (i = 0; i < nvqs; ++i) {
> +		vqs[i] = lg_find_vq(vdev, i, callbacks[i], names[i]);
> +		if (IS_ERR(vqs[i]))
> +			goto error;
> +	}
> +	return 0;
> +
> +error:
> +	lg_del_vqs(vdev);
> +	return PTR_ERR(vqs[i]);
> +}
> +
> +/* The ops structure which hooks everything together. */ static struct
> +virtio_config_ops lguest_config_ops = {
> +	.get_features = lg_get_features,
> +	.finalize_features = lg_finalize_features,
> +	.get = lg_get,
> +	.set = lg_set,
> +	.get_status = lg_get_status,
> +	.set_status = lg_set_status,
> +	.reset = lg_reset,
> +	.find_vqs = lg_find_vqs,
> +	.del_vqs = lg_del_vqs,
> +};
> +
> +static int virtio_platform_probe(struct platform_device *pdev) {
> +	struct virtio_platform_data *pdata = pdev->dev.platform_data;
> +	struct resource *res;
> +	void *devices;
> +
> +	if (!pdata) {
> +		dev_err(&pdev->dev, "no platform data defined\n");
> +		return -EINVAL;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (res == NULL) {
> +		dev_err(&pdev->dev, "cannot find IO resource\n");
> +		return -ENOENT;
> +	}
> +
> +	/* Devices are pointed out using struct resource */
> +	devices = virtio_map(res->start, resource_size(res) >> PAGE_SHIFT);
> +	lg_scan_devices(devices, &pdev->dev, &lguest_config_ops);
> +	return 0;
> +}
> +
> +static int virtio_platform_remove(struct platform_device *pdev) {
> +	return -ENOTSUPP;
> +}
> +
> +static struct platform_driver virtio_platform_driver = {
> +	.driver		= {
> +		.name		= "virtio-platform",
> +		.owner		= THIS_MODULE,
> +	},
> +	.probe		= virtio_platform_probe,
> +	.remove		= virtio_platform_remove,
> +};
> +
> +static int __init virtio_platform_init(void) {
> +	return platform_driver_register(&virtio_platform_driver);
> +}
> +
> +static void __exit virtio_platform_exit(void) {
> +	platform_driver_unregister(&virtio_platform_driver);
> +}
> +
> +module_init(virtio_platform_init);
> +module_exit(virtio_platform_exit);
> +
> +MODULE_DESCRIPTION("VirtIO Platform Driver"); MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:virtio-platform");
> --- /dev/null
> +++ work/include/linux/virtio_platform.h	2011-03-03 15:56:54.000000000
> +0900
> @@ -0,0 +1,12 @@
> +#ifndef _LINUX_VIRTIO_PLATFORM_H
> +#define _LINUX_VIRTIO_PLATFORM_H
> +#include <linux/platform_device.h>
> +#include <linux/lguest_launcher.h>
> +
> +struct virtio_platform_data {
> +	void (*notify_virtio)(struct platform_device *pdev);
> +	void (*notify_virtqueue)(struct platform_device *pdev,
> +				 struct lguest_vqconfig *config);
> +};
> +
> +#endif /* _LINUX_VIRTIO_PLATFORM_H */
> _______________________________________________
> Virtualization mailing list
> Virtualization@lists.linux-foundation.org
> https://lists.linux-foundation.org/mailman/listinfo/virtualization

^ permalink raw reply

* Re: [PATCH 02/02] virtio: Add virtio platform driver
From: Magnus Damm @ 2011-06-24  1:14 UTC (permalink / raw)
  To: Bhushan Bharat-R65777
  Cc: linux-sh@vger.kernel.org, vapier@gentoo.org,
	linux-kernel@vger.kernel.org,
	virtualization@lists.linux-foundation.org, mst@redhat.com
In-Reply-To: <B8D6CA50DACE9E4AAADE9A4D56FBAAE6166661@039-SN1MPN1-004.039d.mgd.msft.net>

Hi Bhushan Bharat,

On Thu, Jun 23, 2011 at 5:54 PM, Bhushan Bharat-R65777
<R65777@freescale.com> wrote:
> What purpose this virtio platform driver serves? Are you trying to make driver layers here and each virtio device driver can hook up into this platform driver. Is that correct ?

The idea behind the virto platform driver is to have a reusable layer
that handles common virtio and vring functionality. Regular virtio
drivers for console, network and disk and interfacing to the virtio
platform driver, so these paravirtualized drivers can with this virtio
platform driver easily be reused by embedded platforms.

Vendor specific code is abstracted away from the virtio platform
driver and interfaced to using regular interrupts and SoC-specific
callbacks. So with this patch virtio can be interfaced as any regular
platform driver. This version of the driver is simply reusing the
configuration method from lguest.

If you want to see all code involved (including extremely experimental
backing drivers) then have a look at:
http://www.spinics.net/lists/linux-sh/msg07188.html

Cheers,

/ magnus

^ permalink raw reply

* RE: [PATCH 02/02] virtio: Add virtio platform driver
From: Bhushan Bharat-R65777 @ 2011-06-24  4:08 UTC (permalink / raw)
  To: Magnus Damm
  Cc: linux-sh@vger.kernel.org, vapier@gentoo.org,
	linux-kernel@vger.kernel.org,
	virtualization@lists.linux-foundation.org, mst@redhat.com
In-Reply-To: <BANLkTi=QhwBAv5GtrTpitVhx+yDZPnRN+g@mail.gmail.com>

Thanks for the explanation. I also thought of same purpose for this patch but I got confused by function names and data structure names in the patch. They still have lguest in it.

Thanks
-Bharat

> -----Original Message-----
> From: Magnus Damm [mailto:magnus.damm@gmail.com]
> Sent: Friday, June 24, 2011 6:44 AM
> To: Bhushan Bharat-R65777
> Cc: linux-kernel@vger.kernel.org; vapier@gentoo.org; mst@redhat.com;
> linux-sh@vger.kernel.org; virtualization@lists.linux-foundation.org
> Subject: Re: [PATCH 02/02] virtio: Add virtio platform driver
> 
> Hi Bhushan Bharat,
> 
> On Thu, Jun 23, 2011 at 5:54 PM, Bhushan Bharat-R65777
> <R65777@freescale.com> wrote:
> > What purpose this virtio platform driver serves? Are you trying to make
> driver layers here and each virtio device driver can hook up into this
> platform driver. Is that correct ?
> 
> The idea behind the virto platform driver is to have a reusable layer
> that handles common virtio and vring functionality. Regular virtio
> drivers for console, network and disk and interfacing to the virtio
> platform driver, so these paravirtualized drivers can with this virtio
> platform driver easily be reused by embedded platforms.
> 
> Vendor specific code is abstracted away from the virtio platform driver
> and interfaced to using regular interrupts and SoC-specific callbacks. So
> with this patch virtio can be interfaced as any regular platform driver.
> This version of the driver is simply reusing the configuration method
> from lguest.
> 
> If you want to see all code involved (including extremely experimental
> backing drivers) then have a look at:
> http://www.spinics.net/lists/linux-sh/msg07188.html
> 
> Cheers,
> 
> / magnus

^ permalink raw reply

* Re: [RFC] virtio: Support releasing lock during kick
From: Stefan Hajnoczi @ 2011-06-24  9:16 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: Stefan Hajnoczi, kvm, virtualization
In-Reply-To: <BANLkTi=fsSLNu2ybeMKvN7gtCDO5FDNfDA@mail.gmail.com>

On Mon, Jun 20, 2011 at 4:27 PM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> On Sun, Jun 19, 2011 at 8:14 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
>> On Wed, Jun 23, 2010 at 10:24:02PM +0100, Stefan Hajnoczi wrote:
>>> The virtio block device holds a lock during I/O request processing.
>>> Kicking the virtqueue while the lock is held results in long lock hold
>>> times and increases contention for the lock.
>>>
>>> This patch modifies virtqueue_kick() to optionally release a lock while
>>> notifying the host.  Virtio block is modified to pass in its lock.  This
>>> allows other vcpus to queue I/O requests during the time spent servicing
>>> the virtqueue notify in the host.
>>>
>>> The virtqueue_kick() function is modified to know about locking because
>>> it changes the state of the virtqueue and should execute with the lock
>>> held (it would not be correct for virtio block to release the lock
>>> before calling virtqueue_kick()).
>>>
>>> Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>>
>> While the optimization makes sense, the API's pretty hairy IMHO.
>> Why don't we split the kick functionality instead?
>> E.g.
>>        /* Report whether host notification is necessary. */
>>        bool virtqueue_kick_prepare(struct virtqueue *vq)
>>        /* Can be done in parallel with add_buf/get_buf */
>>        void virtqueue_kick_notify(struct virtqueue *vq)
>
> This is a nice idea, it makes the code cleaner.  I am testing patches
> that implement this and after Khoa has measured the performance I will
> send them out.

Just an update that benchmarks are being run.  Will send out patches
and results as soon as they are in.

Stefan

^ permalink raw reply

* Re: RFT: virtio_net: limit xmit polling
From: Roopa Prabhu @ 2011-06-24 12:50 UTC (permalink / raw)
  To: Tom Lendacky, Michael S. Tsirkin
  Cc: Krishna Kumar2, habanero, lguest, Shirley Ma, kvm, Carsten Otte,
	linux-s390, Heiko Carstens, linux-kernel, virtualization, steved,
	Christian Borntraeger, netdev, Martin Schwidefsky, linux390
In-Reply-To: <201106211023.24643.tahm@linux.vnet.ibm.com>


[-- Attachment #1.1: Type: text/plain, Size: 1934 bytes --]

Michael,  

I am testing this too.
 I have finished one round of testing. But am running it again just to
confirm.
This time I will see if I can collect some exit stats too. Will post results
sometime this weekend.
I am just doing TCP_STREAM and TCP_MAERTS from guest to remote host.

Thanks,
Roopa


On 6/21/11 8:23 AM, "Tom Lendacky" <tahm@linux.vnet.ibm.com> wrote:

> On Sunday, June 19, 2011 05:27:00 AM Michael S. Tsirkin wrote:
>> > OK, different people seem to test different trees.  In the hope to get
>> > everyone on the same page, I created several variants of this patch so
>> > they can be compared. Whoever's interested, please check out the
>> > following, and tell me how these compare:
> 
> I'm in the process of testing these patches.  Base and v0 are complete
> and v1 is near complete with v2 to follow.  I'm testing with a variety
> of TCP_RR and TCP_STREAM/TCP_MAERTS tests involving local guest-to-guest
> tests and remote host-to-guest tests.  I'll post the results in the next
> day or two when the tests finish.
> 
> Thanks,
> Tom
> 
>> >
>> > kernel:
>> >
>> > git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git
>> >
>> > virtio-net-limit-xmit-polling/base - this is net-next baseline to test
>> > against virtio-net-limit-xmit-polling/v0 - fixes checks on out of capacity
>> > virtio-net-limit-xmit-polling/v1 - previous revision of the patch
>> >               this does xmit,free,xmit,2*free,free
>> > virtio-net-limit-xmit-polling/v2 - new revision of the patch
>> >               this does free,xmit,2*free,free
>> >
>> > There's also this on top:
>> > virtio-net-limit-xmit-polling/v3 -> don't delay avail index update
>> > I don't think it's important to test this one, yet
>> >
>> > Userspace to use: event index work is not yet merged upstream
>> > so the revision to use is still this:
>> > git://git.kernel.org/pub/scm/linux/kernel/git/mst/qemu-kvm.git
>> > virtio-net-event-idx-v3
> 


[-- Attachment #1.2: Type: text/html, Size: 2700 bytes --]

[-- Attachment #2: Type: text/plain, Size: 184 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization

^ permalink raw reply

* [PATCH 1/2] xen: Populate xenbus device attributes
From: Bastian Blank @ 2011-06-24 21:51 UTC (permalink / raw)
  To: xen-devel, virtualization; +Cc: linux-kernel

The xenbus bus type uses device_create_file to assign all used device
attributes. However it does not remove them when the device goes away.

This patch uses the dev_attrs field of the bus type to specify default
attributes for all devices.

Signed-off-by: Bastian Blank <waldi@debian.org>
---
 drivers/xen/xenbus/xenbus_probe.c          |   41 +++++++++------------------
 drivers/xen/xenbus/xenbus_probe.h          |    2 +
 drivers/xen/xenbus/xenbus_probe_backend.c  |    6 +---
 drivers/xen/xenbus/xenbus_probe_frontend.c |    6 +---
 4 files changed, 18 insertions(+), 37 deletions(-)

diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 7397695..2ed0b04 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -378,26 +378,31 @@ static void xenbus_dev_release(struct device *dev)
 		kfree(to_xenbus_device(dev));
 }
 
-static ssize_t xendev_show_nodename(struct device *dev,
-				    struct device_attribute *attr, char *buf)
+static ssize_t nodename_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
 {
 	return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename);
 }
-static DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL);
 
-static ssize_t xendev_show_devtype(struct device *dev,
-				   struct device_attribute *attr, char *buf)
+static ssize_t devtype_show(struct device *dev,
+			    struct device_attribute *attr, char *buf)
 {
 	return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype);
 }
-static DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
 
-static ssize_t xendev_show_modalias(struct device *dev,
-				    struct device_attribute *attr, char *buf)
+static ssize_t modalias_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
 {
 	return sprintf(buf, "xen:%s\n", to_xenbus_device(dev)->devicetype);
 }
-static DEVICE_ATTR(modalias, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_modalias, NULL);
+
+struct device_attribute xenbus_dev_attrs[] = {
+	__ATTR_RO(nodename),
+	__ATTR_RO(devtype),
+	__ATTR_RO(modalias),
+	__ATTR_NULL
+};
+EXPORT_SYMBOL_GPL(xenbus_dev_attrs);
 
 int xenbus_probe_node(struct xen_bus_type *bus,
 		      const char *type,
@@ -449,25 +454,7 @@ int xenbus_probe_node(struct xen_bus_type *bus,
 	if (err)
 		goto fail;
 
-	err = device_create_file(&xendev->dev, &dev_attr_nodename);
-	if (err)
-		goto fail_unregister;
-
-	err = device_create_file(&xendev->dev, &dev_attr_devtype);
-	if (err)
-		goto fail_remove_nodename;
-
-	err = device_create_file(&xendev->dev, &dev_attr_modalias);
-	if (err)
-		goto fail_remove_devtype;
-
 	return 0;
-fail_remove_devtype:
-	device_remove_file(&xendev->dev, &dev_attr_devtype);
-fail_remove_nodename:
-	device_remove_file(&xendev->dev, &dev_attr_nodename);
-fail_unregister:
-	device_unregister(&xendev->dev);
 fail:
 	kfree(xendev);
 	return err;
diff --git a/drivers/xen/xenbus/xenbus_probe.h b/drivers/xen/xenbus/xenbus_probe.h
index 888b990..b814935 100644
--- a/drivers/xen/xenbus/xenbus_probe.h
+++ b/drivers/xen/xenbus/xenbus_probe.h
@@ -48,6 +48,8 @@ struct xen_bus_type
 	struct bus_type bus;
 };
 
+extern struct device_attribute xenbus_dev_attrs[];
+
 extern int xenbus_match(struct device *_dev, struct device_driver *_drv);
 extern int xenbus_dev_probe(struct device *_dev);
 extern int xenbus_dev_remove(struct device *_dev);
diff --git a/drivers/xen/xenbus/xenbus_probe_backend.c b/drivers/xen/xenbus/xenbus_probe_backend.c
index 6cf467b..ec510e5 100644
--- a/drivers/xen/xenbus/xenbus_probe_backend.c
+++ b/drivers/xen/xenbus/xenbus_probe_backend.c
@@ -183,10 +183,6 @@ static void frontend_changed(struct xenbus_watch *watch,
 	xenbus_otherend_changed(watch, vec, len, 0);
 }
 
-static struct device_attribute xenbus_backend_dev_attrs[] = {
-	__ATTR_NULL
-};
-
 static struct xen_bus_type xenbus_backend = {
 	.root = "backend",
 	.levels = 3,		/* backend/type/<frontend>/<id> */
@@ -200,7 +196,7 @@ static struct xen_bus_type xenbus_backend = {
 		.probe		= xenbus_dev_probe,
 		.remove		= xenbus_dev_remove,
 		.shutdown	= xenbus_dev_shutdown,
-		.dev_attrs	= xenbus_backend_dev_attrs,
+		.dev_attrs	= xenbus_dev_attrs,
 	},
 };
 
diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c
index b6a2690..ed2ba47 100644
--- a/drivers/xen/xenbus/xenbus_probe_frontend.c
+++ b/drivers/xen/xenbus/xenbus_probe_frontend.c
@@ -81,10 +81,6 @@ static void backend_changed(struct xenbus_watch *watch,
 	xenbus_otherend_changed(watch, vec, len, 1);
 }
 
-static struct device_attribute xenbus_frontend_dev_attrs[] = {
-	__ATTR_NULL
-};
-
 static const struct dev_pm_ops xenbus_pm_ops = {
 	.suspend	= xenbus_dev_suspend,
 	.resume		= xenbus_dev_resume,
@@ -106,7 +102,7 @@ static struct xen_bus_type xenbus_frontend = {
 		.probe		= xenbus_dev_probe,
 		.remove		= xenbus_dev_remove,
 		.shutdown	= xenbus_dev_shutdown,
-		.dev_attrs	= xenbus_frontend_dev_attrs,
+		.dev_attrs	= xenbus_dev_attrs,
 
 		.pm		= &xenbus_pm_ops,
 	},
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 2/2] xen: Add alias to autoload backend drivers
From: Bastian Blank @ 2011-06-24 21:51 UTC (permalink / raw)
  To: xen-devel, virtualization; +Cc: linux-kernel

All the Xen backend drivers are assigned to a special bus type
xen-backend. This allows userspace to load the modules on request.

This patch defines xen-backend:* aliases on the modules and exports this
names through modalias and uevent.

Signed-off-by: Bastian Blank <waldi@debian.org>
---
 drivers/block/xen-blkback/blkback.c       |    1 +
 drivers/net/xen-netback/netback.c         |    1 +
 drivers/xen/xenbus/xenbus_probe.c         |    3 ++-
 drivers/xen/xenbus/xenbus_probe_backend.c |    3 +++
 4 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index 5cf2993..ed62008 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -824,3 +824,4 @@ static int __init xen_blkif_init(void)
 module_init(xen_blkif_init);
 
 MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS("xen-backend:vbd");
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 0e4851b..fd00f25 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -1743,3 +1743,4 @@ failed_init:
 module_init(netback_init);
 
 MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS("xen-backend:vif");
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 2ed0b04..bd2f90c 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -393,7 +393,8 @@ static ssize_t devtype_show(struct device *dev,
 static ssize_t modalias_show(struct device *dev,
 			     struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "xen:%s\n", to_xenbus_device(dev)->devicetype);
+	return sprintf(buf, "%s:%s\n", dev->bus->name,
+		       to_xenbus_device(dev)->devicetype);
 }
 
 struct device_attribute xenbus_dev_attrs[] = {
diff --git a/drivers/xen/xenbus/xenbus_probe_backend.c b/drivers/xen/xenbus/xenbus_probe_backend.c
index ec510e5..60adf91 100644
--- a/drivers/xen/xenbus/xenbus_probe_backend.c
+++ b/drivers/xen/xenbus/xenbus_probe_backend.c
@@ -107,6 +107,9 @@ static int xenbus_uevent_backend(struct device *dev,
 	if (xdev == NULL)
 		return -ENODEV;
 
+	if (add_uevent_var(env, "MODALIAS=xen-backend:%s", xdev->devicetype))
+		return -ENOMEM;
+
 	/* stuff we want to pass to /sbin/hotplug */
 	if (add_uevent_var(env, "XENBUS_TYPE=%s", xdev->devicetype))
 		return -ENOMEM;
-- 
1.7.5.4

^ permalink raw reply related

* Re: RFT: virtio_net: limit xmit polling
From: Roopa Prabhu @ 2011-06-25 19:44 UTC (permalink / raw)
  To: Roopa Prabhu, Tom Lendacky, Michael S. Tsirkin
  Cc: Krishna Kumar2, habanero, lguest, Shirley Ma, kvm, Carsten Otte,
	linux-s390, Heiko Carstens, linux-kernel, virtualization, steved,
	Christian Borntraeger, netdev, Martin Schwidefsky, linux390
In-Reply-To: <CA29D629.2C9B1%roprabhu@cisco.com>


[-- Attachment #1.1: Type: text/plain, Size: 3019 bytes --]


Here are the results I am getting with a Cisco 10G VIC adapter.
All tests are from the guest to an external host.

virtio-net-limit-xmit-polling/base:
TCP_STREAM: 8089Mbps
TCP_MAERTS: 9334Mbps

virtio-net-limit-xmit-polling/v0
TCP_STREAM: 8004Mbps
TCP_MAERTS: 9338Mbps

virtio-net-limit-xmit-polling/v1
TCP_STREAM: 8028Mbps
TCP_MAERTS: 9339Mbps

virtio-net-limit-xmit-polling/v2
TCP_STREAM: 8045Mbps
TCP_MAERTS: 9337Mbps

For the TCP_STREAM tests I don¹t get consistent results.
Every run gives me slightly different results. But its always between
7900Mbps to 8100Mbps.
But I also see this with the base kernel so its not related to these
patches. 

Thanks,
Roopa

On 6/24/11 5:50 AM, "Roopa Prabhu" <roprabhu@cisco.com> wrote:

> Michael,  
> 
> I am testing this too.
>  I have finished one round of testing. But am running it again just to
> confirm.
> This time I will see if I can collect some exit stats too. Will post results
> sometime this weekend.
> I am just doing TCP_STREAM and TCP_MAERTS from guest to remote host.
> 
> Thanks,
> Roopa
> 
> 
> On 6/21/11 8:23 AM, "Tom Lendacky" <tahm@linux.vnet.ibm.com> wrote:
> 
>> On Sunday, June 19, 2011 05:27:00 AM Michael S. Tsirkin wrote:
>>> > OK, different people seem to test different trees.  In the hope to get
>>> > everyone on the same page, I created several variants of this patch so
>>> > they can be compared. Whoever's interested, please check out the
>>> > following, and tell me how these compare:
>> 
>> I'm in the process of testing these patches.  Base and v0 are complete
>> and v1 is near complete with v2 to follow.  I'm testing with a variety
>> of TCP_RR and TCP_STREAM/TCP_MAERTS tests involving local guest-to-guest
>> tests and remote host-to-guest tests.  I'll post the results in the next
>> day or two when the tests finish.
>> 
>> Thanks,
>> Tom
>> 
>>> >
>>> > kernel:
>>> >
>>> > git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git
>>> >
>>> > virtio-net-limit-xmit-polling/base - this is net-next baseline to test
>>> > against virtio-net-limit-xmit-polling/v0 - fixes checks on out of capacity
>>> > virtio-net-limit-xmit-polling/v1 - previous revision of the patch
>>> >               this does xmit,free,xmit,2*free,free
>>> > virtio-net-limit-xmit-polling/v2 - new revision of the patch
>>> >               this does free,xmit,2*free,free
>>> >
>>> > There's also this on top:
>>> > virtio-net-limit-xmit-polling/v3 -> don't delay avail index update
>>> > I don't think it's important to test this one, yet
>>> >
>>> > Userspace to use: event index work is not yet merged upstream
>>> > so the revision to use is still this:
>>> > git://git.kernel.org/pub/scm/linux/kernel/git/mst/qemu-kvm.git
>>> > virtio-net-event-idx-v3
>> 
> 
> 
> _______________________________________________
> Virtualization mailing list
> Virtualization@lists.linux-foundation.org
> https://lists.linux-foundation.org/mailman/listinfo/virtualization


[-- Attachment #1.2: Type: text/html, Size: 4335 bytes --]

[-- Attachment #2: Type: text/plain, Size: 184 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox