* [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 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@vger.kernel.org, linux-kernel@vger.kernel.org > -----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 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
* 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@vger.kernel.org, linux-kernel@vger.kernel.org > -----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 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
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 a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).