From fd763ad96ae5a4aa76ce00b4090b6044c63c18ed Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 24 Jul 2017 10:57:25 -0700 Subject: netvsc: remove bogus rtnl_unlock Remove accidental rtnl_unlock from earlier testing. Fixes: 3962981f4822 ("netvsc: add rtnl annotations in rndis") Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 9a9e269a25ae..70b7cc37103c 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -1548,7 +1548,6 @@ static int netvsc_probe(struct hv_device *dev, netif_set_real_num_tx_queues(net, nvdev->num_chn); netif_set_real_num_rx_queues(net, nvdev->num_chn); - rtnl_unlock(); netdev_lockdep_set_classes(net); -- cgit v1.2.3 From 37b9dfa0d833227bc65353eec9dd0b00e1545a00 Mon Sep 17 00:00:00 2001 From: Mohammed Gamal Date: Mon, 24 Jul 2017 10:57:26 -0700 Subject: netvsc: Remove redundant use of ipv6_hdr() This condition already uses an object of type ipv6hdr in the line above. Use the object directly instead of calling ipv6_hdr Signed-off-by: Mohammed Gamal Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 70b7cc37103c..c266d427f934 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -339,7 +339,7 @@ static u32 net_checksum_info(struct sk_buff *skb) if (ip6->nexthdr == IPPROTO_TCP) return TRANSPORT_INFO_IPV6_TCP; - else if (ipv6_hdr(skb)->nexthdr == IPPROTO_UDP) + else if (ip6->nexthdr == IPPROTO_UDP) return TRANSPORT_INFO_IPV6_UDP; } -- cgit v1.2.3 From 43bf99ce009de710b68473480a611f3b5ddd11d5 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 24 Jul 2017 10:57:27 -0700 Subject: netvsc: prefetch the first incoming ring element In interrupt handler, prefetch the first incoming ring element so that it is in cache by the time NAPI poll gets to it. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 0a9d9feedc3f..06f39a99da7c 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -1265,10 +1266,15 @@ int netvsc_poll(struct napi_struct *napi, int budget) void netvsc_channel_cb(void *context) { struct netvsc_channel *nvchan = context; + struct vmbus_channel *channel = nvchan->channel; + struct hv_ring_buffer_info *rbi = &channel->inbound; + + /* preload first vmpacket descriptor */ + prefetch(hv_get_ring_buffer(rbi) + rbi->priv_read_index); if (napi_schedule_prep(&nvchan->napi)) { /* disable interupts from host */ - hv_begin_read(&nvchan->channel->inbound); + hv_begin_read(rbi); __napi_schedule(&nvchan->napi); } -- cgit v1.2.3 From 7ca4593338e19595cad48fa8dcd1da28c81352d6 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 24 Jul 2017 10:57:28 -0700 Subject: netvsc: fix netvsc_set_channels The number of channels returned by rndis_filter_device_add maybe less than the number requested. Therefore set correct real number of queues. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 52 +++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index c266d427f934..e212cbeb6333 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -713,39 +713,16 @@ static void netvsc_get_channels(struct net_device *net, } } -static int netvsc_set_queues(struct net_device *net, struct hv_device *dev, - u32 num_chn) -{ - struct netvsc_device_info device_info; - struct netvsc_device *net_device; - int ret; - - memset(&device_info, 0, sizeof(device_info)); - device_info.num_chn = num_chn; - device_info.ring_size = ring_size; - device_info.max_num_vrss_chns = num_chn; - - ret = netif_set_real_num_tx_queues(net, num_chn); - if (ret) - return ret; - - ret = netif_set_real_num_rx_queues(net, num_chn); - if (ret) - return ret; - - net_device = rndis_filter_device_add(dev, &device_info); - return PTR_ERR_OR_ZERO(net_device); -} - 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 = rtnl_dereference(net_device_ctx->nvdev); - unsigned int count = channels->combined_count; + unsigned int orig, count = channels->combined_count; + struct netvsc_device_info device_info; bool was_opened; - int ret; + int ret = 0; /* We do not support separate count for rx, tx, or other */ if (count == 0 || @@ -764,19 +741,29 @@ static int netvsc_set_channels(struct net_device *net, if (count > nvdev->max_chn) return -EINVAL; + orig = nvdev->num_chn; was_opened = rndis_filter_opened(nvdev); if (was_opened) rndis_filter_close(nvdev); rndis_filter_device_remove(dev, nvdev); - ret = netvsc_set_queues(net, dev, count); - if (ret == 0) - nvdev->num_chn = count; - else - netvsc_set_queues(net, dev, nvdev->num_chn); + memset(&device_info, 0, sizeof(device_info)); + device_info.num_chn = count; + device_info.ring_size = ring_size; + device_info.max_num_vrss_chns = count; + + nvdev = rndis_filter_device_add(dev, &device_info); + if (!IS_ERR(nvdev)) { + netif_set_real_num_tx_queues(net, nvdev->num_chn); + netif_set_real_num_rx_queues(net, nvdev->num_chn); + ret = PTR_ERR(nvdev); + } else { + device_info.num_chn = orig; + device_info.max_num_vrss_chns = count; + rndis_filter_device_add(dev, &device_info); + } - nvdev = rtnl_dereference(net_device_ctx->nvdev); if (was_opened) rndis_filter_open(nvdev); @@ -863,7 +850,6 @@ 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 = nvdev->num_chn; rndis_filter_device_remove(hdev, nvdev); -- cgit v1.2.3 From 27f5aa92ccafbe1bbc695307e3dee41a0e924c28 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 24 Jul 2017 10:57:29 -0700 Subject: netvsc: include rtnetlink.h Since these files use rtnl_derefernce make sure and include rtnetlink.h Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 2 ++ drivers/net/hyperv/rndis_filter.c | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index e212cbeb6333..a94fd545a650 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -33,6 +33,8 @@ #include #include #include +#include + #include #include #include diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index e439886f72c1..eaa3f0d5682a 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "hyperv_net.h" -- cgit v1.2.3 From 658677f17c5cbe84ec24fd7be69b4da1ed580596 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 24 Jul 2017 10:57:30 -0700 Subject: netvsc: remove no longer used max_num_rss queues This value has been calculated in rndis_device_attach since 4.11. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/hyperv/hyperv_net.h | 1 - drivers/net/hyperv/netvsc_drv.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index afb65f753574..4e7ff348327e 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -147,7 +147,6 @@ struct hv_netvsc_packet { struct netvsc_device_info { unsigned char mac_adr[ETH_ALEN]; int ring_size; - u32 max_num_vrss_chns; u32 num_chn; }; diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index a94fd545a650..262486ce8e2a 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -753,7 +753,6 @@ static int netvsc_set_channels(struct net_device *net, memset(&device_info, 0, sizeof(device_info)); device_info.num_chn = count; device_info.ring_size = ring_size; - device_info.max_num_vrss_chns = count; nvdev = rndis_filter_device_add(dev, &device_info); if (!IS_ERR(nvdev)) { @@ -762,7 +761,6 @@ static int netvsc_set_channels(struct net_device *net, ret = PTR_ERR(nvdev); } else { device_info.num_chn = orig; - device_info.max_num_vrss_chns = count; rndis_filter_device_add(dev, &device_info); } -- cgit v1.2.3