[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH/RFC] Properly rmmod of netfront device


  • To: xen-devel@xxxxxxxxxxxxxxxxxxx
  • From: Glauber de Oliveira Costa <gcosta@xxxxxxxxxx>
  • Date: Fri, 17 Nov 2006 10:34:22 -0200
  • Delivery-date: Fri, 17 Nov 2006 04:34:30 -0800
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

We found problems while removing the netfront device in a guest kernel.

Here follows a first solution attempt, and comments are very welcome. 
A more detailed description can be found in the commit log. 

Thanks,

-- 
Glauber de Oliveira Costa
Red Hat Inc.
"Free as in Freedom"
# HG changeset patch
# User gcosta@xxxxxxxxxx
# Date 1163770243 18000
# Node ID 47fcd5f768fef50cba2fc6dbadc7b75de55e88a5
# Parent  822e0f23a8cb17be0457d6b030af2a4fe6c4d7de
[LINUX] netfront module not beging able to be rmmod'd

Current attempts to remove the netfront module leads to BUG()s
being triggered. It is because the call path of a module removal
is different from device detach via backend. In the former,
netfront_closing() (which unregisters the device) is never called.

Solution is to call the proper deinitialization routines in module
removal, in case they were not called before (dev->state !=
XenbusStateClosed). At this point, backend still holds gnttab entries,
and we wait for it to finish (while at be level, it frees the proper
structures and releases the entries).

Last, doing it leaves the device in state 6 in the backend. When
initializing again, we change our state to XenbusStateInitialising,
forcing the backend to see it and start init negotiation again

Signed-off-by: Glauber de Oliveira Costa <gcosta@xxxxxxxxxx>

diff -r 822e0f23a8cb -r 47fcd5f768fe 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Nov 17 07:53:00 
2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Nov 17 08:30:43 
2006 -0500
@@ -242,6 +242,10 @@ static void frontend_changed(struct xenb
 
        case XenbusStateClosed:
                xenbus_switch_state(dev, XenbusStateClosed);
+               if (be->netif) {
+                       netif_disconnect(be->netif);
+                       be->netif = NULL;
+               }
                if (xenbus_dev_is_online(dev))
                        break;
                /* fall through if not online */
diff -r 822e0f23a8cb -r 47fcd5f768fe 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Fri Nov 17 
07:53:00 2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Fri Nov 17 
08:30:43 2006 -0500
@@ -501,6 +501,11 @@ static int setup_device(struct xenbus_de
        info->irq = err;
        return 0;
 
+       /* backend will ignore this state change unless it's currently in
+        * Closed state. But then, we wan't it to reconnect, since we're now
+        * back */
+       xenbus_switch_state(dev, XenbusStateInitialising);
+
  fail:
        return err;
 }
@@ -2014,8 +2019,21 @@ static int __devexit netfront_remove(str
 static int __devexit netfront_remove(struct xenbus_device *dev)
 {
        struct netfront_info *info = dev->dev.driver_data;
+       unsigned long timeout = jiffies + 2*HZ;
 
        DPRINTK("%s\n", dev->nodename);
+       if ( dev->state != XenbusStateClosed ){
+               close_netdev(info);
+               xenbus_frontend_closed(dev);
+       }
+
+       /* Give a chance for the foreing access to end in a reasonable ammount 
of time
+        * if it's still happening, there is little we can do here */
+       while ( gnttab_query_foreign_access(info->rx_ring_ref) ){
+               if ( time_after(jiffies, timeout) ) 
+                       break;
+               schedule_timeout_interruptible(HZ/10);
+       }
 
        netif_disconnect_backend(info);
        free_netdev(info->netdev);
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.