Date: Tue, 12 Jan 2010 08:14:08 -0500 From: John Baldwin <jhb@freebsd.org> To: freebsd-hackers@freebsd.org Cc: Max Laier <max@love2party.net>, "H.Fazaeli" <fazaeli@sepehrs.com> Subject: Re: uiomove and mutex Message-ID: <201001120814.08397.jhb@freebsd.org> In-Reply-To: <201001112122.43000.max@love2party.net> References: <4B4B7A7F.2090808@sepehrs.com> <201001112122.43000.max@love2party.net>
next in thread | previous in thread | raw e-mail | index | archive | help
On Monday 11 January 2010 3:22:42 pm Max Laier wrote: > On Monday 11 January 2010 20:22:39 H.Fazaeli wrote: > > dear gurus > > > > man mutex(9) states that: > > > > "No mutexes should be held (except for Giant) across functions which > > access memory in userspace, such as copyin(9), copyout(9), uiomove(9), > > fuword(9), etc. No locks are needed when calling these functions." > > > > can someone pls. explain why it is so? > > Any memory access to user memory (unless the memory has been wired down > before) can result in a swap in from secondary storage, which - in turn - > results in a sleep. Most locks are not allowed to be held over a sleep. > > See locking(9) for details. > > > Suppose I have a kernel buffer to which kernel writes and > > userland processes read via a character device. In the device > > read method, If we unlock the mutex just before uiomove, is it > > guaranteed that kernel does not write to the buffer in the middle > > of uiomove? If yes, how? What is the solution in such a situation? > > rwlocks? an intermediate buffer? > > sx(9) is one possibility. The other way is to use a pointer or state that you > modify while holding the mutex: > > Thread1: > > lock(&mtx); > buffer_in_use=1; > unlock(&mtx); > > uiomove() > > lock(&mtx); > buffer_in_use=0; > wakeup(&buffer_in_use); > unlock(&mtx); > > Thread2: > > lock(&mtx); > while(buffer_in_use) > mlseep(&buffer_in_use, &mtx, ...) > do_stuff_to_the_buffer(); > unlock(&mtx); Note that a simple flag like this is actually a slower version of using an sx lock. If you have a very simple driver I would just use an sx lock. If you later find that you need to optimize it then you can look at doing something fancier. If you already have other state you are frobbing that includes the equivalent of a buffer_in_use flag then an approach like the above may be ok instead of an sx lock. -- John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001120814.08397.jhb>