Re: [net-next RFC V5 4/5] virtio_net: multiqueue support

2012-07-30 Thread Sasha Levin
On 07/29/2012 11:44 AM, Michael S. Tsirkin wrote:
 On Sat, Jul 21, 2012 at 02:02:58PM +0200, Sasha Levin wrote:
 On 07/20/2012 03:40 PM, Michael S. Tsirkin wrote:
 -  err = init_vqs(vi);
 + if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ))
 + vi-has_cvq = true;
 +
 How about we disable multiqueue if there's no cvq?
 Will make logic a bit simpler, won't it?

 multiqueues don't really depend on cvq. Does this added complexity really 
 justifies adding an artificial limit?
 
 Well !cvq support is a legacy feature: the reason we support it
 in driver is to avoid breaking on old hosts. Adding more code to that
 path just doesn't make much sense since old hosts won't have mq.

Is it really a legacy feature? The spec suggests that its an optional queue 
which is not necessary for the operation of the device.

Which is why we never implemented it in lkvm - we weren't interested in any of 
the features it provided at that time and we could provide high performance 
with vhost support even without it.
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [net-next RFC V5 4/5] virtio_net: multiqueue support

2012-07-29 Thread Michael S. Tsirkin
On Sat, Jul 21, 2012 at 02:02:58PM +0200, Sasha Levin wrote:
 On 07/20/2012 03:40 PM, Michael S. Tsirkin wrote:
  -  err = init_vqs(vi);
   +if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ))
   +vi-has_cvq = true;
   +
  How about we disable multiqueue if there's no cvq?
  Will make logic a bit simpler, won't it?
 
 multiqueues don't really depend on cvq. Does this added complexity really 
 justifies adding an artificial limit?

Well !cvq support is a legacy feature: the reason we support it
in driver is to avoid breaking on old hosts. Adding more code to that
path just doesn't make much sense since old hosts won't have mq.

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


Re: [net-next RFC V5 4/5] virtio_net: multiqueue support

2012-07-29 Thread Michael S. Tsirkin
On Mon, Jul 23, 2012 at 01:48:35PM +0800, Jason Wang wrote:
 +   }
 
 -   if (virtio_has_feature(vi-vdev, VIRTIO_NET_F_CTRL_VQ)) {
 +   ret = vi-vdev-config-find_vqs(vi-vdev, total_vqs, vqs, callbacks,
 +(const char **)names);
 +   if (ret)
 +   goto err;
 +
 +   if (vi-has_cvq)
 vi-cvq = vqs[2];
 
 -   if (virtio_has_feature(vi-vdev, VIRTIO_NET_F_CTRL_VLAN))
 -   vi-dev-features |= NETIF_F_HW_VLAN_FILTER;
 +   for (i = 0; i  vi-num_queue_pairs * 2; i += 2) {
 +   int j = i == 0 ? i : i + vi-has_cvq;
 +   vi-rq[i / 2]-vq = vqs[j];
 +   vi-sq[i / 2]-vq = vqs[j + 1];
 Same here.
 
 Consider the code is really simple, seem no need to use helpers.

Well it was not simple to at least one reader :)
The problem is not this logic is complex,
it is that it is spread all over the code.

If we had e.g. vnet_tx_vqn_to_queuenum vnet_tx_queuenum_to_vqn
and same for rx, then the logic would all be
in one place, and have a tidy comment on top explaining
the VQ numbering scheme.

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


Re: [net-next RFC V5 4/5] virtio_net: multiqueue support

2012-07-29 Thread Jason Wang

On 07/29/2012 05:44 PM, Michael S. Tsirkin wrote:

On Sat, Jul 21, 2012 at 02:02:58PM +0200, Sasha Levin wrote:

On 07/20/2012 03:40 PM, Michael S. Tsirkin wrote:

-   err = init_vqs(vi);

+   if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ))
+   vi-has_cvq = true;
+

How about we disable multiqueue if there's no cvq?
Will make logic a bit simpler, won't it?

multiqueues don't really depend on cvq. Does this added complexity really 
justifies adding an artificial limit?

Well !cvq support is a legacy feature: the reason we support it
in driver is to avoid breaking on old hosts. Adding more code to that
path just doesn't make much sense since old hosts won't have mq.



After some thought about this, maybe there's no need to the cvq for the 
negotiation if we want support only two modes ( 1 tx/rx queue pair and N 
tx/rx queue pairs). We can do this just through the feature bit negotiation.

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


Re: [net-next RFC V5 4/5] virtio_net: multiqueue support

2012-07-29 Thread Jason Wang

