diff options
author | Jason Wang <jasowang@redhat.com> | 2012-12-07 02:04:57 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-12-09 00:30:55 -0500 |
commit | d73bcd2c28e3c77d9f52d42a45a52455488e287e (patch) | |
tree | 38c315252ce27702680807107619d0aad2e60129 | |
parent | 986a4f4d452dec004697f667439d27c3fda9c928 (diff) |
virtio-net: support changing the number of queue pairs through ethtool
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>
-rw-r--r-- | drivers/net/virtio_net.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index c0830488a39..a644eebb31d 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -1075,10 +1075,53 @@ static void virtnet_get_drvinfo(struct net_device *dev, | |||
1075 | 1075 | ||
1076 | } | 1076 | } |
1077 | 1077 | ||
1078 | /* TODO: Eliminate OOO packets during switching */ | ||
1079 | static int virtnet_set_channels(struct net_device *dev, | ||
1080 | struct ethtool_channels *channels) | ||
1081 | { | ||
1082 | struct virtnet_info *vi = netdev_priv(dev); | ||
1083 | u16 queue_pairs = channels->combined_count; | ||
1084 | int err; | ||
1085 | |||
1086 | /* We don't support separate rx/tx channels. | ||
1087 | * We don't allow setting 'other' channels. | ||
1088 | */ | ||
1089 | if (channels->rx_count || channels->tx_count || channels->other_count) | ||
1090 | return -EINVAL; | ||
1091 | |||
1092 | if (queue_pairs > vi->max_queue_pairs) | ||
1093 | return -EINVAL; | ||
1094 | |||
1095 | err = virtnet_set_queues(vi, queue_pairs); | ||
1096 | if (!err) { | ||
1097 | netif_set_real_num_tx_queues(dev, queue_pairs); | ||
1098 | netif_set_real_num_rx_queues(dev, queue_pairs); | ||
1099 | |||
1100 | virtnet_set_affinity(vi, true); | ||
1101 | } | ||
1102 | |||
1103 | return err; | ||
1104 | } | ||
1105 | |||
1106 | static void virtnet_get_channels(struct net_device *dev, | ||
1107 | struct ethtool_channels *channels) | ||
1108 | { | ||
1109 | struct virtnet_info *vi = netdev_priv(dev); | ||
1110 | |||
1111 | channels->combined_count = vi->curr_queue_pairs; | ||
1112 | channels->max_combined = vi->max_queue_pairs; | ||
1113 | channels->max_other = 0; | ||
1114 | channels->rx_count = 0; | ||
1115 | channels->tx_count = 0; | ||
1116 | channels->other_count = 0; | ||
1117 | } | ||
1118 | |||
1078 | static const struct ethtool_ops virtnet_ethtool_ops = { | 1119 | static const struct ethtool_ops virtnet_ethtool_ops = { |
1079 | .get_drvinfo = virtnet_get_drvinfo, | 1120 | .get_drvinfo = virtnet_get_drvinfo, |
1080 | .get_link = ethtool_op_get_link, | 1121 | .get_link = ethtool_op_get_link, |
1081 | .get_ringparam = virtnet_get_ringparam, | 1122 | .get_ringparam = virtnet_get_ringparam, |
1123 | .set_channels = virtnet_set_channels, | ||
1124 | .get_channels = virtnet_get_channels, | ||
1082 | }; | 1125 | }; |
1083 | 1126 | ||
1084 | #define MIN_MTU 68 | 1127 | #define MIN_MTU 68 |