aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <stephen@networkplumber.org>2018-03-20 18:03:05 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-22 12:45:09 -0400
commit7b2ee50c0cd513a176a26a71f2989facdd75bfea (patch)
tree3056b5d027d819b98ce01e26128b3617b3a23e58
parent0ef58b0a05c127762f975c3dfe8b922e4aa87a29 (diff)
hv_netvsc: common detach logic
Make common function for detaching internals of device during changes to MTU and RSS. Make sure no more packets are transmitted and all packets have been received before doing device teardown. Change the wait logic to be common and use usleep_range(). Changes transmit enabling logic so that transmit queues are disabled during the period when lower device is being changed. And enabled only after sub channels are setup. This avoids issue where it could be that a packet was being sent while subchannel was not initialized. Fixes: 8195b1396ec8 ("hv_netvsc: fix deadlock on hotplug") 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.h1
-rw-r--r--drivers/net/hyperv/netvsc.c20
-rw-r--r--drivers/net/hyperv/netvsc_drv.c278
-rw-r--r--drivers/net/hyperv/rndis_filter.c17
4 files changed, 173 insertions, 143 deletions
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index cd538d5a7986..32861036c3fc 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -212,7 +212,6 @@ void netvsc_channel_cb(void *context);
212int netvsc_poll(struct napi_struct *napi, int budget); 212int netvsc_poll(struct napi_struct *napi, int budget);
213 213
214void rndis_set_subchannel(struct work_struct *w); 214void rndis_set_subchannel(struct work_struct *w);
215bool rndis_filter_opened(const struct netvsc_device *nvdev);
216int rndis_filter_open(struct netvsc_device *nvdev); 215int rndis_filter_open(struct netvsc_device *nvdev);
217int rndis_filter_close(struct netvsc_device *nvdev); 216int rndis_filter_close(struct netvsc_device *nvdev);
218struct netvsc_device *rndis_filter_device_add(struct hv_device *dev, 217struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 37b0a30d6b03..7472172823f3 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -555,8 +555,6 @@ void netvsc_device_remove(struct hv_device *device)
555 = rtnl_dereference(net_device_ctx->nvdev); 555 = rtnl_dereference(net_device_ctx->nvdev);
556 int i; 556 int i;
557 557
558 cancel_work_sync(&net_device->subchan_work);
559
560 netvsc_revoke_buf(device, net_device); 558 netvsc_revoke_buf(device, net_device);
561 559
562 RCU_INIT_POINTER(net_device_ctx->nvdev, NULL); 560 RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
@@ -643,14 +641,18 @@ static void netvsc_send_tx_complete(struct netvsc_device *net_device,
643 queue_sends = 641 queue_sends =
644 atomic_dec_return(&net_device->chan_table[q_idx].queue_sends); 642 atomic_dec_return(&net_device->chan_table[q_idx].queue_sends);
645 643
646 if (net_device->destroy && queue_sends == 0) 644 if (unlikely(net_device->destroy)) {
647 wake_up(&net_device->wait_drain); 645 if (queue_sends == 0)
646 wake_up(&net_device->wait_drain);
647 } else {
648 struct netdev_queue *txq = netdev_get_tx_queue(ndev, q_idx);
648 649
649 if (netif_tx_queue_stopped(netdev_get_tx_queue(ndev, q_idx)) && 650 if (netif_tx_queue_stopped(txq) &&
650 (hv_ringbuf_avail_percent(&channel->outbound) > RING_AVAIL_PERCENT_HIWATER || 651 (hv_ringbuf_avail_percent(&channel->outbound) > RING_AVAIL_PERCENT_HIWATER ||
651 queue_sends < 1)) { 652 queue_sends < 1)) {
652 netif_tx_wake_queue(netdev_get_tx_queue(ndev, q_idx)); 653 netif_tx_wake_queue(txq);
653 ndev_ctx->eth_stats.wake_queue++; 654 ndev_ctx->eth_stats.wake_queue++;
655 }
654 } 656 }
655} 657}
656 658
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index faea0be18924..f28c85d212ce 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -46,7 +46,10 @@
46 46
47#include "hyperv_net.h" 47#include "hyperv_net.h"
48 48
49#define RING_SIZE_MIN 64 49#define RING_SIZE_MIN 64
50#define RETRY_US_LO 5000
51#define RETRY_US_HI 10000
52#define RETRY_MAX 2000 /* >10 sec */
50 53
51#define LINKCHANGE_INT (2 * HZ) 54#define LINKCHANGE_INT (2 * HZ)
52#define VF_TAKEOVER_INT (HZ / 10) 55#define VF_TAKEOVER_INT (HZ / 10)
@@ -123,10 +126,8 @@ static int netvsc_open(struct net_device *net)
123 } 126 }
124 127
125 rdev = nvdev->extension; 128 rdev = nvdev->extension;
126 if (!rdev->link_state) { 129 if (!rdev->link_state)
127 netif_carrier_on(net); 130 netif_carrier_on(net);
128 netif_tx_wake_all_queues(net);
129 }
130 131
131 if (vf_netdev) { 132 if (vf_netdev) {
132 /* Setting synthetic device up transparently sets 133 /* Setting synthetic device up transparently sets
@@ -142,36 +143,25 @@ static int netvsc_open(struct net_device *net)
142 return 0; 143 return 0;
143} 144}
144 145
145static int netvsc_close(struct net_device *net) 146static int netvsc_wait_until_empty(struct netvsc_device *nvdev)
146{ 147{
147 struct net_device_context *net_device_ctx = netdev_priv(net); 148 unsigned int retry = 0;
148 struct net_device *vf_netdev 149 int i;
149 = rtnl_dereference(net_device_ctx->vf_netdev);
150 struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
151 int ret = 0;
152 u32 aread, i, msec = 10, retry = 0, retry_max = 20;
153 struct vmbus_channel *chn;
154
155 netif_tx_disable(net);
156
157 /* No need to close rndis filter if it is removed already */
158 if (!nvdev)
159 goto out;
160
161 ret = rndis_filter_close(nvdev);
162 if (ret != 0) {
163 netdev_err(net, "unable to close device (ret %d).\n", ret);
164 return ret;
165 }
166 150
167 /* Ensure pending bytes in ring are read */ 151 /* Ensure pending bytes in ring are read */
168 while (true) { 152 for (;;) {
169 aread = 0; 153 u32 aread = 0;
154
170 for (i = 0; i < nvdev->num_chn; i++) { 155 for (i = 0; i < nvdev->num_chn; i++) {
171 chn = nvdev->chan_table[i].channel; 156 struct vmbus_channel *chn
157 = nvdev->chan_table[i].channel;
158
172 if (!chn) 159 if (!chn)
173 continue; 160 continue;
174 161
162 /* make sure receive not running now */
163 napi_synchronize(&nvdev->chan_table[i].napi);
164
175 aread = hv_get_bytes_to_read(&chn->inbound); 165 aread = hv_get_bytes_to_read(&chn->inbound);
176 if (aread) 166 if (aread)
177 break; 167 break;
@@ -181,22 +171,40 @@ static int netvsc_close(struct net_device *net)
181 break; 171 break;
182 } 172 }
183 173
184 retry++; 174 if (aread == 0)
185 if (retry > retry_max || aread == 0) 175 return 0;
186 break;
187 176
188 msleep(msec); 177 if (++retry > RETRY_MAX)
178 return -ETIMEDOUT;
189 179
190 if (msec < 1000) 180 usleep_range(RETRY_US_LO, RETRY_US_HI);
191 msec *= 2;
192 } 181 }
182}
193 183
194 if (aread) { 184static int netvsc_close(struct net_device *net)
195 netdev_err(net, "Ring buffer not empty after closing rndis\n"); 185{
196 ret = -ETIMEDOUT; 186 struct net_device_context *net_device_ctx = netdev_priv(net);
187 struct net_device *vf_netdev
188 = rtnl_dereference(net_device_ctx->vf_netdev);
189 struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
190 int ret;
191
192 netif_tx_disable(net);
193
194 /* No need to close rndis filter if it is removed already */
195 if (!nvdev)
196 return 0;
197
198 ret = rndis_filter_close(nvdev);
199 if (ret != 0) {
200 netdev_err(net, "unable to close device (ret %d).\n", ret);
201 return ret;
197 } 202 }
198 203
199out: 204 ret = netvsc_wait_until_empty(nvdev);
205 if (ret)
206 netdev_err(net, "Ring buffer not empty after closing rndis\n");
207
200 if (vf_netdev) 208 if (vf_netdev)
201 dev_close(vf_netdev); 209 dev_close(vf_netdev);
202 210
@@ -845,16 +853,81 @@ static void netvsc_get_channels(struct net_device *net,
845 } 853 }
846} 854}
847 855
856static int netvsc_detach(struct net_device *ndev,
857 struct netvsc_device *nvdev)
858{
859 struct net_device_context *ndev_ctx = netdev_priv(ndev);
860 struct hv_device *hdev = ndev_ctx->device_ctx;
861 int ret;
862
863 /* Don't try continuing to try and setup sub channels */
864 if (cancel_work_sync(&nvdev->subchan_work))
865 nvdev->num_chn = 1;
866
867 /* If device was up (receiving) then shutdown */
868 if (netif_running(ndev)) {
869 netif_tx_disable(ndev);
870
871 ret = rndis_filter_close(nvdev);
872 if (ret) {
873 netdev_err(ndev,
874 "unable to close device (ret %d).\n", ret);
875 return ret;
876 }
877
878 ret = netvsc_wait_until_empty(nvdev);
879 if (ret) {
880 netdev_err(ndev,
881 "Ring buffer not empty after closing rndis\n");
882 return ret;
883 }
884 }
885
886 netif_device_detach(ndev);
887
888 rndis_filter_device_remove(hdev, nvdev);
889
890 return 0;
891}
892
893static int netvsc_attach(struct net_device *ndev,
894 struct netvsc_device_info *dev_info)
895{
896 struct net_device_context *ndev_ctx = netdev_priv(ndev);
897 struct hv_device *hdev = ndev_ctx->device_ctx;
898 struct netvsc_device *nvdev;
899 struct rndis_device *rdev;
900 int ret;
901
902 nvdev = rndis_filter_device_add(hdev, dev_info);
903 if (IS_ERR(nvdev))
904 return PTR_ERR(nvdev);
905
906 /* Note: enable and attach happen when sub-channels setup */
907
908 netif_carrier_off(ndev);
909
910 if (netif_running(ndev)) {
911 ret = rndis_filter_open(nvdev);
912 if (ret)
913 return ret;
914
915 rdev = nvdev->extension;
916 if (!rdev->link_state)
917 netif_carrier_on(ndev);
918 }
919
920 return 0;
921}
922
848static int netvsc_set_channels(struct net_device *net, 923static int netvsc_set_channels(struct net_device *net,
849 struct ethtool_channels *channels) 924 struct ethtool_channels *channels)
850{ 925{
851 struct net_device_context *net_device_ctx = netdev_priv(net); 926 struct net_device_context *net_device_ctx = netdev_priv(net);
852 struct hv_device *dev = net_device_ctx->device_ctx;
853 struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev); 927 struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
854 unsigned int orig, count = channels->combined_count; 928 unsigned int orig, count = channels->combined_count;
855 struct netvsc_device_info device_info; 929 struct netvsc_device_info device_info;
856 bool was_opened; 930 int ret;
857 int ret = 0;
858 931
859 /* We do not support separate count for rx, tx, or other */ 932 /* We do not support separate count for rx, tx, or other */
860 if (count == 0 || 933 if (count == 0 ||
@@ -871,9 +944,6 @@ static int netvsc_set_channels(struct net_device *net,
871 return -EINVAL; 944 return -EINVAL;
872 945
873 orig = nvdev->num_chn; 946 orig = nvdev->num_chn;
874 was_opened = rndis_filter_opened(nvdev);
875 if (was_opened)
876 rndis_filter_close(nvdev);
877 947
878 memset(&device_info, 0, sizeof(device_info)); 948 memset(&device_info, 0, sizeof(device_info));
879 device_info.num_chn = count; 949 device_info.num_chn = count;
@@ -882,28 +952,17 @@ static int netvsc_set_channels(struct net_device *net,
882 device_info.recv_sections = nvdev->recv_section_cnt; 952 device_info.recv_sections = nvdev->recv_section_cnt;
883 device_info.recv_section_size = nvdev->recv_section_size; 953 device_info.recv_section_size = nvdev->recv_section_size;
884 954
885 rndis_filter_device_remove(dev, nvdev); 955 ret = netvsc_detach(net, nvdev);
956 if (ret)
957 return ret;
886 958
887 nvdev = rndis_filter_device_add(dev, &device_info); 959 ret = netvsc_attach(net, &device_info);
888 if (IS_ERR(nvdev)) { 960 if (ret) {
889 ret = PTR_ERR(nvdev);
890 device_info.num_chn = orig; 961 device_info.num_chn = orig;
891 nvdev = rndis_filter_device_add(dev, &device_info); 962 if (netvsc_attach(net, &device_info))
892 963 netdev_err(net, "restoring channel setting failed\n");
893 if (IS_ERR(nvdev)) {
894 netdev_err(net, "restoring channel setting failed: %ld\n",
895 PTR_ERR(nvdev));
896 return ret;
897 }
898 } 964 }
899 965
900 if (was_opened)
901 rndis_filter_open(nvdev);
902
903 /* We may have missed link change notifications */
904 net_device_ctx->last_reconfig = 0;
905 schedule_delayed_work(&net_device_ctx->dwork, 0);
906
907 return ret; 966 return ret;
908} 967}
909 968
@@ -969,10 +1028,8 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
969 struct net_device_context *ndevctx = netdev_priv(ndev); 1028 struct net_device_context *ndevctx = netdev_priv(ndev);
970 struct net_device *vf_netdev = rtnl_dereference(ndevctx->vf_netdev); 1029 struct net_device *vf_netdev = rtnl_dereference(ndevctx->vf_netdev);
971 struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev); 1030 struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev);
972 struct hv_device *hdev = ndevctx->device_ctx;
973 int orig_mtu = ndev->mtu; 1031 int orig_mtu = ndev->mtu;
974 struct netvsc_device_info device_info; 1032 struct netvsc_device_info device_info;
975 bool was_opened;
976 int ret = 0; 1033 int ret = 0;
977 1034
978 if (!nvdev || nvdev->destroy) 1035 if (!nvdev || nvdev->destroy)
@@ -985,11 +1042,6 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
985 return ret; 1042 return ret;
986 } 1043 }
987 1044
988 netif_device_detach(ndev);
989 was_opened = rndis_filter_opened(nvdev);
990 if (was_opened)
991 rndis_filter_close(nvdev);
992
993 memset(&device_info, 0, sizeof(device_info)); 1045 memset(&device_info, 0, sizeof(device_info));
994 device_info.num_chn = nvdev->num_chn; 1046 device_info.num_chn = nvdev->num_chn;
995 device_info.send_sections = nvdev->send_section_cnt; 1047 device_info.send_sections = nvdev->send_section_cnt;
@@ -997,35 +1049,27 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
997 device_info.recv_sections = nvdev->recv_section_cnt; 1049 device_info.recv_sections = nvdev->recv_section_cnt;
998 device_info.recv_section_size = nvdev->recv_section_size; 1050 device_info.recv_section_size = nvdev->recv_section_size;
999 1051
1000 rndis_filter_device_remove(hdev, nvdev); 1052 ret = netvsc_detach(ndev, nvdev);
1053 if (ret)
1054 goto rollback_vf;
1001 1055
1002 ndev->mtu = mtu; 1056 ndev->mtu = mtu;
1003 1057
1004 nvdev = rndis_filter_device_add(hdev, &device_info); 1058 ret = netvsc_attach(ndev, &device_info);
1005 if (IS_ERR(nvdev)) { 1059 if (ret)
1006 ret = PTR_ERR(nvdev); 1060 goto rollback;
1007
1008 /* Attempt rollback to original MTU */
1009 ndev->mtu = orig_mtu;
1010 nvdev = rndis_filter_device_add(hdev, &device_info);
1011
1012 if (vf_netdev)
1013 dev_set_mtu(vf_netdev, orig_mtu);
1014
1015 if (IS_ERR(nvdev)) {
1016 netdev_err(ndev, "restoring mtu failed: %ld\n",
1017 PTR_ERR(nvdev));
1018 return ret;
1019 }
1020 }
1021 1061
1022 if (was_opened) 1062 return 0;
1023 rndis_filter_open(nvdev);
1024 1063
1025 netif_device_attach(ndev); 1064rollback:
1065 /* Attempt rollback to original MTU */
1066 ndev->mtu = orig_mtu;
1026 1067
1027 /* We may have missed link change notifications */ 1068 if (netvsc_attach(ndev, &device_info))
1028 schedule_delayed_work(&ndevctx->dwork, 0); 1069 netdev_err(ndev, "restoring mtu failed\n");
1070rollback_vf:
1071 if (vf_netdev)
1072 dev_set_mtu(vf_netdev, orig_mtu);
1029 1073
1030 return ret; 1074 return ret;
1031} 1075}
@@ -1531,11 +1575,9 @@ static int netvsc_set_ringparam(struct net_device *ndev,
1531{ 1575{
1532 struct net_device_context *ndevctx = netdev_priv(ndev); 1576 struct net_device_context *ndevctx = netdev_priv(ndev);
1533 struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev); 1577 struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev);
1534 struct hv_device *hdev = ndevctx->device_ctx;
1535 struct netvsc_device_info device_info; 1578 struct netvsc_device_info device_info;
1536 struct ethtool_ringparam orig; 1579 struct ethtool_ringparam orig;
1537 u32 new_tx, new_rx; 1580 u32 new_tx, new_rx;
1538 bool was_opened;
1539 int ret = 0; 1581 int ret = 0;
1540 1582
1541 if (!nvdev || nvdev->destroy) 1583 if (!nvdev || nvdev->destroy)
@@ -1560,34 +1602,18 @@ static int netvsc_set_ringparam(struct net_device *ndev,
1560 device_info.recv_sections = new_rx; 1602 device_info.recv_sections = new_rx;
1561 device_info.recv_section_size = nvdev->recv_section_size; 1603 device_info.recv_section_size = nvdev->recv_section_size;
1562 1604
1563 netif_device_detach(ndev); 1605 ret = netvsc_detach(ndev, nvdev);
1564 was_opened = rndis_filter_opened(nvdev); 1606 if (ret)
1565 if (was_opened) 1607 return ret;
1566 rndis_filter_close(nvdev);
1567
1568 rndis_filter_device_remove(hdev, nvdev);
1569
1570 nvdev = rndis_filter_device_add(hdev, &device_info);
1571 if (IS_ERR(nvdev)) {
1572 ret = PTR_ERR(nvdev);
1573 1608
1609 ret = netvsc_attach(ndev, &device_info);
1610 if (ret) {
1574 device_info.send_sections = orig.tx_pending; 1611 device_info.send_sections = orig.tx_pending;
1575 device_info.recv_sections = orig.rx_pending; 1612 device_info.recv_sections = orig.rx_pending;
1576 nvdev = rndis_filter_device_add(hdev, &device_info);
1577 if (IS_ERR(nvdev)) {
1578 netdev_err(ndev, "restoring ringparam failed: %ld\n",
1579 PTR_ERR(nvdev));
1580 return ret;
1581 }
1582 }
1583 1613
1584 if (was_opened) 1614 if (netvsc_attach(ndev, &device_info))
1585 rndis_filter_open(nvdev); 1615 netdev_err(ndev, "restoring ringparam failed");
1586 netif_device_attach(ndev); 1616 }
1587
1588 /* We may have missed link change notifications */
1589 ndevctx->last_reconfig = 0;
1590 schedule_delayed_work(&ndevctx->dwork, 0);
1591 1617
1592 return ret; 1618 return ret;
1593} 1619}
@@ -2072,8 +2098,8 @@ no_net:
2072static int netvsc_remove(struct hv_device *dev) 2098static int netvsc_remove(struct hv_device *dev)
2073{ 2099{
2074 struct net_device_context *ndev_ctx; 2100 struct net_device_context *ndev_ctx;
2075 struct net_device *vf_netdev; 2101 struct net_device *vf_netdev, *net;
2076 struct net_device *net; 2102 struct netvsc_device *nvdev;
2077 2103
2078 net = hv_get_drvdata(dev); 2104 net = hv_get_drvdata(dev);
2079 if (net == NULL) { 2105 if (net == NULL) {
@@ -2083,10 +2109,14 @@ static int netvsc_remove(struct hv_device *dev)
2083 2109
2084 ndev_ctx = netdev_priv(net); 2110 ndev_ctx = netdev_priv(net);
2085 2111
2086 netif_device_detach(net);
2087
2088 cancel_delayed_work_sync(&ndev_ctx->dwork); 2112 cancel_delayed_work_sync(&ndev_ctx->dwork);
2089 2113
2114 rcu_read_lock();
2115 nvdev = rcu_dereference(ndev_ctx->nvdev);
2116
2117 if (nvdev)
2118 cancel_work_sync(&nvdev->subchan_work);
2119
2090 /* 2120 /*
2091 * Call to the vsc driver to let it know that the device is being 2121 * Call to the vsc driver to let it know that the device is being
2092 * removed. Also blocks mtu and channel changes. 2122 * removed. Also blocks mtu and channel changes.
@@ -2096,11 +2126,13 @@ static int netvsc_remove(struct hv_device *dev)
2096 if (vf_netdev) 2126 if (vf_netdev)
2097 netvsc_unregister_vf(vf_netdev); 2127 netvsc_unregister_vf(vf_netdev);
2098 2128
2129 if (nvdev)
2130 rndis_filter_device_remove(dev, nvdev);
2131
2099 unregister_netdevice(net); 2132 unregister_netdevice(net);
2100 2133
2101 rndis_filter_device_remove(dev,
2102 rtnl_dereference(ndev_ctx->nvdev));
2103 rtnl_unlock(); 2134 rtnl_unlock();
2135 rcu_read_unlock();
2104 2136
2105 hv_set_drvdata(dev, NULL); 2137 hv_set_drvdata(dev, NULL);
2106 2138
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 963314eb3226..a6ec41c399d6 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -1118,6 +1118,7 @@ void rndis_set_subchannel(struct work_struct *w)
1118 for (i = 0; i < VRSS_SEND_TAB_SIZE; i++) 1118 for (i = 0; i < VRSS_SEND_TAB_SIZE; i++)
1119 ndev_ctx->tx_table[i] = i % nvdev->num_chn; 1119 ndev_ctx->tx_table[i] = i % nvdev->num_chn;
1120 1120
1121 netif_device_attach(ndev);
1121 rtnl_unlock(); 1122 rtnl_unlock();
1122 return; 1123 return;
1123 1124
@@ -1128,6 +1129,8 @@ failed:
1128 1129
1129 nvdev->max_chn = 1; 1130 nvdev->max_chn = 1;
1130 nvdev->num_chn = 1; 1131 nvdev->num_chn = 1;
1132
1133 netif_device_attach(ndev);
1131unlock: 1134unlock:
1132 rtnl_unlock(); 1135 rtnl_unlock();
1133} 1136}
@@ -1330,6 +1333,10 @@ out:
1330 net_device->num_chn = 1; 1333 net_device->num_chn = 1;
1331 } 1334 }
1332 1335
1336 /* No sub channels, device is ready */
1337 if (net_device->num_chn == 1)
1338 netif_device_attach(net);
1339
1333 return net_device; 1340 return net_device;
1334 1341
1335err_dev_remv: 1342err_dev_remv:
@@ -1342,9 +1349,6 @@ void rndis_filter_device_remove(struct hv_device *dev,
1342{ 1349{
1343 struct rndis_device *rndis_dev = net_dev->extension; 1350 struct rndis_device *rndis_dev = net_dev->extension;
1344 1351
1345 /* Don't try and setup sub channels if about to halt */
1346 cancel_work_sync(&net_dev->subchan_work);
1347
1348 /* Halt and release the rndis device */ 1352 /* Halt and release the rndis device */
1349 rndis_filter_halt_device(rndis_dev); 1353 rndis_filter_halt_device(rndis_dev);
1350 1354
@@ -1368,10 +1372,3 @@ int rndis_filter_close(struct netvsc_device *nvdev)
1368 1372
1369 return rndis_filter_close_device(nvdev->extension); 1373 return rndis_filter_close_device(nvdev->extension);
1370} 1374}
1371
1372bool rndis_filter_opened(const struct netvsc_device *nvdev)
1373{
1374 const struct rndis_device *dev = nvdev->extension;
1375
1376 return dev->state == RNDIS_DEV_DATAINITIALIZED;
1377}