On 07/23/2012 05:28 PM, Sasha Levin wrote:

On 07/23/2012 07:54 AM, Jason Wang wrote:

On 07/21/2012 08:02 PM, Sasha Levin wrote:

On 07/20/2012 03:40 PM, Michael S. Tsirkin wrote:

-err = init_vqs(vi);

+if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ))
+vi-has_cvq = true;
+

How about we disable multiqueue if there's no cvq?
Will make logic a bit simpler, won't it?

multiqueues don't really depend on cvq. Does this added complexity really 
justifies adding an artificial limit?


Yes, it does not depends on cvq. Cvq were just used to negotiate the number of 
queues a guest wishes to use which is really useful (at least for now). Since 
multiqueue can not out-perform for single queue in every kinds of workloads or 
benchmark, so we want to let guest driver use single queue by default even when 
multiqueue were enabled by management software and let use to enalbe it through 
ethtool. So user could not feel regression when it switch to use a multiqueue 
capable driver and backend.

Why would you limit it to a single vq if the user has specified a different number 
of vqs (1) in the virtio-net device config?
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


The only reason is to prevent the user from seeing the regression. The 
performance of small packet sending is wrose than single queue, it tends 
to send more but small packets when multiqueue is enabled. If we make 
multiqueue bahave as good as single queue, we can remove this limit.


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


Re: [net-next RFC V5 4/5] virtio_net: multiqueue support

2012-07-23 Thread Sasha Levin
On 07/23/2012 07:54 AM, Jason Wang wrote:
 On 07/21/2012 08:02 PM, Sasha Levin wrote:
 On 07/20/2012 03:40 PM, Michael S. Tsirkin wrote:
 -err = init_vqs(vi);
 +if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ))
 +vi-has_cvq = true;
 +
 How about we disable multiqueue if there's no cvq?
 Will make logic a bit simpler, won't it?
 multiqueues don't really depend on cvq. Does this added complexity really 
 justifies adding an artificial limit?

 
 Yes, it does not depends on cvq. Cvq were just used to negotiate the number 
 of queues a guest wishes to use which is really useful (at least for now). 
 Since multiqueue can not out-perform for single queue in every kinds of 
 workloads or benchmark, so we want to let guest driver use single queue by 
 default even when multiqueue were enabled by management software and let use 
 to enalbe it through ethtool. So user could not feel regression when it 
 switch to use a multiqueue capable driver and backend.

Why would you limit it to a single vq if the user has specified a different 
number of vqs (1) in the virtio-net device config?
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [net-next RFC V5 4/5] virtio_net: multiqueue support

2012-07-22 Thread Jason Wang

On 07/20/2012 09:40 PM, Michael S. Tsirkin wrote:

On Thu, Jul 05, 2012 at 06:29:53PM +0800, Jason Wang wrote:

This patch converts virtio_net to a multi queue device. After negotiated
VIRTIO_NET_F_MULTIQUEUE feature, the virtio device has many tx/rx queue pairs,
and driver could read the number from config space.

The driver expects the number of rx/tx queue paris is equal to the number of
vcpus. To maximize the performance under this per-cpu rx/tx queue pairs, some
optimization were introduced:

- Txq selection is based on the processor id in order to avoid contending a lock
   whose owner may exits to host.
- Since the txq/txq were per-cpu, affinity hint were set to the cpu that owns
   the queue pairs.

Signed-off-by: Krishna Kumarkrkum...@in.ibm.com
Signed-off-by: Jason Wangjasow...@redhat.com

Overall fine. I think it is best to smash the following patch
into this one, so that default behavior does not
jump to mq then back. some comments below: mostly nits, and a minor bug.


Sure, thanks for the reviewing.


If you are worried the patch is too big, it can be split
differently
- rework to use send_queue/receive_queue structures, no
  functional changes.
- add multiqueue

but this is not a must.


---
  drivers/net/virtio_net.c   |  645 ++-
  include/linux/virtio_net.h |2 +
  2 files changed, 452 insertions(+), 195 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 1db445b..7410187 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -26,6 +26,7 @@
  #includelinux/scatterlist.h
  #includelinux/if_vlan.h
  #includelinux/slab.h
+#includelinux/interrupt.h

  static int napi_weight = 128;
  module_param(napi_weight, int, 0444);
@@ -41,6 +42,8 @@ module_param(gso, bool, 0444);
  #define VIRTNET_SEND_COMMAND_SG_MAX2
  #define VIRTNET_DRIVER_VERSION 1.0.0

