aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netback/interface.c
diff options
context:
space:
mode:
authorPaul Durrant <Paul.Durrant@citrix.com>2013-09-17 12:46:08 -0400
committerDavid S. Miller <davem@davemloft.net>2013-09-19 14:03:51 -0400
commit279f438e36c0a70b23b86d2090aeec50155034a9 (patch)
tree2321278098da43c72508e97edbf8a76f2ee63683 /drivers/net/xen-netback/interface.c
parentbd784a140712fd06674f2240eecfc4ccae421129 (diff)
xen-netback: Don't destroy the netdev until the vif is shut down
Without this patch, if a frontend cycles through states Closing and Closed (which Windows frontends need to do) then the netdev will be destroyed and requires re-invocation of hotplug scripts to restore state before the frontend can move to Connected. Thus when udev is not in use the backend gets stuck in InitWait. With this patch, the netdev is left alone whilst the backend is still online and is only de-registered and freed just prior to destroying the vif (which is also nicely symmetrical with the netdev allocation and registration being done during probe) so no re-invocation of hotplug scripts is required. Signed-off-by: Paul Durrant <paul.durrant@citrix.com> Cc: David Vrabel <david.vrabel@citrix.com> Cc: Wei Liu <wei.liu2@citrix.com> Cc: Ian Campbell <ian.campbell@citrix.com> Acked-by: Wei Liu <wei.liu2@citrix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/xen-netback/interface.c')
-rw-r--r--drivers/net/xen-netback/interface.c26
1 files changed, 10 insertions, 16 deletions
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 77fee1d51fb2..01bb854c7f62 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -353,6 +353,9 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
353 } 353 }
354 354
355 netdev_dbg(dev, "Successfully created xenvif\n"); 355 netdev_dbg(dev, "Successfully created xenvif\n");
356
357 __module_get(THIS_MODULE);
358
356 return vif; 359 return vif;
357} 360}
358 361
@@ -366,8 +369,6 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
366 if (vif->tx_irq) 369 if (vif->tx_irq)
367 return 0; 370 return 0;
368 371
369 __module_get(THIS_MODULE);
370
371 err = xenvif_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref); 372 err = xenvif_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref);
372 if (err < 0) 373 if (err < 0)
373 goto err; 374 goto err;
@@ -452,12 +453,6 @@ void xenvif_carrier_off(struct xenvif *vif)
452 453
453void xenvif_disconnect(struct xenvif *vif) 454void xenvif_disconnect(struct xenvif *vif)
454{ 455{
455 /* Disconnect funtion might get called by generic framework
456 * even before vif connects, so we need to check if we really
457 * need to do a module_put.
458 */
459 int need_module_put = 0;
460
461 if (netif_carrier_ok(vif->dev)) 456 if (netif_carrier_ok(vif->dev))
462 xenvif_carrier_off(vif); 457 xenvif_carrier_off(vif);
463 458
@@ -468,23 +463,22 @@ void xenvif_disconnect(struct xenvif *vif)
468 unbind_from_irqhandler(vif->tx_irq, vif); 463 unbind_from_irqhandler(vif->tx_irq, vif);
469 unbind_from_irqhandler(vif->rx_irq, vif); 464 unbind_from_irqhandler(vif->rx_irq, vif);
470 } 465 }
471 /* vif->irq is valid, we had a module_get in 466 vif->tx_irq = 0;
472 * xenvif_connect.
473 */
474 need_module_put = 1;
475 } 467 }
476 468
477 if (vif->task) 469 if (vif->task)
478 kthread_stop(vif->task); 470 kthread_stop(vif->task);
479 471
472 xenvif_unmap_frontend_rings(vif);
473}
474
475void xenvif_free(struct xenvif *vif)
476{
480 netif_napi_del(&vif->napi); 477 netif_napi_del(&vif->napi);
481 478
482 unregister_netdev(vif->dev); 479 unregister_netdev(vif->dev);
483 480
484 xenvif_unmap_frontend_rings(vif);
485
486 free_netdev(vif->dev); 481 free_netdev(vif->dev);
487 482
488 if (need_module_put) 483 module_put(THIS_MODULE);
489 module_put(THIS_MODULE);
490} 484}