[issue1996] panic: assertion: p->p_lock == 0 in kern_wait

Matthew Dillon 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
    specified anywhere.

    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 mailing list