Date: Thu, 03 Nov 2005 06:57:42 -0600 (CST) From: Sergey Babkin <babkin@verizon.net> To: "M. Warner Losh" <imp@bsdimp.com>, scottl@samsco.org Cc: freebsd-hackers@freebsd.org Subject: Re: Re: locking in a device driver Message-ID: <20669850.1131022662391.JavaMail.root@vms061.mailsrvcs.net>
next in thread | raw e-mail | index | archive | help
>From: "M. Warner Losh" <imp@bsdimp.com> > Scott Long <scottl@samsco.org> writes: >: Dinesh Nair wrote: >: > >: > >: > On 11/03/05 03:12 Warner Losh said the following: >: > >: >> Yes. if you tsleep with signals enabled, the periodic timer will go >: >> off, and you'll return early. This typically isn't what you want >: >> either. >: > >: > >: > looks like i've got a lot of work to do, poring thru all the ioctls for >: > the device and trying to use another method to wait instead of tsleep(). >: >: Note that a thread can block on select/poll in 4.x and still allow other >: threads to run. I used this to solve a very similar problem to your in >: a 4.x app of mine. I have the app thread wait on select() on the device >: node for the driver. When the driver gets to a state when an ioctl >: won't block (like data being available to read), then it does the >: appropriate magic in it's d_poll method. select in userland sees this, >: allows the thread to resume running, and the thread then calls ioctl. >: Of course you have to be careful that you don't have multiple threads >: competing for the same data or that the data won't somehow disappear >: before the ioctl call runs. But it does work. Look at the aac(4) >: driver for my example of this. > >Yes. If you have the ability to know that an ioctl won't block before >you call it, that would work too. This method is a little trickier, >like you say, but can be made to work. I've also seen ioctls that Maybe it can be fixed in the kernel without too much trouble. Basically, the trick would be to start another kernel thread when the first one blocks. Then the original one can be left executing the ioctl while the new one continues the work. Then of cours ethere should be some notification mechanism that the ioctl has completed. The new thread can start in a signal handler, kind of like what UnixWare does (and I believe Solaris too): they have an M:N model where M user threads are scheduled on N kernel threads. When all the kernel threads of a process get blocked, a signal is sent thread which handler then starts a new kernel thread if there are any runnable user threads. Hm, suppose we have a per-process property "is threaded" that would be set by the threads library. Any blocking calls (tsleep() and such) would check it, and if it's set than immediately post this "all threads are blocked" signal. Then the library can catch it and handle in some useful way, maybe doing an rfork() or just running another user thread and returning to this one later. -SB
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20669850.1131022662391.JavaMail.root>