+#define MAX_QUEUES 256
+
  struct virtnet_stats {
struct u64_stats_sync tx_syncp;
struct u64_stats_sync rx_syncp;

Would be a bit better not to have artificial limits like that.
Maybe allocate arrays at probe time, then we can
take whatever the device gives us?


Sure.

@@ -51,43 +54,69 @@ struct virtnet_stats {
u64 rx_packets;
  };

-struct virtnet_info {
-   struct virtio_device *vdev;
-   struct virtqueue *rvq, *svq, *cvq;
-   struct net_device *dev;
+/* Internal representation of a send virtqueue */
+struct send_queue {
+   /* Virtqueue associated with this send _queue */
+   struct virtqueue *vq;
+
+   /* TX: fragments + linear part + virtio header */
+   struct scatterlist sg[MAX_SKB_FRAGS + 2];
+};
+
+/* Internal representation of a receive virtqueue */
+struct receive_queue {
+   /* Virtqueue associated with this receive_queue */
+   struct virtqueue *vq;
+
+   /* Back pointer to the virtnet_info */
+   struct virtnet_info *vi;
+
struct napi_struct napi;
-   unsigned int status;

/* Number of input buffers, and max we've ever had. */
unsigned int num, max;

+   /* Work struct for refilling if we run low on memory. */
+   struct delayed_work refill;
+
+   /* Chain pages by the private ptr. */
+   struct page *pages;
+
+   /* RX: fragments + linear part + virtio header */
+   struct scatterlist sg[MAX_SKB_FRAGS + 2];
+};
+
+struct virtnet_info {
+   u16 num_queue_pairs;/* # of RX/TX vq pairs */
+
+   struct send_queue *sq[MAX_QUEUES] cacheline_aligned_in_smp;
+   struct receive_queue *rq[MAX_QUEUES] cacheline_aligned_in_smp;

The assumption is a tx/rx pair is handled on the same cpu, yes?
If yes maybe make it a single array to improve cache locality
a bit?
struct queue_pair {
struct send_queue sq;
struct receive_queue rq;
};


Ok.

+   struct virtqueue *cvq;
+
+   struct virtio_device *vdev;
+   struct net_device *dev;
+   unsigned int status;
+
/* I like... big packets and I cannot lie! */
bool big_packets;

/* Host will merge rx buffers for big packets (shake it! shake it!) */
bool mergeable_rx_bufs;

+   /* Has control virtqueue */
+   bool has_cvq;
+

won't checking (cvq != NULL) be enough?


Enough, so has_cvq is dupliated with vi-cvq. I will remove it in next 
version.



/* enable config space updates */
bool config_enable;

/* Active statistics */
struct virtnet_stats __percpu *stats;

-   /* Work struct for refilling if we run low on memory. */
-   struct delayed_work refill;
-
/* Work struct for config space updates */
struct work_struct config_work;

/* Lock for config space updates */
struct mutex config_lock;
-
-   /* Chain pages by the private ptr. */
-   struct page *pages;
-
-   /* fragments + linear part + virtio header */
-   struct scatterlist rx_sg[MAX_SKB_FRAGS + 2];

Re: [net-next RFC V5 4/5] virtio_net: multiqueue support

2012-07-22 Thread Jason Wang

On 07/21/2012 08:02 PM, Sasha Levin wrote:

On 07/20/2012 03:40 PM, Michael S. Tsirkin wrote:

-   err = init_vqs(vi);

+   if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ))
+   vi-has_cvq = true;
+

How about we disable multiqueue if there's no cvq?
Will make logic a bit simpler, won't it?

multiqueues don't really depend on cvq. Does this added complexity really 
justifies adding an artificial limit?



Yes, it does not depends on cvq. Cvq were just used to negotiate the 
number of queues a guest wishes to use which is really useful (at least 
for now). Since multiqueue can not out-perform for single queue in every 
kinds of workloads or benchmark, so we want to let guest driver use 
single queue by default even when multiqueue were enabled by management 
software and let use to enalbe it through ethtool. So user could not 
feel regression when it switch to use a multiqueue capable driver and 
backend.


So the only difference is the user experiences.

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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


Re: [net-next RFC V5 4/5] virtio_net: multiqueue support

2012-07-21 Thread Sasha Levin
On 07/20/2012 03:40 PM, Michael S. Tsirkin wrote:
 -err = init_vqs(vi);
  +  if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ))
  +  vi-has_cvq = true;
  +
 How about we disable multiqueue if there's no cvq?
 Will make logic a bit simpler, won't it?

multiqueues don't really depend on cvq. Does this added complexity really 
justifies adding an artificial limit?


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


