aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaiyang Zhang <haiyangz@microsoft.com>2013-12-20 19:52:31 -0500
committerDavid S. Miller <davem@davemloft.net>2013-12-21 22:23:06 -0500
commita68f9614614749727286f675d15f1e09d13cb54a (patch)
tree1236f0c9e306e2c527846addfb34f7690cc3163d
parent965cdea825693c821d200e38fac9402cde6dce6a (diff)
hyperv: Fix race between probe and open calls
Moving the register_netdev to the end of probe to prevent possible open call happens before NetVSP is connected. Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> Reviewed-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/hyperv/netvsc_drv.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index f8135725bcf6..71baeb3ed905 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -261,9 +261,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
261 struct sk_buff *skb; 261 struct sk_buff *skb;
262 262
263 net = ((struct netvsc_device *)hv_get_drvdata(device_obj))->ndev; 263 net = ((struct netvsc_device *)hv_get_drvdata(device_obj))->ndev;
264 if (!net) { 264 if (!net || net->reg_state != NETREG_REGISTERED) {
265 netdev_err(net, "got receive callback but net device"
266 " not initialized yet\n");
267 packet->status = NVSP_STAT_FAIL; 265 packet->status = NVSP_STAT_FAIL;
268 return 0; 266 return 0;
269 } 267 }
@@ -435,19 +433,11 @@ static int netvsc_probe(struct hv_device *dev,
435 SET_ETHTOOL_OPS(net, &ethtool_ops); 433 SET_ETHTOOL_OPS(net, &ethtool_ops);
436 SET_NETDEV_DEV(net, &dev->device); 434 SET_NETDEV_DEV(net, &dev->device);
437 435
438 ret = register_netdev(net);
439 if (ret != 0) {
440 pr_err("Unable to register netdev.\n");
441 free_netdev(net);
442 goto out;
443 }
444
445 /* Notify the netvsc driver of the new device */ 436 /* Notify the netvsc driver of the new device */
446 device_info.ring_size = ring_size; 437 device_info.ring_size = ring_size;
447 ret = rndis_filter_device_add(dev, &device_info); 438 ret = rndis_filter_device_add(dev, &device_info);
448 if (ret != 0) { 439 if (ret != 0) {
449 netdev_err(net, "unable to add netvsc device (ret %d)\n", ret); 440 netdev_err(net, "unable to add netvsc device (ret %d)\n", ret);
450 unregister_netdev(net);
451 free_netdev(net); 441 free_netdev(net);
452 hv_set_drvdata(dev, NULL); 442 hv_set_drvdata(dev, NULL);
453 return ret; 443 return ret;
@@ -456,7 +446,13 @@ static int netvsc_probe(struct hv_device *dev,
456 446
457 netif_carrier_on(net); 447 netif_carrier_on(net);
458 448
459out: 449 ret = register_netdev(net);
450 if (ret != 0) {
451 pr_err("Unable to register netdev.\n");
452 rndis_filter_device_remove(dev);
453 free_netdev(net);
454 }
455
460 return ret; 456 return ret;
461} 457}
462 458