diff options
author | KY Srinivasan | 2015-05-27 22:16:57 +0200 |
---|---|---|
committer | David S. Miller | 2015-05-31 02:38:44 +0200 |
commit | e01ec2199ef22e2cabd7d6e68a192f3eb728029f (patch) | |
tree | 8b85d6e5667092dd5f9cb083685c6d6e61f1b560 /drivers/net/hyperv/rndis_filter.c | |
parent | net: limit tcp/udp rmem/wmem to SOCK_{RCV,SND}BUF_MIN (diff) | |
download | kernel-qcow2-linux-e01ec2199ef22e2cabd7d6e68a192f3eb728029f.tar.gz kernel-qcow2-linux-e01ec2199ef22e2cabd7d6e68a192f3eb728029f.tar.xz kernel-qcow2-linux-e01ec2199ef22e2cabd7d6e68a192f3eb728029f.zip |
hv_netvsc: Properly size the vrss queues
The current algorithm for deciding on the number of VRSS channels is
not optimal since we open up the min of number of CPUs online and the
number of VRSS channels the host is offering. So on a 32 VCPU guest
we could potentially open 32 VRSS subchannels. Experimentation has
shown that it is best to limit the number of VRSS channels to the number
of CPUs within a NUMA node.
Here is the new algorithm for deciding on the number of sub-channels we
would open up:
1) Pick the minimum of what the host is offering and what the driver
in the guest is specifying as the default value.
2) Pick the minimum of (1) and the numbers of CPUs in the NUMA
node the primary channel is bound to.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/hyperv/rndis_filter.c')
-rw-r--r-- | drivers/net/hyperv/rndis_filter.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 9118cea91882..006c1b8c2385 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -1013,6 +1013,9 @@ int rndis_filter_device_add(struct hv_device *dev, struct ndis_recv_scale_cap rsscap; u32 rsscap_size = sizeof(struct ndis_recv_scale_cap); u32 mtu, size; + u32 num_rss_qs; + const struct cpumask *node_cpu_mask; + u32 num_possible_rss_qs; rndis_device = get_rndis_device(); if (!rndis_device) @@ -1100,9 +1103,18 @@ int rndis_filter_device_add(struct hv_device *dev, if (ret || rsscap.num_recv_que < 2) goto out; + num_rss_qs = min(device_info->max_num_vrss_chns, rsscap.num_recv_que); + net_device->max_chn = rsscap.num_recv_que; - net_device->num_chn = (num_online_cpus() < rsscap.num_recv_que) ? - num_online_cpus() : rsscap.num_recv_que; + + /* + * We will limit the VRSS channels to the number CPUs in the NUMA node + * the primary channel is currently bound to. + */ + 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); + if (net_device->num_chn == 1) goto out; |