aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/xen-netback/common.h1
-rw-r--r--drivers/net/xen-netback/interface.c19
-rw-r--r--drivers/net/xen-netback/netback.c20
-rw-r--r--drivers/net/xen-netback/xenbus.c5
4 files changed, 44 insertions, 1 deletions
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
index 9d7f1723dd8f..6102a6c59f4e 100644
--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -120,6 +120,7 @@ void xenvif_get(struct xenvif *vif);
120void xenvif_put(struct xenvif *vif); 120void xenvif_put(struct xenvif *vif);
121 121
122int xenvif_xenbus_init(void); 122int xenvif_xenbus_init(void);
123void xenvif_xenbus_fini(void);
123 124
124int xenvif_schedulable(struct xenvif *vif); 125int xenvif_schedulable(struct xenvif *vif);
125 126
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index d98414168485..82202c2b1bd1 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -316,6 +316,8 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
316 if (vif->irq) 316 if (vif->irq)
317 return 0; 317 return 0;
318 318
319 __module_get(THIS_MODULE);
320
319 err = xen_netbk_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref); 321 err = xen_netbk_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref);
320 if (err < 0) 322 if (err < 0)
321 goto err; 323 goto err;
@@ -343,6 +345,7 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
343err_unmap: 345err_unmap:
344 xen_netbk_unmap_frontend_rings(vif); 346 xen_netbk_unmap_frontend_rings(vif);
345err: 347err:
348 module_put(THIS_MODULE);
346 return err; 349 return err;
347} 350}
348 351
@@ -360,18 +363,32 @@ void xenvif_carrier_off(struct xenvif *vif)
360 363
361void xenvif_disconnect(struct xenvif *vif) 364void xenvif_disconnect(struct xenvif *vif)
362{ 365{
366 /* Disconnect funtion might get called by generic framework
367 * even before vif connects, so we need to check if we really
368 * need to do a module_put.
369 */
370 int need_module_put = 0;
371
363 if (netif_carrier_ok(vif->dev)) 372 if (netif_carrier_ok(vif->dev))
364 xenvif_carrier_off(vif); 373 xenvif_carrier_off(vif);
365 374
366 atomic_dec(&vif->refcnt); 375 atomic_dec(&vif->refcnt);
367 wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0); 376 wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0);
368 377
369 if (vif->irq) 378 if (vif->irq) {
370 unbind_from_irqhandler(vif->irq, vif); 379 unbind_from_irqhandler(vif->irq, vif);
380 /* vif->irq is valid, we had a module_get in
381 * xenvif_connect.
382 */
383 need_module_put = 1;
384 }
371 385
372 unregister_netdev(vif->dev); 386 unregister_netdev(vif->dev);
373 387
374 xen_netbk_unmap_frontend_rings(vif); 388 xen_netbk_unmap_frontend_rings(vif);
375 389
376 free_netdev(vif->dev); 390 free_netdev(vif->dev);
391
392 if (need_module_put)
393 module_put(THIS_MODULE);
377} 394}
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 295a9c267df4..2d9477fd900f 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -1949,5 +1949,25 @@ failed_init:
1949 1949
1950module_init(netback_init); 1950module_init(netback_init);
1951 1951
1952static void __exit netback_fini(void)
1953{
1954 int i, j;
1955
1956 xenvif_xenbus_fini();
1957
1958 for (i = 0; i < xen_netbk_group_nr; i++) {
1959 struct xen_netbk *netbk = &xen_netbk[i];
1960 del_timer_sync(&netbk->net_timer);
1961 kthread_stop(netbk->task);
1962 for (j = 0; j < MAX_PENDING_REQS; j++) {
1963 if (netbk->mmap_pages[i])
1964 __free_page(netbk->mmap_pages[i]);
1965 }
1966 }
1967
1968 vfree(xen_netbk);
1969}
1970module_exit(netback_fini);
1971
1952MODULE_LICENSE("Dual BSD/GPL"); 1972MODULE_LICENSE("Dual BSD/GPL");
1953MODULE_ALIAS("xen-backend:vif"); 1973MODULE_ALIAS("xen-backend:vif");
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index 410018c4c528..d230c145660c 100644
--- a/drivers/net/xen-netback/xenbus.c
+++ b/drivers/net/xen-netback/xenbus.c
@@ -485,3 +485,8 @@ int xenvif_xenbus_init(void)
485{ 485{
486 return xenbus_register_backend(&netback_driver); 486 return xenbus_register_backend(&netback_driver);
487} 487}
488
489void xenvif_xenbus_fini(void)
490{
491 return xenbus_unregister_driver(&netback_driver);
492}