All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 1/2] hv_netvsc: Set vRSS with num_chn in RNDIS filter
@ 2015-08-12  0:14 Andrew Schwartzmeyer
  2015-08-12  0:14 ` [PATCH net-next 2/2] hv_netvsc: Implement set_channels ethtool op Andrew Schwartzmeyer
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Andrew Schwartzmeyer @ 2015-08-12  0:14 UTC (permalink / raw)
  To: haiyangz; +Cc: kys, andschwa, netdev, linux-kernel

Uses device_info->num_chn to pass user provided number of vRSS
queues (from ethtool --set-channels) to rndis_filter_device_add. If
nonzero and less than the maximum, set net_device->num_chn to the given
value; else default to prior algorithm.

Always initialize struct device_info to 0, otherwise not all its fields
are guaranteed to be 0, which is necessary when checking if num_chn has
been purposefully set.

Signed-off-by: Andrew Schwartzmeyer <andschwa@microsoft.com>
---
 drivers/net/hyperv/hyperv_net.h   | 1 +
 drivers/net/hyperv/netvsc_drv.c   | 3 +++
 drivers/net/hyperv/rndis_filter.c | 7 ++++++-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 5ce7020ca530..5fa98f599b3d 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -162,6 +162,7 @@ struct netvsc_device_info {
 	bool link_state;	/* 0 - link up, 1 - link down */
 	int  ring_size;
 	u32  max_num_vrss_chns;
+	u32  num_chn;
 };
 
 enum rndis_device_state {
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 7b36d5fecc1f..21845202a52d 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -799,6 +799,8 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
 
 	ndevctx->device_ctx = hdev;
 	hv_set_drvdata(hdev, ndev);
+
+	memset(&device_info, 0, sizeof(device_info));
 	device_info.ring_size = ring_size;
 	device_info.max_num_vrss_chns = max_num_vrss_chns;
 	rndis_filter_device_add(hdev, &device_info);
@@ -1022,6 +1024,7 @@ static int netvsc_probe(struct hv_device *dev,
 	net->needed_headroom = max_needed_headroom;
 
 	/* Notify the netvsc driver of the new device */
+	memset(&device_info, 0, sizeof(device_info));
 	device_info.ring_size = ring_size;
 	device_info.max_num_vrss_chns = max_num_vrss_chns;
 	ret = rndis_filter_device_add(dev, &device_info);
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 9b8263db49cc..5931a799aa17 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -1125,7 +1125,12 @@ int rndis_filter_device_add(struct hv_device *dev,
 	 */
 	node_cpu_mask = cpumask_of_node(cpu_to_node(dev->channel->target_cpu));
 	num_possible_rss_qs = cpumask_weight(node_cpu_mask);
-	net_device->num_chn = min(num_possible_rss_qs, num_rss_qs);
+
+	/* We will use the given number of channels if available. */
+	if (device_info->num_chn && device_info->num_chn < net_device->max_chn)
+		net_device->num_chn = device_info->num_chn;
+	else
+		net_device->num_chn = min(num_possible_rss_qs, num_rss_qs);
 
 	num_rss_qs = net_device->num_chn - 1;
 	net_device->num_sc_offered = num_rss_qs;
-- 
2.4.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH net-next 2/2] hv_netvsc: Implement set_channels ethtool op
  2015-08-12  0:14 [PATCH net-next 1/2] hv_netvsc: Set vRSS with num_chn in RNDIS filter Andrew Schwartzmeyer
@ 2015-08-12  0:14 ` Andrew Schwartzmeyer
  2015-08-12 19:05   ` Haiyang Zhang
  2015-08-12 21:45   ` David Miller
  2015-08-12 19:05 ` [PATCH net-next 1/2] hv_netvsc: Set vRSS with num_chn in RNDIS filter Haiyang Zhang
  2015-08-12 21:45 ` David Miller
  2 siblings, 2 replies; 6+ messages in thread
