Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Oct 2009 11:41:06 +0200
From:      Giorgos Keramidas <keramida@freebsd.org>
To:        Kostik Belousov <kostikbel@gmail.com>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r198590 - head/sys/kern
Message-ID:  <87r5slw765.fsf@kobe.laptop>
In-Reply-To: <20091030032240.GD2147@deviant.kiev.zoral.com.ua> (Kostik Belousov's message of "Fri, 30 Oct 2009 05:22:40 %2B0200")
References:  <200910291434.n9TEYOVJ099388@svn.freebsd.org> <871vklbxyf.fsf@kobe.laptop> <20091030032240.GD2147@deviant.kiev.zoral.com.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
--=-=-=
Content-Transfer-Encoding: quoted-printable

The patch works fine so far.  I haven't seen any other panics of this
sort, for around 5 hours of running with a patched kernel.

On Fri, 30 Oct 2009 05:22:40 +0200, Kostik Belousov <kostikbel@gmail.com> w=
rote:
> Could you, please, test the following patch ? What application did
> exposed the issue ?
>
> diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
> index 7f5cfa3..e174df1 100644
> --- a/sys/kern/kern_sig.c
> +++ b/sys/kern/kern_sig.c
> @@ -220,7 +220,7 @@ static int sigproptbl[NSIG] =3D {
>          SA_KILL|SA_PROC,		/* SIGUSR2 */
>  };
>=20=20
> -static void reschedule_signals(struct proc *p, sigset_t block);
> +static void reschedule_signals(struct proc *p, sigset_t block, int flags=
);
>=20=20
>  static void
>  sigqueue_start(void)
> @@ -1024,7 +1024,7 @@ kern_sigprocmask(struct thread *td, int how, sigset=
_t *set, sigset_t *oset,
>  	 * possibly waking it up.
>  	 */
>  	if (p->p_numthreads !=3D 1)
> -		reschedule_signals(p, new_block);
> +		reschedule_signals(p, new_block, flags);
>=20=20
>  	if (!(flags & SIGPROCMASK_PROC_LOCKED))
>  		PROC_UNLOCK(p);
> @@ -1859,13 +1859,11 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
>  #endif
>  		(*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)],=20
>  				ksi, &td->td_sigmask);
> -		SIGSETOR(td->td_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]);
> -		if (!SIGISMEMBER(ps->ps_signodefer, sig)) {
> -			SIGEMPTYSET(mask);
> +		mask =3D ps->ps_catchmask[_SIG_IDX(sig)];
> +		if (!SIGISMEMBER(ps->ps_signodefer, sig))
>  			SIGADDSET(mask, sig);
> -			kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
> -			    SIGPROCMASK_PROC_LOCKED);
> -		}
> +		kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
> +		    SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED);
>  		if (SIGISMEMBER(ps->ps_sigreset, sig)) {
>  			/*
>  			 * See kern_sigaction() for origin of this code.
> @@ -2401,7 +2399,7 @@ stopme:
>  }
>=20=20
>  static void
> -reschedule_signals(struct proc *p, sigset_t block)
> +reschedule_signals(struct proc *p, sigset_t block, int flags)
>  {
>  	struct sigacts *ps;
>  	struct thread *td;
> @@ -2419,12 +2417,14 @@ reschedule_signals(struct proc *p, sigset_t block)
>=20=20
>  		td =3D sigtd(p, i, 0);
>  		signotify(td);
> -		mtx_lock(&ps->ps_mtx);
> +		if (!(flags & SIGPROCMASK_PS_LOCKED))
> +			mtx_lock(&ps->ps_mtx);
>  		if (p->p_flag & P_TRACED || SIGISMEMBER(ps->ps_sigcatch, i))
>  			tdsigwakeup(td, i, SIG_CATCH,
>  			    (SIGISMEMBER(ps->ps_sigintr, i) ? EINTR :
>  			     ERESTART));
> -		mtx_unlock(&ps->ps_mtx);
> +		if (!(flags & SIGPROCMASK_PS_LOCKED))
> +			mtx_unlock(&ps->ps_mtx);
>  	}
>  }
>=20=20
> @@ -2452,7 +2452,7 @@ tdsigcleanup(struct thread *td)
>  	SIGFILLSET(unblocked);
>  	SIGSETNAND(unblocked, td->td_sigmask);
>  	SIGFILLSET(td->td_sigmask);
> -	reschedule_signals(p, unblocked);
> +	reschedule_signals(p, unblocked, 0);
>=20=20
>  }
>=20=20
> @@ -2734,15 +2734,11 @@ postsig(sig)
>  		} else
>  			returnmask =3D td->td_sigmask;
>=20=20
> -		kern_sigprocmask(td, SIG_BLOCK,
> -		    &ps->ps_catchmask[_SIG_IDX(sig)], NULL,
> -		    SIGPROCMASK_PROC_LOCKED);
> -		if (!SIGISMEMBER(ps->ps_signodefer, sig)) {
> -			SIGEMPTYSET(mask);
> +		mask =3D ps->ps_catchmask[_SIG_IDX(sig)];
> +		if (!SIGISMEMBER(ps->ps_signodefer, sig))
>  			SIGADDSET(mask, sig);
> -			kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
> -			    SIGPROCMASK_PROC_LOCKED);
> -		}
> +		kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
> +		    SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED);
>=20=20
>  		if (SIGISMEMBER(ps->ps_sigreset, sig)) {
>  			/*
> diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h
> index b9a54f0..c27a128 100644
> --- a/sys/sys/signalvar.h
> +++ b/sys/sys/signalvar.h
> @@ -319,6 +319,7 @@ extern int kern_logsigexit;	/* Sysctl variable kern.l=
ogsigexit */
>  /* flags for kern_sigprocmask */
>  #define	SIGPROCMASK_OLD		0x0001
>  #define	SIGPROCMASK_PROC_LOCKED	0x0002
> +#define	SIGPROCMASK_PS_LOCKED	0x0004
>=20=20
>  /*
>   * Machine-independent functions:

--=-=-=
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.11 (FreeBSD)

iEYEARECAAYFAkrqtLoACgkQ1g+UGjGGA7bPZgCfWSOKfFZN7HmFICqWCJVUqzIv
yR4AoIyr62tfa0EnGmWeRmHlrVCKRwhJ
=TDFr
-----END PGP SIGNATURE-----
--=-=-=--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?87r5slw765.fsf>