Re: [net-next RFC V5 4/5] virtio_net: multiqueue support

2012-07-20 Thread Michael S. Tsirkin
On Thu, Jul 05, 2012 at 06:29:53PM +0800, Jason Wang wrote:
 This patch converts virtio_net to a multi queue device. After negotiated
 VIRTIO_NET_F_MULTIQUEUE feature, the virtio device has many tx/rx queue pairs,
 and driver could read the number from config space.
 
 The driver expects the number of rx/tx queue paris is equal to the number of
 vcpus. To maximize the performance under this per-cpu rx/tx queue pairs, some
 optimization were introduced:
 
 - Txq selection is based on the processor id in order to avoid contending a 
 lock
   whose owner may exits to host.
 - Since the txq/txq were per-cpu, affinity hint were set to the cpu that owns
   the queue pairs.
 
 Signed-off-by: Krishna Kumar krkum...@in.ibm.com
 Signed-off-by: Jason Wang jasow...@redhat.com

Overall fine. I think it is best to smash the following patch
into this one, so that default behavior does not
jump to mq then back. some comments below: mostly nits, and a minor bug.

If you are worried the patch is too big, it can be split
differently
- rework to use send_queue/receive_queue structures, no
  functional changes.
- add multiqueue

but this is not a must.

 ---
  drivers/net/virtio_net.c   |  645 ++-
  include/linux/virtio_net.h |2 +
  2 files changed, 452 insertions(+), 195 deletions(-)
 
 diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
 index 1db445b..7410187 100644
 --- a/drivers/net/virtio_net.c
 +++ b/drivers/net/virtio_net.c
 @@ -26,6 +26,7 @@
  #include linux/scatterlist.h
  #include linux/if_vlan.h
  #include linux/slab.h
 +#include linux/interrupt.h
  
  static int napi_weight = 128;
  module_param(napi_weight, int, 0444);
 @@ -41,6 +42,8 @@ module_param(gso, bool, 0444);
  #define VIRTNET_SEND_COMMAND_SG_MAX2
  #define VIRTNET_DRIVER_VERSION 1.0.0
  
 +#define MAX_QUEUES 256
 +
  struct virtnet_stats {
   struct u64_stats_sync tx_syncp;
   struct u64_stats_sync rx_syncp;

Would be a bit better not to have artificial limits like that.
Maybe allocate arrays at probe time, then we can
take whatever the device gives us?

 @@ -51,43 +54,69 @@ struct virtnet_stats {
   u64 rx_packets;
  };
  
 -struct virtnet_info {
 - struct virtio_device *vdev;
 - struct virtqueue *rvq, *svq, *cvq;
 - struct net_device *dev;
 +/* Internal representation of a send virtqueue */
 +struct send_queue {
 + /* Virtqueue associated with this send _queue */
 + struct virtqueue *vq;
 +
 + /* TX: fragments + linear part + virtio header */
 + struct scatterlist sg[MAX_SKB_FRAGS + 2];
 +};
 +
 +/* Internal representation of a receive virtqueue */
 +struct receive_queue {
 + /* Virtqueue associated with this receive_queue */
 + struct virtqueue *vq;
 +
 + /* Back pointer to the virtnet_info */
 + struct virtnet_info *vi;
 +
   struct napi_struct napi;
 - unsigned int status;
  
   /* Number of input buffers, and max we've ever had. */
   unsigned int num, max;
  
 + /* Work struct for refilling if we run low on memory. */
 + struct delayed_work refill;
 +
 + /* Chain pages by the private ptr. */
 + struct page *pages;
 +
 + /* RX: fragments + linear part + virtio header */
 + struct scatterlist sg[MAX_SKB_FRAGS + 2];
 +};
 +
 +struct virtnet_info {
 + u16 num_queue_pairs;/* # of RX/TX vq pairs */
 +
 + struct send_queue *sq[MAX_QUEUES] cacheline_aligned_in_smp;
 + struct receive_queue *rq[MAX_QUEUES] cacheline_aligned_in_smp;

The assumption is a tx/rx pair is handled on the same cpu, yes?
If yes maybe make it a single array to improve cache locality
a bit?
struct queue_pair {
struct send_queue sq;
struct receive_queue rq;
};

 + struct virtqueue *cvq;
 +
 + struct virtio_device *vdev;
 + struct net_device *dev;
 + unsigned int status;
 +
   /* I like... big packets and I cannot lie! */
   bool big_packets;
  
   /* Host will merge rx buffers for big packets (shake it! shake it!) */
   bool mergeable_rx_bufs;
  
 + /* Has control virtqueue */
 + bool has_cvq;
 +

won't checking (cvq != NULL) be enough?

   /* enable config space updates */
   bool config_enable;
  
   /* Active statistics */
   struct virtnet_stats __percpu *stats;
  
 - /* Work struct for refilling if we run low on memory. */
 - struct delayed_work refill;
 -
   /* Work struct for config space updates */
   struct work_struct config_work;
  
   /* Lock for config space updates */
   struct mutex config_lock;
 -
 - /* Chain pages by the private ptr. */
 - struct page *pages;
 -
 - /* fragments + linear part + virtio header */
 - struct scatterlist rx_sg[MAX_SKB_FRAGS + 2];
 - struct scatterlist tx_sg[MAX_SKB_FRAGS + 2];
  };
  
  struct skb_vnet_hdr {
 @@ -108,6 +137,22 @@ struct padded_vnet_hdr {
   char padding[6];
  };
  

Re: [net-next RFC V5 4/5] virtio_net: multiqueue support

2012-07-06 Thread Jason Wang

On 07/06/2012 04:02 AM, Amos Kong wrote:

On 07/05/2012 06:29 PM, Jason Wang wrote:

This patch converts virtio_net to a multi queue device. After negotiated
VIRTIO_NET_F_MULTIQUEUE feature, the virtio device has many tx/rx queue pairs,
and driver could read the number from config space.

The driver expects the number of rx/tx queue paris is equal to the number of
vcpus. To maximize the performance under this per-cpu rx/tx queue pairs, some
optimization were introduced:

- Txq selection is based on the processor id in order to avoid contending a lock
   whose owner may exits to host.
- Since the txq/txq were per-cpu, affinity hint were set to the cpu that owns
   the queue pairs.

Signed-off-by: Krishna Kumarkrkum...@in.ibm.com
Signed-off-by: Jason Wangjasow...@redhat.com
---

...



  static int virtnet_probe(struct virtio_device *vdev)
  {
-   int err;
+   int i, err;
struct net_device *dev;
struct virtnet_info *vi;
+   u16 num_queues, num_queue_pairs;
+
+   /* Find if host supports multiqueue virtio_net device */
+   err = virtio_config_val(vdev, VIRTIO_NET_F_MULTIQUEUE,
+   offsetof(struct virtio_net_config,
+   num_queues),num_queues);
+
+   /* We need atleast 2 queue's */


s/atleast/at least/



+   if (err || num_queues  2)
+   num_queues = 2;
+   if (num_queues  MAX_QUEUES * 2)
+   num_queues = MAX_QUEUES;

 num_queues = MAX_QUEUES * 2;

MAX_QUEUES is the limitation of RX or TX.


Right, it's a typo, thanks.

+
+   num_queue_pairs = num_queues / 2;

...



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


Re: [net-next RFC V5 4/5] virtio_net: multiqueue support

2012-07-05 Thread Amos Kong
On 07/05/2012 06:29 PM, Jason Wang wrote:
 This patch converts virtio_net to a multi queue device. After negotiated
 VIRTIO_NET_F_MULTIQUEUE feature, the virtio device has many tx/rx queue pairs,
 and driver could read the number from config space.
 
 The driver expects the number of rx/tx queue paris is equal to the number of
 vcpus. To maximize the performance under this per-cpu rx/tx queue pairs, some
 optimization were introduced:
 
 - Txq selection is based on the processor id in order to avoid contending a 
 lock
   whose owner may exits to host.
 - Since the txq/txq were per-cpu, affinity hint were set to the cpu that owns
   the queue pairs.
 
 Signed-off-by: Krishna Kumar krkum...@in.ibm.com
 Signed-off-by: Jason Wang jasow...@redhat.com
 ---

...

  
  static int virtnet_probe(struct virtio_device *vdev)
  {
 - int err;
 + int i, err;
   struct net_device *dev;
   struct virtnet_info *vi;
 + u16 num_queues, num_queue_pairs;
 +
 + /* Find if host supports multiqueue virtio_net device */
 + err = virtio_config_val(vdev, VIRTIO_NET_F_MULTIQUEUE,
 + offsetof(struct virtio_net_config,
 + num_queues), num_queues);
 +
 + /* We need atleast 2 queue's */


s/atleast/at least/


 + if (err || num_queues  2)
 + num_queues = 2;
 + if (num_queues  MAX_QUEUES * 2)
 + num_queues = MAX_QUEUES;

num_queues = MAX_QUEUES * 2;

MAX_QUEUES is the limitation of RX or TX.

 +
 + num_queue_pairs = num_queues / 2;

...

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