[issue1996] panic: assertion: p->p_lock == 0 in kern_wait
dillon at apollo.backplane.com
Mon Jun 6 12:14:18 PDT 2011
:> + while (p->p_lock)
:> + tsleep(p, 0, "reap4", hz);
:> kfree(p, M_PROC);
The reason it is safe is that tsleep() is a global procedure call
which GCC is unable to optimize. Because of this GCC does not
know whether any non-local variables will be modified or not, so
it can't make that optimization. In this case p->p_lock is non-local,
so GCC will reload it across any procedure call.
GCC will still optimize any local variable use across the procedure
call as long as the address of the local variable (e.g. &i) isn't
The rules apply to the automatic registerization of locals too, though
GCC isn't above temporarily placing such variables into registers. This
is why you sometimes see things like: 'fubar(&tvp); vp = tvp;',
because the programmer wants GCC to be able to optimize 'vp' into a
If tsleep() were declared in the same source file (whether static or
not) then the assumption would not work and a cpu_ccfence() would
be needed to force the compiler to do the right thing.
I use cpu_ccfence() in numerous situations where reloads have to be
forced across inlined/static function calls.
More information about the Bugs