Date: Wed, 13 Feb 2013 10:53:02 -0500 From: John Baldwin <jhb@freebsd.org> To: Hans Petter Selasky <hselasky@c2i.net> Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r246614 - head/sys/dev/usb/wlan Message-ID: <201302131053.02740.jhb@freebsd.org> In-Reply-To: <201302120843.32349.hselasky@c2i.net> References: <201302101036.r1AAaHs1022034@svn.freebsd.org> <201302111133.02161.jhb@freebsd.org> <201302120843.32349.hselasky@c2i.net>
next in thread | previous in thread | raw e-mail | index | archive | help
On Tuesday, February 12, 2013 2:43:32 am Hans Petter Selasky wrote: > On Monday 11 February 2013 17:33:02 John Baldwin wrote: > > On Sunday, February 10, 2013 5:36:17 am Hans Petter Selasky wrote: > > > Author: hselasky > > > Date: Sun Feb 10 10:36:16 2013 > > > New Revision: 246614 > > > URL: http://svnweb.freebsd.org/changeset/base/246614 > > > > > > Log: > > > - Streamline detach logic in wlan drivers, so that > > > > > > freed memory cannot be used during detach. > > > > > > - Remove all panic() calls from the urtw driver because > > > > > > panic() is not appropriate here. > > > > > > - Remove redundant checks for device detached in > > > > > > device detach callbacks. > > > > > > - Use DEVMETHOD_END to mark end of device methods. > > > > Using a detached flag to bail from ioctl generally means you are doing > > things wrong in detach. The correct solution is to always detach your > > ifnet first, then start tearing down other state. In general with device > > detach routines the first order of business is removing external > > references such as character devices, ifnets, etc. and only start shutting > > down the hardware and releasing state once those steps have completed. > > Hi, > > What I can do to solve the problem is to lock a mutex while detaching. Is the > ifnet detach routine non-blocking? > > Why do I say that? It is because we are in a chicken-egg situation. USB is > feeding data into ifnet and ifnet is feeding data into USB. Each stack is > running under its own lock. The current approach is: > > 1) Stop data traffic in both directions > 2) Make sure no more init happens (ioctl fix) > 3) Free USB and IFNET. > > I see currently no way I can atomically stop all traffic and prevent futher > init at the same time, while holding a single mutex. Do you? You shouldn't call routines that can drain like if_detach() or destroy_dev() or the like while holding any mutexes period. I think you need a 0) step which is "detach external consumers" including cdev's (destroy_dev()) and ifnet's (if_detach). Once both of those routines have finished, you can then proceed with actually stopping device operation, and 2) is not needed as it can't happen once 0) has finished. When a device has both an ifnet and a cdev you may need something to handle the case of one part being dead but not the other. For now you can call if_detach() first as it doesn't sleep (though that is a bug). The real fix for this case (and things like tun(4) can need this as well) is to have a way to call just the non-blocking parts of things like if_detach() and destroy_dev() first to mark the relevant portions as dead and then follow those with blocking calls that do the drain. This is all part of step 0 though. -- John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302131053.02740.jhb>