Subject: Re: lockmgr/lockinit and LK_SPIN - panic caused by legal flags?
To: Gary Thorpe <gathorpe79@yahoo.com>
From: Bill Studenmund <wrstuden@netbsd.org>
List: tech-kern
Date: 09/09/2003 09:13:36
On Tue, 9 Sep 2003, Gary Thorpe wrote:

> Ok, so basically, the only way the code won't panic is if both
> lockinit() and lockmgr() specify LK_SPIN with each invocation for the
> same lock. However, looking at the code it is possible to do this:
>
> lockinit(lkp, prio, wmesg, 0, LK_SPIN|LK_SLEEPFAIL);
> .
> .
> .
> lockmgr(lkp, LK_SPIN|LK_SLEEPFAIL, NULL);
>
> (LK_SPIN|LK_SLEEPFAIL) ^ (LK_SPIN|LK_SLEEPFAIL) = 0;
> 0 & LK_SPIN = 0;
> no panic;
>
> Does this make sense? While the code requires that LK_SPIN must always
> be specified (unlike all the other flags - bad documentation), it
> doesn't prevent this mix/matching. How about:

I don't see where the problem is.

> lockinit(lkp, prio, wmesg, 0, LK_SPIN);
> .
> .
> .
> lockmgr(lkp, LK_EXCLUSIVE, NULL);
> (LK_SPIN) ^ (LK_EXCLUSIVE) = LK_EXCLUSIVE|LK_SPIN;
> LK_EXCLUSIVE|LK_SPIN & LK_SPIN = LK_SPIN;
> panic;
>
> Here, I would have tried to initialize a spin lock, get the lock
> exclusively and it would still panic. The man page leaves this part out
> and thats all I have to go by.

Then the man page should be changed.

However you initialized the lock as a spin lock, then tried to access it
as if it wasn't. -> Boom!

What the LK_SPIN panic is trying to do is make it so that we don't
silently mix up lock pointers. Everything that is supposed to have a spin
lock will have LK_SPIN, and stuff that is supposed to be a sleeper lock
won't. Think of it as a way of hiding both struct lockmgr_spin and struct
lockmgr_sleep within struct lockmgr.

Take care,

Bill