svn commit: r198590 - head/sys/kern
Giorgos Keramidas
keramida at freebsd.org
Thu Oct 29 23:08:13 UTC 2009
On Thu, 29 Oct 2009 14:34:24 +0000 (UTC), Konstantin Belousov <kib at FreeBSD.org> wrote:
> Author: kib
> Date: Thu Oct 29 14:34:24 2009
> New Revision: 198590
> URL: http://svn.freebsd.org/changeset/base/198590
>
> Log:
> Trapsignal() calls kern_sigprocmask() when delivering catched signal
> with proc lock held.
>
> Reported and tested by: Mykola Dzham freebsd at levsha org ua
> MFC after: 1 month
Hi Konstantin,
Some of the recent kern_sig changes end up recursing on a non-recursive
mutex in kern_sigprocmask() -> reschedule_signals():
panic: _mtx_lock_sleep: recursed on non-recursive mutex sigacts @ /usr/src/sys/kern/kern_sig.c:2422
(kgdb) bt
#0 doadump () at pcpu.h:246
#1 0xc0680bee in boot (howto=260) at /usr/src/sys/kern/kern_shutdown.c:416
#2 0xc0680ec2 in panic (fmt=Variable "fmt" is not available.
) at /usr/src/sys/kern/kern_shutdown.c:579
#3 0xc06716ea in _mtx_lock_sleep (m=0xc8154aa8, tid=3332925072, opts=0, file=0xc09bb332 "/usr/src/sys/kern/kern_sig.c", line=2422)
at /usr/src/sys/kern/kern_mutex.c:341
#4 0xc0671907 in _mtx_lock_flags (m=0xc8154aa8, opts=0, file=0xc09bb332 "/usr/src/sys/kern/kern_sig.c", line=2422)
at /usr/src/sys/kern/kern_mutex.c:203
#5 0xc0683434 in reschedule_signals (p=0xc71172a8, block={__bits = {0, 0, 0, 0}}) at /usr/src/sys/kern/kern_sig.c:2422
#6 0xc0683751 in kern_sigprocmask (td=0xc6a86690, how=1, set=0xe9005cd4, oset=0x0, flags=2) at /usr/src/sys/kern/kern_sig.c:1027
#7 0xc0684801 in postsig (sig=20) at /usr/src/sys/kern/kern_sig.c:2743
#8 0xc06be228 in ast (framep=0xe9005d38) at /usr/src/sys/kern/subr_trap.c:234
#9 0xc0920624 in doreti_ast () at /usr/src/sys/i386/i386/exception.s:365
I think the change that started causing this for MT applications was
change 197963 in /head that added this bit of code in kern_sig.c inside
kern_sigprocmask():
: @@ -1012,7 +1012,20 @@
: break;
: }
: }
: - PROC_UNLOCK(td->td_proc);
: + /*
: + * The new_block set contains signals that were not previosly
: + * blocked, but are blocked now.
: + *
: + * In case we block any signal that was not previously blocked
: + * for td, and process has the signal pending, try to schedule
: + * signal delivery to some thread that does not block the signal,
: + * possibly waking it up.
: + */
: + if (p->p_numthreads != 1)
: + reschedule_signals(p, new_block);
: +
: + PROC_UNLOCK(p);
: return (error);
AFAICT, postsig() is called with proc->p_sigacts->ps_mtx locked, so when
we are recursing when reschedule_signals() tries to lock it once more.
Since we are holding the proc lock in kern_sigprocmask(), is it safe to
assert that we own ps_mtx, drop it and re-acquire it immediately after
calling reschedule_signals()?
More information about the svn-src-all
mailing list