panic by unlocking of mutex in KLD

Mateusz Guzik mjguzik at gmail.com
Mon Jan 12 12:22:09 PST 2009


On Mon, Jan 12, 2009 at 08:49:59PM +0100, Alexej Sokolov wrote:
> 2009/1/12 Mateusz Guzik <mjguzik at gmail.com>
> 
> > On Mon, Jan 12, 2009 at 07:16:51PM +0100, Alexej Sokolov wrote:
> > > 2009/1/12 Mateusz Guzik <mjguzik at gmail.com>
> > >
> > > > On Mon, Jan 12, 2009 at 05:19:56PM +0100, Alexej Sokolov wrote:
> > > > > 2009/1/12 Mateusz Guzik <mjguzik at gmail.com>
> > > > > > Mutexes have owners. It panics on loading because processes cannot
> > > > > > return to userland with locks held.
> > > > >
> > > > > i am not sure about it. Some time ago i implemented a charecter
> > device
> > > > with
> > > > > two syscalls: write, read. "write" lock the mutex and  "read" unlock
> > it.
> > > > The
> > > > > user space programm opens device, then mekes "write" (mutex will held
> > in
> > > > > kernel), goes back to user space, then makes "read" (mutex will
> > unlocked
> > > > in
> > > > > kernel) and it all run without panic. If needed i can post the source
> > > > code.
> > > > >
> > > >
> > > > Do you have kernel compiled with WITNESS? At least on -CURRENT the
> > > > kernel panicked like this (while loading your module):
> > > >
> > > > System call kldload returning with 1 locks held
> > >
> > > My kernel is compiled without WITNESS. And it allows to lock mutex in one
> > > systcall (for example "write") and to unlock it in other ("read").
> > > Do you mean it is "very bad idea" to do something like this ?
> > > I could not find anywhere in the documentation that a it is not allowed
> > to
> > > return in the user space with a locked mutex.
> > > Can you give me some reference on man page, source code or something
> > other
> > > from where can I understand it ?
> > >
> >
> > Locks are used to synchronize access to data changeable by other
> > threads. I don't know if I'm correct here, but let's consider the
> > following situation: your process grabs a mutex and returns to userland,
> > then it's killed due to segmentation violation. This mutex should (and
> > can be) unlocked on exit, but the state of data protected by it is
> > unknown. (For example your process was killed while inserting something
> > into linked list.) So even if the kernel could be guided to unlock it on
> > exit, the data could be in inconsistent state.
> >
> > Also your locking scheme doesn't make much sense. Consider this:
> >        proc1 calls write on your cdev
> > but in the meantime
> >        proc2 calls read on your cdev
> >
> > So you get panic because proc1 was writing some data. (attempt to unlock
> > mutex locked by proc1) Even if the kernel wouldn't panic, proc2 would
> > read inconsistend data because proc1 was writing. Proper solution is to
> > lock mutex before and after reading/writing data. For working example
> > you can check how devctl was implemented (sys/kern/subr_bus.c).
> >
> > --
> > Mateusz Guzik <mjguzik at gmail.com>
> >
> 
> Ok , now I understaand it.
> If a thread return to user space with locked mutex, kernel doesen't know if
> the thread will come back to unlock it. It is really unsafe return to
> userspace without unlocking of helding mutexes.
> 

Provided example is really unfortunate. :/ Forget it.

(And a proper solution for your locking issue is of course to lock
mutex before read/write and *unlock* it after it's done. (missed that
word in my previous mail))

Threads in userland holding kernel locks would lead to panics in a lot
of situations. For example you already have sleepable mutex and call
some kernel function that acquires sx lock - the kernel panics as this
is not allowed combination.

-- 
Mateusz Guzik <mjguzik at gmail.com>


More information about the freebsd-hackers mailing list