aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstephen hemminger <stephen@networkplumber.org>2017-07-28 11:59:42 -0400
committerDavid S. Miller <davem@davemloft.net>2017-07-29 18:25:43 -0400
commit867047c4512aa65fb4cf66b253b51b830c7fa172 (patch)
tree61fe0635f7c2eaae5d6591d5df61f05c18a3ff11
parentd6aac1f218873f2266de23280bffb909b4a98fbf (diff)
netvsc: fix warnings reported by lockdep
This includes a bunch of fixups for issues reported by lockdep. * ethtool routines can assume RTNL * send is done with RCU lock (and BH disable) * avoid refetching internal device struct (netvsc) instead pass it as a parameter. Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/hyperv/hyperv_net.h3
-rw-r--r--drivers/net/hyperv/netvsc.c2
-rw-r--r--drivers/net/hyperv/netvsc_drv.c15
-rw-r--r--drivers/net/hyperv/rndis_filter.c84
4 files changed, 54 insertions, 50 deletions
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 4e7ff348327e..fb62ea632914 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -217,7 +217,8 @@ int rndis_filter_receive(struct net_device *ndev,
217 struct vmbus_channel *channel, 217 struct vmbus_channel *channel,
218 void *data, u32 buflen); 218 void *data, u32 buflen);
219 219
220int rndis_filter_set_device_mac(struct net_device *ndev, char *mac); 220int rndis_filter_set_device_mac(struct netvsc_device *ndev,
221 const char *mac);
221 222
222void netvsc_switch_datapath(struct net_device *nv_dev, bool vf); 223void netvsc_switch_datapath(struct net_device *nv_dev, bool vf);
223 224
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 06f39a99da7c..94c00acac58a 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -832,7 +832,7 @@ int netvsc_send(struct net_device_context *ndev_ctx,
832 struct sk_buff *skb) 832 struct sk_buff *skb)
833{ 833{
834 struct netvsc_device *net_device 834 struct netvsc_device *net_device
835 = rcu_dereference_rtnl(ndev_ctx->nvdev); 835 = rcu_dereference_bh(ndev_ctx->nvdev);
836 struct hv_device *device = ndev_ctx->device_ctx; 836 struct hv_device *device = ndev_ctx->device_ctx;
837 int ret = 0; 837 int ret = 0;
838 struct netvsc_channel *nvchan; 838 struct netvsc_channel *nvchan;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index f1eaf675d2e9..a04f2efbbc25 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -923,6 +923,8 @@ static void netvsc_get_stats64(struct net_device *net,
923 923
924static int netvsc_set_mac_addr(struct net_device *ndev, void *p) 924static int netvsc_set_mac_addr(struct net_device *ndev, void *p)
925{ 925{
926 struct net_device_context *ndc = netdev_priv(ndev);
927 struct netvsc_device *nvdev = rtnl_dereference(ndc->nvdev);
926 struct sockaddr *addr = p; 928 struct sockaddr *addr = p;
927 char save_adr[ETH_ALEN]; 929 char save_adr[ETH_ALEN];
928 unsigned char save_aatype; 930 unsigned char save_aatype;
@@ -935,7 +937,10 @@ static int netvsc_set_mac_addr(struct net_device *ndev, void *p)
935 if (err != 0) 937 if (err != 0)
936 return err; 938 return err;
937 939
938 err = rndis_filter_set_device_mac(ndev, addr->sa_data); 940 if (!nvdev)
941 return -ENODEV;
942
943 err = rndis_filter_set_device_mac(nvdev, addr->sa_data);
939 if (err != 0) { 944 if (err != 0) {
940 /* roll back to saved MAC */ 945 /* roll back to saved MAC */
941 memcpy(ndev->dev_addr, save_adr, ETH_ALEN); 946 memcpy(ndev->dev_addr, save_adr, ETH_ALEN);
@@ -981,7 +986,7 @@ static void netvsc_get_ethtool_stats(struct net_device *dev,
981 struct ethtool_stats *stats, u64 *data) 986 struct ethtool_stats *stats, u64 *data)
982{ 987{
983 struct net_device_context *ndc = netdev_priv(dev); 988 struct net_device_context *ndc = netdev_priv(dev);
984 struct netvsc_device *nvdev = rcu_dereference(ndc->nvdev); 989 struct netvsc_device *nvdev = rtnl_dereference(ndc->nvdev);
985 const void *nds = &ndc->eth_stats; 990 const void *nds = &ndc->eth_stats;
986 const struct netvsc_stats *qstats; 991 const struct netvsc_stats *qstats;
987 unsigned int start; 992 unsigned int start;
@@ -1019,7 +1024,7 @@ static void netvsc_get_ethtool_stats(struct net_device *dev,
1019static void netvsc_get_strings(struct net_device *dev, u32 stringset, u8 *data) 1024static void netvsc_get_strings(struct net_device *dev, u32 stringset, u8 *data)
1020{ 1025{
1021 struct net_device_context *ndc = netdev_priv(dev); 1026 struct net_device_context *ndc = netdev_priv(dev);
1022 struct netvsc_device *nvdev = rcu_dereference(ndc->nvdev); 1027 struct netvsc_device *nvdev = rtnl_dereference(ndc->nvdev);
1023 u8 *p = data; 1028 u8 *p = data;
1024 int i; 1029 int i;
1025 1030
@@ -1077,7 +1082,7 @@ netvsc_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
1077 u32 *rules) 1082 u32 *rules)
1078{ 1083{
1079 struct net_device_context *ndc = netdev_priv(dev); 1084 struct net_device_context *ndc = netdev_priv(dev);
1080 struct netvsc_device *nvdev = rcu_dereference(ndc->nvdev); 1085 struct netvsc_device *nvdev = rtnl_dereference(ndc->nvdev);
1081 1086
1082 if (!nvdev) 1087 if (!nvdev)
1083 return -ENODEV; 1088 return -ENODEV;
@@ -1127,7 +1132,7 @@ static int netvsc_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
1127 u8 *hfunc) 1132 u8 *hfunc)
1128{ 1133{
1129 struct net_device_context *ndc = netdev_priv(dev); 1134 struct net_device_context *ndc = netdev_priv(dev);
1130 struct netvsc_device *ndev = rcu_dereference(ndc->nvdev); 1135 struct netvsc_device *ndev = rtnl_dereference(ndc->nvdev);
1131 struct rndis_device *rndis_dev; 1136 struct rndis_device *rndis_dev;
1132 int i; 1137 int i;
1133 1138
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index eaa3f0d5682a..bf21ea92c743 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -85,14 +85,6 @@ static struct rndis_device *get_rndis_device(void)
85 return device; 85 return device;
86} 86}
87 87
88static struct netvsc_device *
89net_device_to_netvsc_device(struct net_device *ndev)
90{
91 struct net_device_context *net_device_ctx = netdev_priv(ndev);
92
93 return rtnl_dereference(net_device_ctx->nvdev);
94}
95
96static struct rndis_request *get_rndis_request(struct rndis_device *dev, 88static struct rndis_request *get_rndis_request(struct rndis_device *dev,
97 u32 msg_type, 89 u32 msg_type,
98 u32 msg_len) 90 u32 msg_len)
@@ -252,7 +244,10 @@ static int rndis_filter_send_request(struct rndis_device *dev,
252 pb[0].len; 244 pb[0].len;
253 } 245 }
254 246
247 rcu_read_lock_bh();
255 ret = netvsc_send(net_device_ctx, packet, NULL, &pb, NULL); 248 ret = netvsc_send(net_device_ctx, packet, NULL, &pb, NULL);
249 rcu_read_unlock_bh();
250
256 return ret; 251 return ret;
257} 252}
258 253
@@ -452,8 +447,9 @@ int rndis_filter_receive(struct net_device *ndev,
452 return 0; 447 return 0;
453} 448}
454 449
455static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, 450static int rndis_filter_query_device(struct rndis_device *dev,
456 void *result, u32 *result_size) 451 struct netvsc_device *nvdev,
452 u32 oid, void *result, u32 *result_size)
457{ 453{
458 struct rndis_request *request; 454 struct rndis_request *request;
459 u32 inresult_size = *result_size; 455 u32 inresult_size = *result_size;
@@ -480,8 +476,6 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
480 query->dev_vc_handle = 0; 476 query->dev_vc_handle = 0;
481 477
482 if (oid == OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES) { 478 if (oid == OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES) {
483 struct net_device_context *ndevctx = netdev_priv(dev->ndev);
484 struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev);
485 struct ndis_offload *hwcaps; 479 struct ndis_offload *hwcaps;
486 u32 nvsp_version = nvdev->nvsp_version; 480 u32 nvsp_version = nvdev->nvsp_version;
487 u8 ndis_rev; 481 u8 ndis_rev;
@@ -550,14 +544,15 @@ cleanup:
550 544
551/* Get the hardware offload capabilities */ 545/* Get the hardware offload capabilities */
552static int 546static int
553rndis_query_hwcaps(struct rndis_device *dev, struct ndis_offload *caps) 547rndis_query_hwcaps(struct rndis_device *dev, struct netvsc_device *net_device,
548 struct ndis_offload *caps)
554{ 549{
555 u32 caps_len = sizeof(*caps); 550 u32 caps_len = sizeof(*caps);
556 int ret; 551 int ret;
557 552
558 memset(caps, 0, sizeof(*caps)); 553 memset(caps, 0, sizeof(*caps));
559 554
560 ret = rndis_filter_query_device(dev, 555 ret = rndis_filter_query_device(dev, net_device,
561 OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES, 556 OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES,
562 caps, &caps_len); 557 caps, &caps_len);
563 if (ret) 558 if (ret)
@@ -586,11 +581,12 @@ rndis_query_hwcaps(struct rndis_device *dev, struct ndis_offload *caps)
586 return 0; 581 return 0;
587} 582}
588 583
589static int rndis_filter_query_device_mac(struct rndis_device *dev) 584static int rndis_filter_query_device_mac(struct rndis_device *dev,
585 struct netvsc_device *net_device)
590{ 586{
591 u32 size = ETH_ALEN; 587 u32 size = ETH_ALEN;
592 588
593 return rndis_filter_query_device(dev, 589 return rndis_filter_query_device(dev, net_device,
594 RNDIS_OID_802_3_PERMANENT_ADDRESS, 590 RNDIS_OID_802_3_PERMANENT_ADDRESS,
595 dev->hw_mac_adr, &size); 591 dev->hw_mac_adr, &size);
596} 592}
@@ -598,9 +594,9 @@ static int rndis_filter_query_device_mac(struct rndis_device *dev)
598#define NWADR_STR "NetworkAddress" 594#define NWADR_STR "NetworkAddress"
599#define NWADR_STRLEN 14 595#define NWADR_STRLEN 14
600 596
601int rndis_filter_set_device_mac(struct net_device *ndev, char *mac) 597int rndis_filter_set_device_mac(struct netvsc_device *nvdev,
598 const char *mac)
602{ 599{
603 struct netvsc_device *nvdev = net_device_to_netvsc_device(ndev);
604 struct rndis_device *rdev = nvdev->extension; 600 struct rndis_device *rdev = nvdev->extension;
605 struct rndis_request *request; 601 struct rndis_request *request;
606 struct rndis_set_request *set; 602 struct rndis_set_request *set;
@@ -654,11 +650,8 @@ int rndis_filter_set_device_mac(struct net_device *ndev, char *mac)
654 wait_for_completion(&request->wait_event); 650 wait_for_completion(&request->wait_event);
655 651
656 set_complete = &request->response_msg.msg.set_complete; 652 set_complete = &request->response_msg.msg.set_complete;
657 if (set_complete->status != RNDIS_STATUS_SUCCESS) { 653 if (set_complete->status != RNDIS_STATUS_SUCCESS)
658 netdev_err(ndev, "Fail to set MAC on host side:0x%x\n", 654 ret = -EIO;
659 set_complete->status);
660 ret = -EINVAL;
661 }
662 655
663cleanup: 656cleanup:
664 put_rndis_request(rdev, request); 657 put_rndis_request(rdev, request);
@@ -791,27 +784,27 @@ cleanup:
791 return ret; 784 return ret;
792} 785}
793 786
794static int rndis_filter_query_device_link_status(struct rndis_device *dev) 787static int rndis_filter_query_device_link_status(struct rndis_device *dev,
788 struct netvsc_device *net_device)
795{ 789{
796 u32 size = sizeof(u32); 790 u32 size = sizeof(u32);
797 u32 link_status; 791 u32 link_status;
798 int ret;
799 792
800 ret = rndis_filter_query_device(dev, 793 return rndis_filter_query_device(dev, net_device,
801 RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, 794 RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
802 &link_status, &size); 795 &link_status, &size);
803
804 return ret;
805} 796}
806 797
807static int rndis_filter_query_link_speed(struct rndis_device *dev) 798static int rndis_filter_query_link_speed(struct rndis_device *dev,
799 struct netvsc_device *net_device)
808{ 800{
809 u32 size = sizeof(u32); 801 u32 size = sizeof(u32);
810 u32 link_speed; 802 u32 link_speed;
811 struct net_device_context *ndc; 803 struct net_device_context *ndc;
812 int ret; 804 int ret;
813 805
814 ret = rndis_filter_query_device(dev, RNDIS_OID_GEN_LINK_SPEED, 806 ret = rndis_filter_query_device(dev, net_device,
807 RNDIS_OID_GEN_LINK_SPEED,
815 &link_speed, &size); 808 &link_speed, &size);
816 809
817 if (!ret) { 810 if (!ret) {
@@ -880,14 +873,14 @@ void rndis_filter_update(struct netvsc_device *nvdev)
880 schedule_work(&rdev->mcast_work); 873 schedule_work(&rdev->mcast_work);
881} 874}
882 875
883static int rndis_filter_init_device(struct rndis_device *dev) 876static int rndis_filter_init_device(struct rndis_device *dev,
877 struct netvsc_device *nvdev)
884{ 878{
885 struct rndis_request *request; 879 struct rndis_request *request;
886 struct rndis_initialize_request *init; 880 struct rndis_initialize_request *init;
887 struct rndis_initialize_complete *init_complete; 881 struct rndis_initialize_complete *init_complete;
888 u32 status; 882 u32 status;
889 int ret; 883 int ret;
890 struct netvsc_device *nvdev = net_device_to_netvsc_device(dev->ndev);
891 884
892 request = get_rndis_request(dev, RNDIS_MSG_INIT, 885 request = get_rndis_request(dev, RNDIS_MSG_INIT,
893 RNDIS_MESSAGE_SIZE(struct rndis_initialize_request)); 886 RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
@@ -1024,12 +1017,17 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
1024{ 1017{
1025 struct net_device *ndev = 1018 struct net_device *ndev =
1026 hv_get_drvdata(new_sc->primary_channel->device_obj); 1019 hv_get_drvdata(new_sc->primary_channel->device_obj);
1027 struct netvsc_device *nvscdev = net_device_to_netvsc_device(ndev); 1020 struct net_device_context *ndev_ctx = netdev_priv(ndev);
1021 struct netvsc_device *nvscdev;
1028 u16 chn_index = new_sc->offermsg.offer.sub_channel_index; 1022 u16 chn_index = new_sc->offermsg.offer.sub_channel_index;
1029 struct netvsc_channel *nvchan; 1023 struct netvsc_channel *nvchan;
1030 int ret; 1024 int ret;
1031 1025
1032 if (chn_index >= nvscdev->num_chn) 1026 /* This is safe because this callback only happens when
1027 * new device is being setup and waiting on the channel_init_wait.
1028 */
1029 nvscdev = rcu_dereference_raw(ndev_ctx->nvdev);
1030 if (!nvscdev || chn_index >= nvscdev->num_chn)
1033 return; 1031 return;
1034 1032
1035 nvchan = nvscdev->chan_table + chn_index; 1033 nvchan = nvscdev->chan_table + chn_index;
@@ -1104,27 +1102,27 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
1104 rndis_device->ndev = net; 1102 rndis_device->ndev = net;
1105 1103
1106 /* Send the rndis initialization message */ 1104 /* Send the rndis initialization message */
1107 ret = rndis_filter_init_device(rndis_device); 1105 ret = rndis_filter_init_device(rndis_device, net_device);
1108 if (ret != 0) 1106 if (ret != 0)
1109 goto err_dev_remv; 1107 goto err_dev_remv;
1110 1108
1111 /* Get the MTU from the host */ 1109 /* Get the MTU from the host */
1112 size = sizeof(u32); 1110 size = sizeof(u32);
1113 ret = rndis_filter_query_device(rndis_device, 1111 ret = rndis_filter_query_device(rndis_device, net_device,
1114 RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE, 1112 RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE,
1115 &mtu, &size); 1113 &mtu, &size);
1116 if (ret == 0 && size == sizeof(u32) && mtu < net->mtu) 1114 if (ret == 0 && size == sizeof(u32) && mtu < net->mtu)
1117 net->mtu = mtu; 1115 net->mtu = mtu;
1118 1116
1119 /* Get the mac address */ 1117 /* Get the mac address */
1120 ret = rndis_filter_query_device_mac(rndis_device); 1118 ret = rndis_filter_query_device_mac(rndis_device, net_device);
1121 if (ret != 0) 1119 if (ret != 0)
1122 goto err_dev_remv; 1120 goto err_dev_remv;
1123 1121
1124 memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN); 1122 memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN);
1125 1123
1126 /* Find HW offload capabilities */ 1124 /* Find HW offload capabilities */
1127 ret = rndis_query_hwcaps(rndis_device, &hwcaps); 1125 ret = rndis_query_hwcaps(rndis_device, net_device, &hwcaps);
1128 if (ret != 0) 1126 if (ret != 0)
1129 goto err_dev_remv; 1127 goto err_dev_remv;
1130 1128
@@ -1185,7 +1183,7 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
1185 if (ret) 1183 if (ret)
1186 goto err_dev_remv; 1184 goto err_dev_remv;
1187 1185
1188 rndis_filter_query_device_link_status(rndis_device); 1186 rndis_filter_query_device_link_status(rndis_device, net_device);
1189 1187
1190 netdev_dbg(net, "Device MAC %pM link state %s\n", 1188 netdev_dbg(net, "Device MAC %pM link state %s\n",
1191 rndis_device->hw_mac_adr, 1189 rndis_device->hw_mac_adr,
@@ -1194,11 +1192,11 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
1194 if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5) 1192 if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5)
1195 return net_device; 1193 return net_device;
1196 1194
1197 rndis_filter_query_link_speed(rndis_device); 1195 rndis_filter_query_link_speed(rndis_device, net_device);
1198 1196
1199 /* vRSS setup */ 1197 /* vRSS setup */
1200 memset(&rsscap, 0, rsscap_size); 1198 memset(&rsscap, 0, rsscap_size);
1201 ret = rndis_filter_query_device(rndis_device, 1199 ret = rndis_filter_query_device(rndis_device, net_device,
1202 OID_GEN_RECEIVE_SCALE_CAPABILITIES, 1200 OID_GEN_RECEIVE_SCALE_CAPABILITIES,
1203 &rsscap, &rsscap_size); 1201 &rsscap, &rsscap_size);
1204 if (ret || rsscap.num_recv_que < 2) 1202 if (ret || rsscap.num_recv_que < 2)