mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Reorganizes network frontend device unregister and removal, so that
occur in the right order and succeed. Now on Closing state we: - stop queue - unbind irq - unregister the device On removal: - end foreign access to TX and RX pages (we cannot do this before) - free_netdev, doing the last stage of destroying an allocated device Makes xm-test network "03_attach_detach_multiple_pos" pass: http://xmtest.dague.org/cgi-bin/display?view=single&testid=1068 Signed-off-by: Murillo F. Bernardes <mfb@br.ibm.com>
This commit is contained in:
1 parent
914dc0db80
commit
ada4e79b32
1 file changed
+26
-27
@@ -1209,33 +1209,14 @@ static int netfront_remove(struct xenbus_device *dev)
|
||||
|
||||
DPRINTK("%s\n", dev->nodename);
|
||||
|
||||
netif_free(info);
|
||||
kfree(info);
|
||||
netif_disconnect_backend(info);
|
||||
free_netdev(info->netdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void netif_free(struct netfront_info *info)
|
||||
{
|
||||
netif_disconnect_backend(info);
|
||||
close_netdev(info);
|
||||
}
|
||||
|
||||
|
||||
static void close_netdev(struct netfront_info *info)
|
||||
{
|
||||
if (info->netdev) {
|
||||
#ifdef CONFIG_PROC_FS
|
||||
xennet_proc_delif(info->netdev);
|
||||
#endif
|
||||
unregister_netdev(info->netdev);
|
||||
info->netdev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void netif_disconnect_backend(struct netfront_info *info)
|
||||
{
|
||||
/* Stop old i/f to prevent errors whilst we rebuild the state. */
|
||||
spin_lock_irq(&info->tx_lock);
|
||||
@@ -1245,18 +1226,36 @@ static void netif_disconnect_backend(struct netfront_info *info)
|
||||
spin_unlock(&info->rx_lock);
|
||||
spin_unlock_irq(&info->tx_lock);
|
||||
|
||||
end_access(info->tx_ring_ref, info->tx.sring);
|
||||
end_access(info->rx_ring_ref, info->rx.sring);
|
||||
info->tx_ring_ref = GRANT_INVALID_REF;
|
||||
info->rx_ring_ref = GRANT_INVALID_REF;
|
||||
info->tx.sring = NULL;
|
||||
info->rx.sring = NULL;
|
||||
#ifdef CONFIG_PROC_FS
|
||||
xennet_proc_delif(info->netdev);
|
||||
#endif
|
||||
|
||||
if (info->irq)
|
||||
unbind_from_irqhandler(info->irq, info->netdev);
|
||||
info->evtchn = info->irq = 0;
|
||||
|
||||
del_timer_sync(&info->rx_refill_timer);
|
||||
|
||||
unregister_netdev(info->netdev);
|
||||
}
|
||||
|
||||
|
||||
static void netif_disconnect_backend(struct netfront_info *info)
|
||||
{
|
||||
end_access(info->tx_ring_ref, info->tx.sring);
|
||||
end_access(info->rx_ring_ref, info->rx.sring);
|
||||
info->tx_ring_ref = GRANT_INVALID_REF;
|
||||
info->rx_ring_ref = GRANT_INVALID_REF;
|
||||
info->tx.sring = NULL;
|
||||
info->rx.sring = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void netif_free(struct netfront_info *info)
|
||||
{
|
||||
close_netdev(info);
|
||||
netif_disconnect_backend(info);
|
||||
free_netdev(info->netdev);
|
||||
}
|
||||
|
||||
|
||||
|
||||