From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933278AbbHLAPS (ORCPT ); Tue, 11 Aug 2015 20:15:18 -0400 Received: from mail-bn1bn0109.outbound.protection.outlook.com ([157.56.110.109]:3872 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932485AbbHLAOx (ORCPT ); Tue, 11 Aug 2015 20:14:53 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=andschwa@microsoft.com; From: Andrew Schwartzmeyer To: CC: , , , Subject: [PATCH net-next 2/2] hv_netvsc: Implement set_channels ethtool op Date: Tue, 11 Aug 2015 17:14:32 -0700 Message-ID: <1439338472-21361-2-git-send-email-andschwa@microsoft.com> X-Mailer: git-send-email 2.4.2 In-Reply-To: <1439338472-21361-1-git-send-email-andschwa@microsoft.com> References: <1439338472-21361-1-git-send-email-andschwa@microsoft.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [131.107.160.55] X-ClientProxiedBy: BLUPR0401CA0031.namprd04.prod.outlook.com (25.162.114.169) To BY1PR0301MB1222.namprd03.prod.outlook.com (25.161.203.18) X-Microsoft-Exchange-Diagnostics: 1;BY1PR0301MB1222;2:9dNKrZkr53qJpMHKQZheULKrEc5zcC3/zU0L8FYyoinHg4fbG3+ZEQ42FAMEE2m0pmCIpFP6h64M6t10Wtec2OYWEPHIMHsWlpQjMDnid2jYg/EhxZLb79ukdykE79kMBeF6jdSSsdPUYZuGNRr8BqkEJXdMaWKHfVI7QGFugCc=;3:TLXMlCMyJJyCoiNe/WvkuweETugfsbUHockjD/Wm4EBsqwFRlVZ81Rn4YD3cyy7Oh6ywrHzGTc+sVAzrmpxKJMHsDJMkren6/pzTedBf+KH5L1Wafd/PZvqyUdb8xTuhMRGIBV1+hPzQTPsrLucz/g==;25:Ob9l6n/3pFGu7Wp8MJKozxc8x+cxbs7KHP57AXhi2JJ+C117XaUjU2/6XGBWhCpnS7Enkqf0rnUkAiKFDsFkQggbDHxeotZ0iewBdUlfcZduRi63eWoz6HrTt4M29oMPX83U1PQL1C6MHMUrji4V1wDv4vxFWaAWIYrXZ0Pw0mmd7xl3vzrkXpyLNZnSRZ8KFmHqc82mzqux5h7N7g3awuHZK5Lko15EMRuna4p2moSO7CP7erCm82lDTz/ueIzMvk6ZZq2Fmw5pQYG+rbrrAQ== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY1PR0301MB1222; X-O365ENT-EOP-Header: Message processed by - O365_ENT: Allow from ranges (Engineering ONLY) X-Microsoft-Exchange-Diagnostics: 1;BY1PR0301MB1222;20:DHPv82i40Apu2G+ZqtLs5dBed8n/XWXC2hmyD1k0oa8BCGrn6sBAzGXvX6cWGVmjE+p5rECO59PY7J7GYGSjvbwsz25q8sYetVDRwg4yhQJmdYC4tOdC9CsESExxbmwLUAom/Dfb3KSuGG5dsU4xt3ubXwLecbm3oJt5NqJBnKAz+4zi8ZagElST59JEGiOGplBbjCOMAzsKlKbN/FnwHXX7QGk2/StS2IraP1Rj5o8qbRlEgMXR4lMF2BclQ5VOn9aAvZgjf8pO/kZlXyddIAysBmMxxOa5lbArHuw1R/V9eLFQzUW/DwiLW3uDpt/6v+cpUM7nZ6wDT7TYmQnbUoAwjZ/nddT+rNjzyvsj6hyY6PfBp5hdTPU7kJUFsqshcehMAzZxDXipmHyEs2YWo4pt4SqKSO7FUwgWC/NgU6U9sO4jDzH2pbYmwxPteehUW1Odm1cThCppv+NlXEjPwKVrmqvTGun5hbELQdxoWo8S1CyHMPIoE2m7w0Jsglyq5/9Dxf1JB2rYInb3AD8BpIjGrFcbm5kP4IPyPPI5g4IAms3cWxpVlY2x1JLGRaHdy92p+bhgiR4OtXpyMTPh6toHfcB6yOZ3A3HFW0w0e5w=;4:QwVDLf3FqrV77BPjrInxSiqTb54LejJatIcuxAQTDtT7cxpNiYg9A9cYCJ/6lpCyVx6E/c+ndMVkR6WbRA69mcdJbbwgqw0XJe3oxVQyKZBTjEYWLqSQeIO3TspXHLD0U7E63C5FYJZwh86YKAwUBSVdZ0NAzzAwNyBnddYQvNeT0mMCc125EVyoBZhFxdS7YHpFeTwiLHJzU8U5ERoTnzUHFZkJRsEAW+0qk0nlpQWmqxRhfhCW7pIyWJvT4xbeoeo0nPtNsGDJ8cbxX1NTOXCYlFYR8Vz/m300EhrF7vk= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(108003899814671); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(5005006)(3002001);SRVR:BY1PR0301MB1222;BCL:0;PCL:0;RULEID:;SRVR:BY1PR0301MB1222; X-Forefront-PRVS: 0666E15D35 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(6009001)(199003)(189002)(10090500001)(189998001)(48376002)(50466002)(19580405001)(19580395003)(50226001)(1511001)(64706001)(33646002)(66066001)(47776003)(87976001)(2561002)(92566002)(62966003)(77156002)(86362001)(450100001)(2421001)(122386002)(46102003)(40100003)(77096005)(68736005)(86612001)(2950100001)(42186005)(76176999)(50986999)(5001860100001)(5001830100001)(5001960100002)(81156007)(4001450100002)(101416001)(97736004)(5003940100001)(4001540100001)(110136002)(36756003)(105586002)(106356001)(2351001)(10290500002)(5005710100001)(229853001);DIR:OUT;SFP:1102;SCL:1;SRVR:BY1PR0301MB1222;H:ubuntu.corp.microsoft.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BY1PR0301MB1222;23:6WlAcTSgMdRkDDbU+M3Me2d3ZTZ2ctPfJiPxczH?= =?us-ascii?Q?fG4lKs/wkFNtBppRYMs/tVTrjui5RblFbFo+NdN1oFnV6WUwl2PyVgkw9yUb?= =?us-ascii?Q?uVC8rpSyczkZhEnNMaTC9xZN5zjHRG3rxKNxPQ3gjSDKEkvEQbmiGIyF/MjI?= =?us-ascii?Q?Wm9fqNeVVJvOZdA0yzvAwHswA5TJOzEwjvbqAEdEPO4wLiDoit0s7zWLDvyd?= =?us-ascii?Q?mJBdp8uR7sFcvW24EsDNE25vYdZFm7CqNhs3fYGOm4CcRoyboRe08tbJWzPE?= =?us-ascii?Q?6php+diyiUfj5+P5QM8B1OU4G5ys5t0VPQZM64OhAbDNd9gEVK9MLHdHHZfS?= =?us-ascii?Q?HY9m4XeAb8DCtdolSu+t4YvGR9VI/iTPb/Nhhnh5rdu0VTPhJ5YsWbBUTntw?= =?us-ascii?Q?qt2PJfQtc8dTpuJK6ABdr4bv1jp/CMbEsu+fQjqOZB1OYR99Szc8UTCUwPuR?= =?us-ascii?Q?jnfLoDkr/uEE3nrBY4lz/Cl81BK+xz2X5b8//XCH5z+k8IJBWfwGUIs5FuIo?= =?us-ascii?Q?LugNvF+ITOoINdoho1z0GKCqUKueXq/ZbSu70dA6y0B3zEplcyHoFwfx4Art?= =?us-ascii?Q?MhxZYil7VFS0aqhqy/Ux/JHKjhht54JggYHY/OeNTJ1MpVs1oAmL7xoPBFhq?= =?us-ascii?Q?d7nVWUSj1cIkfFVXOu6VSpTfDsEi+Y5pG8rdNPhRbOqDQLHaQAKn4qLunoJj?= =?us-ascii?Q?lZe988oIq/yROsBC+5957U6Tp9aWhq2yYCpAU6V7LLAMcsSphxjZtpjxaqbq?= =?us-ascii?Q?jkwjRoEy3bAJRBusBs/lQpvBwGDnQFlq8dBWSCJjieLYzuzhrQci0nY6JRCd?= =?us-ascii?Q?ieiQiX+7CbYQKppnVayPfw1B+K8j7rjq2DfPQ3aFbwIJD/Xdua/fLyyp+S2a?= =?us-ascii?Q?RDcmc6hXMcwgBOuWlyC9FVVc8/EN2cPKYPNOboMFrE21dmAZM/tftrvhClX7?= =?us-ascii?Q?G4t5dPhnyvT9H3xr+UZImIT1RZNlkpHkejZQMYcWJCQWZxW/AXy8hsoGFP8y?= =?us-ascii?Q?KOIhDpH/8kzxUDuC+EQB3S0JZyqkwctAnQKhftVFECptOUfpdZRsiLQbBsGN?= =?us-ascii?Q?3FBnd+jTJ9MXJCD2VnAiQ9n6Br/iN/98PPq/mn9Up++1MA9bL8b8td2R812H?= =?us-ascii?Q?+y/nKY9STcn2s9U9NK1E+p/I/g/Ad68ObBo0mn2OKRh5GkgIz3j64yvlCYMH?= =?us-ascii?Q?5IJMWrs93QCBFJYXiWohOyMLuvDjko+hQ3yPbNAzyvy4tzfHA/VkGzIRFQbt?= =?us-ascii?Q?6C1VKZJUD1IdqJ0HSiBRghvuUoRWkqINVh4cX4a9ct9qf5OkD4rPJ3bW6scQ?= =?us-ascii?Q?GbHuv3abFgEgpVmnCBPJynXM=3D?= X-Microsoft-Exchange-Diagnostics: 1;BY1PR0301MB1222;5:SmUe9zNGD1ON3MSbHSjs3HgBdipV6xgNH6Bzsf2BzeKpORaEBmD8NwS3VqiRPao9yJh8kox8Lzz9Vdd+hdWWCvCInYHl5iN/vUjZUVwnpI/11UAGYiNFCYR5FkVx8sR6kC71GiUeOfcq2zoHk0OcGA==;24:0YyNi+EY6eT3xASc/+xj7Xm573gJaMKZDsdHo4wzktDA6pSiWsskaQqyeo5twDvYR7RPZmUdF4bR9/b7HuWWk6Kcdf/qpOnhQ8pAIcdF3g4=;20:qRtBCIhs7qZrQBVRuJq06EgrmTZT5HmECasONRA85a+BdN1bFvy5owb1Rw2uo6XC+sXz/8R5YQo243eM9Ml/dQ== X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Aug 2015 00:14:49.8998 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY1PR0301MB1222 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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