From: Andrew Schwartzmeyer @ 2015-08-12  0:14 UTC (permalink / raw)
  To: haiyangz; +Cc: kys, andschwa, netdev, linux-kernel

This enables the use of ethtool --set-channels devname combined N to
change the number of vRSS queues. Separate rx, tx, and other parameters
are not supported. The maximum is rsscap.num_recv_que. It passes the
given value to rndis_filter_device_add through the device_info->num_chn
field.

If the procedure fails, it attempts to recover to the prior state. If
the recovery fails, it logs an error and aborts.

Current num_chn is saved and restored when changing the MTU.

Signed-off-by: Andrew Schwartzmeyer <andschwa@microsoft.com>
---
 drivers/net/hyperv/netvsc_drv.c | 97 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 21845202a52d..f3b9d3eb753b 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -770,6 +770,101 @@ static void netvsc_get_channels(struct net_device *net,
 	}
 }
 
+static int netvsc_set_channels(struct net_device *net,
+			       struct ethtool_channels *channels)
+{
+	struct net_device_context *net_device_ctx = netdev_priv(net);
+	struct hv_device *dev = net_device_ctx->device_ctx;
+	struct netvsc_device *nvdev = hv_get_drvdata(dev);
+	struct netvsc_device_info device_info;
+	const u32 num_chn = nvdev->num_chn;
+	const u32 max_chn = min_t(u32, nvdev->max_chn, num_online_cpus());
+	int ret = 0;
+	bool recovering = false;
+
+	if (!nvdev || nvdev->destroy)
+		return -ENODEV;
+
+	if (nvdev->nvsp_version < NVSP_PROTOCOL_VERSION_5) {
+		pr_info("vRSS unsupported before NVSP Version 5\n");
+		return -EINVAL;
+	}
+
+	/* We do not support rx, tx, or other */
+	if (!channels ||
+	    channels->rx_count ||
+	    channels->tx_count ||
+	    channels->other_count ||
+	    (channels->combined_count < 1))
+		return -EINVAL;
+
+	if (channels->combined_count > max_chn) {
+		pr_info("combined channels too high, using %d\n", max_chn);
+		channels->combined_count = max_chn;
+	}
+
+	ret = netvsc_close(net);
+	if (ret)
+		goto out;
+
+ do_set:
+	nvdev->start_remove = true;
+	rndis_filter_device_remove(dev);
+
+	nvdev->num_chn = channels->combined_count;
+
+	net_device_ctx->device_ctx = dev;
+	hv_set_drvdata(dev, net);
+
+	memset(&device_info, 0, sizeof(device_info));
+	device_info.num_chn = nvdev->num_chn; /* passed to RNDIS */
+	device_info.ring_size = ring_size;
+	device_info.max_num_vrss_chns = max_num_vrss_chns;
+
+	ret = rndis_filter_device_add(dev, &device_info);
+	if (ret) {
+		if (recovering) {
+			netdev_err(net, "unable to add netvsc device (ret %d)\n", ret);
+			return ret;
+		}
+		goto recover;
+	}
+
+	nvdev = hv_get_drvdata(dev);
+
+	ret = netif_set_real_num_tx_queues(net, nvdev->num_chn);
+	if (ret) {
+		if (recovering) {
+			netdev_err(net, "could not set tx queue count (ret %d)\n", ret);
+			return ret;
+		}
+		goto recover;
+	}
+
+	ret = netif_set_real_num_rx_queues(net, nvdev->num_chn);
+	if (ret) {
+		if (recovering) {
+			netdev_err(net, "could not set rx queue count (ret %d)\n", ret);
+			return ret;
+		}
+		goto recover;
+	}
+
+ out:
+	netvsc_open(net);
+
+	return ret;
+
+ recover:
+	/* If the above failed, we attempt to recover through the same
+	 * process but with the original number of channels.
+	 */
+	netdev_err(net, "could not set channels, recovering\n");
+	recovering = true;
+	channels->combined_count = num_chn;
+	goto do_set;
+}
+
 static int netvsc_change_mtu(struct net_device *ndev, int mtu)
 {
 	struct net_device_context *ndevctx = netdev_priv(ndev);
@@ -802,6 +897,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
 
 	memset(&device_info, 0, sizeof(device_info));
 	device_info.ring_size = ring_size;
+	device_info.num_chn = nvdev->num_chn;
 	device_info.max_num_vrss_chns = max_num_vrss_chns;
 	rndis_filter_device_add(hdev, &device_info);
 
@@ -891,6 +987,7 @@ static const struct ethtool_ops ethtool_ops = {
 	.get_drvinfo	= netvsc_get_drvinfo,
 	.get_link	= ethtool_op_get_link,
 	.get_channels   = netvsc_get_channels,
+	.set_channels   = netvsc_set_channels,
 };
 
 static const struct net_device_ops device_ops = {
-- 
2.4.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* RE: [PATCH net-next 1/2] hv_netvsc: Set vRSS with num_chn in RNDIS filter
  2015-08-12  0:14 [PATCH net-next 1/2] hv_netvsc: Set vRSS with num_chn in RNDIS filter Andrew Schwartzmeyer
  2015-08-12  0:14 ` [PATCH net-next 2/2] hv_netvsc: Implement set_channels ethtool op Andrew Schwartzmeyer
@ 2015-08-12 19:05 ` Haiyang Zhang
  2015-08-12 21:45 ` David Miller
  2 siblings, 0 replies; 6+ messages in thread
From: Haiyang Zhang @ 2015-08-12 19:05 UTC (permalink / raw)
  To: Andy Schwartzmeyer; +Cc: KY Srinivasan, netdev, linux-kernel



> -----Original Message-----
> From: Andy Schwartzmeyer
> Sent: Tuesday, August 11, 2015 8:15 PM
> To: Haiyang Zhang <haiyangz@microsoft.com>
> Cc: KY Srinivasan <kys@microsoft.com>; Andy Schwartzmeyer
> <andschwa@microsoft.com>; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org
> Subject: [PATCH net-next 1/2] hv_netvsc: Set vRSS with num_chn in RNDIS
> filter
> 
> Uses device_info->num_chn to pass user provided number of vRSS
> queues (from ethtool --set-channels) to rndis_filter_device_add. If
> nonzero and less than the maximum, set net_device->num_chn to the given
> value; else default to prior algorithm.
> 
> Always initialize struct device_info to 0, otherwise not all its fields
> are guaranteed to be 0, which is necessary when checking if num_chn has
> been purposefully set.
> 
> Signed-off-by: Andrew Schwartzmeyer <andschwa@microsoft.com>

Thank you!

Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [PATCH net-next 2/2] hv_netvsc: Implement set_channels ethtool op
  2015-08-12  0:14 ` [PATCH net-next 2/2] hv_netvsc: Implement set_channels ethtool op Andrew Schwartzmeyer
@ 2015-08-12 19:05   ` Haiyang Zhang
  2015-08-12 21:45   ` David Miller
  1 sibling, 0 replies; 6+ messages in thread
From: Haiyang Zhang @ 2015-08-12 19:05 UTC (permalink / raw)
  To: Andy Schwartzmeyer; +Cc: KY Srinivasan, netdev, linux-kernel



> -----Original Message-----
> From: Andy Schwartzmeyer
> Sent: Tuesday, August 11, 2015 8:15 PM
> To: Haiyang Zhang <haiyangz@microsoft.com>
> Cc: KY Srinivasan <kys@microsoft.com>; Andy Schwartzmeyer
> <andschwa@microsoft.com>; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org
> Subject: [PATCH net-next 2/2] hv_netvsc: Implement set_channels ethtool
> op
> 
> This enables the use of ethtool --set-channels devname combined N to
> change the number of vRSS queues. Separate rx, tx, and other parameters
> are not supported. The maximum is rsscap.num_recv_que. It passes the
> given value to rndis_filter_device_add through the device_info->num_chn
> field.
> 
> If the procedure fails, it attempts to recover to the prior state. If
> the recovery fails, it logs an error and aborts.
> 
> Current num_chn is saved and restored when changing the MTU.
> 
> Signed-off-by: Andrew Schwartzmeyer <andschwa@microsoft.com>

Thank you!

Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net-next 1/2] hv_netvsc: Set vRSS with num_chn in RNDIS filter
  2015-08-12  0:14 [PATCH net-next 1/2] hv_netvsc: Set vRSS with num_chn in RNDIS filter Andrew Schwartzmeyer
  2015-08-12  0:14 ` [PATCH net-next 2/2] hv_netvsc: Implement set_channels ethtool op Andrew Schwartzmeyer
  2015-08-12 19:05 ` [PATCH net-next 1/2] hv_netvsc: Set vRSS with num_chn in RNDIS filter Haiyang Zhang
@ 2015-08-12 21:45 ` David Miller
  2 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2015-08-12 21:45 UTC (permalink / raw)
  To: andschwa; +Cc: haiyangz, kys, netdev, linux-kernel

From: Andrew Schwartzmeyer <andschwa@microsoft.com>
Date: Tue, 11 Aug 2015 17:14:31 -0700

> Uses device_info->num_chn to pass user provided number of vRSS
> queues (from ethtool --set-channels) to rndis_filter_device_add. If
> nonzero and less than the maximum, set net_device->num_chn to the given
> value; else default to prior algorithm.
> 
> Always initialize struct device_info to 0, otherwise not all its fields
> are guaranteed to be 0, which is necessary when checking if num_chn has
> been purposefully set.
> 
> Signed-off-by: Andrew Schwartzmeyer <andschwa@microsoft.com>

Applied.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net-next 2/2] hv_netvsc: Implement set_channels ethtool op
  2015-08-12  0:14 ` [PATCH net-next 2/2] hv_netvsc: Implement set_channels ethtool op Andrew Schwartzmeyer
  2015-08-12 19:05   ` Haiyang Zhang
@ 2015-08-12 21:45   ` David Miller
  1 sibling, 0 replies; 6+ messages in thread
From: David Miller @ 2015-08-12 21:45 UTC (permalink / raw)
  To: andschwa; +Cc: haiyangz, kys, netdev, linux-kernel

From: Andrew Schwartzmeyer <andschwa@microsoft.com>
Date: Tue, 11 Aug 2015 17:14:32 -0700

> This enables the use of ethtool --set-channels devname combined N to
> change the number of vRSS queues. Separate rx, tx, and other parameters
> are not supported. The maximum is rsscap.num_recv_que. It passes the
> given value to rndis_filter_device_add through the device_info->num_chn
> field.
> 
> If the procedure fails, it attempts to recover to the prior state. If
> the recovery fails, it logs an error and aborts.
> 
> Current num_chn is saved and restored when changing the MTU.
> 
> Signed-off-by: Andrew Schwartzmeyer <andschwa@microsoft.com>

Applied.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-08-12 21:45 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-12  0:14 [PATCH net-next 1/2] hv_netvsc: Set vRSS with num_chn in RNDIS filter Andrew Schwartzmeyer
2015-08-12  0:14 ` [PATCH net-next 2/2] hv_netvsc: Implement set_channels ethtool op Andrew Schwartzmeyer
2015-08-12 19:05   ` Haiyang Zhang
2015-08-12 21:45   ` David Miller
2015-08-12 19:05 ` [PATCH net-next 1/2] hv_netvsc: Set vRSS with num_chn in RNDIS filter Haiyang Zhang
2015-08-12 21:45 ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.