[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH/RFC] Properly rmmod of netfront device
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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |