virtio-net: support changing the number of queue pairs through ethtool
authorJason Wang <jasowang@redhat.com>
Fri, 7 Dec 2012 07:04:57 +0000 (07:04 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sun, 9 Dec 2012 05:30:55 +0000 (00:30 -0500)
This patch implements the ethtool_{set|get}_channels method of virtio-net to
allow user to change the number of queues when the device is running on demand.

Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/virtio_net.c

index c0830488a3902af71bf965b50996923397e33156..a644eebb31d84c8d4f7fefd05f6e4934ea423343 100644 (file)
@@ -1075,10 +1075,53 @@ static void virtnet_get_drvinfo(struct net_device *dev,
 
 }
 
+/* TODO: Eliminate OOO packets during switching */
+static int virtnet_set_channels(struct net_device *dev,
+                               struct ethtool_channels *channels)
+{
+       struct virtnet_info *vi = netdev_priv(dev);
+       u16 queue_pairs = channels->combined_count;
+       int err;
+
+       /* We don't support separate rx/tx channels.
+        * We don't allow setting 'other' channels.
+        */
+       if (channels->rx_count || channels->tx_count || channels->other_count)
+               return -EINVAL;
+
+       if (queue_pairs > vi->max_queue_pairs)
+               return -EINVAL;
+
+       err = virtnet_set_queues(vi, queue_pairs);
+       if (!err) {
+               netif_set_real_num_tx_queues(dev, queue_pairs);
+               netif_set_real_num_rx_queues(dev, queue_pairs);
+
+               virtnet_set_affinity(vi, true);
+       }
+
+       return err;
+}
+
+static void virtnet_get_channels(struct net_device *dev,
+                                struct ethtool_channels *channels)
+{
+       struct virtnet_info *vi = netdev_priv(dev);
+
+       channels->combined_count = vi->curr_queue_pairs;
+       channels->max_combined = vi->max_queue_pairs;
+       channels->max_other = 0;
+       channels->rx_count = 0;
+       channels->tx_count = 0;
+       channels->other_count = 0;
+}
+
 static const struct ethtool_ops virtnet_ethtool_ops = {
        .get_drvinfo = virtnet_get_drvinfo,
        .get_link = ethtool_op_get_link,
        .get_ringparam = virtnet_get_ringparam,
+       .set_channels = virtnet_set_channels,
+       .get_channels = virtnet_get_channels,
 };
 
 #define MIN_MTU 68