Skip to content

Commit b103f35

Browse files
Wei Liudavem330
authored andcommitted
xen-netback: enable user to unload netback module
This patch enables user to unload netback module, which is useful when user wants to upgrade to a newer netback module without rebooting the host. Netfront cannot handle netback removal event. As we cannot fix all possible frontends we add module get / put along with vif get / put to avoid mis-unloading of netback. To unload netback module, user needs to shutdown all VMs or migrate them to another host or unplug all vifs before hand. Signed-off-by: Wei Liu <[email protected]> Acked-by: Ian Campbell <[email protected]>¬ Signed-off-by: David S. Miller <[email protected]>
1 parent f1db320 commit b103f35

File tree

4 files changed

+44
-1
lines changed

4 files changed

+44
-1
lines changed

drivers/net/xen-netback/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ void xenvif_get(struct xenvif *vif);
120120
void xenvif_put(struct xenvif *vif);
121121

122122
int xenvif_xenbus_init(void);
123+
void xenvif_xenbus_fini(void);
123124

124125
int xenvif_schedulable(struct xenvif *vif);
125126

drivers/net/xen-netback/interface.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,8 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
316316
if (vif->irq)
317317
return 0;
318318

319+
__module_get(THIS_MODULE);
320+
319321
err = xen_netbk_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref);
320322
if (err < 0)
321323
goto err;
@@ -343,6 +345,7 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
343345
err_unmap:
344346
xen_netbk_unmap_frontend_rings(vif);
345347
err:
348+
module_put(THIS_MODULE);
346349
return err;
347350
}
348351

@@ -360,18 +363,32 @@ void xenvif_carrier_off(struct xenvif *vif)
360363

361364
void xenvif_disconnect(struct xenvif *vif)
362365
{
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+
363372
if (netif_carrier_ok(vif->dev))
364373
xenvif_carrier_off(vif);
365374

366375
atomic_dec(&vif->refcnt);
367376
wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0);
368377

369-
if (vif->irq)
378+
if (vif->irq) {
370379
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+
}
371385

372386
unregister_netdev(vif->dev);
373387

374388
xen_netbk_unmap_frontend_rings(vif);
375389

376390
free_netdev(vif->dev);
391+
392+
if (need_module_put)
393+
module_put(THIS_MODULE);
377394
}

drivers/net/xen-netback/netback.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,5 +1949,25 @@ static int __init netback_init(void)
19491949

19501950
module_init(netback_init);
19511951

1952+
static 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+
}
1970+
module_exit(netback_fini);
1971+
19521972
MODULE_LICENSE("Dual BSD/GPL");
19531973
MODULE_ALIAS("xen-backend:vif");

drivers/net/xen-netback/xenbus.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,3 +485,8 @@ int xenvif_xenbus_init(void)
485485
{
486486
return xenbus_register_backend(&netback_driver);
487487
}
488+
489+
void xenvif_xenbus_fini(void)
490+
{
491+
return xenbus_unregister_driver(&netback_driver);
492+
}

0 commit comments

Comments
 (0)