diff options
author | jhb <jhb@FreeBSD.org> | 2001-06-22 23:02:37 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2001-06-22 23:02:37 +0000 |
commit | 8210b8d106096a99d54127a3dd7994fa47bf8a86 (patch) | |
tree | 899dc79ea3aef327a9778bbc1750e413800057ae | |
parent | ff768af1444daf52be91cb03270ce21515596ad7 (diff) | |
download | FreeBSD-src-8210b8d106096a99d54127a3dd7994fa47bf8a86.zip FreeBSD-src-8210b8d106096a99d54127a3dd7994fa47bf8a86.tar.gz |
- Change CURSIG() and postsig() to require that the proc lock is held
rather than grabbing it and releasing it themselves. This allows callers
of these functions to get the lock to close race conditions.
- Grab Giant around ktrace in postsig.
- Count the switches performed on SIGSTOP's as involuntary context switches
in the resource usage stats.
Reported by: tegge (signal race), bde (missing csw stats)
-rw-r--r-- | sys/kern/kern_sig.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 5c43d06..82d2c73 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -172,19 +172,15 @@ int CURSIG(struct proc *p) { sigset_t tmpset; - int r = 0; - PROC_LOCK(p); + PROC_LOCK_ASSERT(p, MA_OWNED); if (SIGISEMPTY(p->p_siglist)) - goto out; + return (0); tmpset = p->p_siglist; SIGSETNAND(tmpset, p->p_sigmask); if (SIGISEMPTY(tmpset) && (p->p_flag & P_TRACED) == 0) - goto out; - r = issignal(p); -out: - PROC_UNLOCK(p); - return (r); + return (0); + return (issignal(p)); } static __inline int @@ -1386,6 +1382,7 @@ issignal(p) stop(p); PROC_UNLOCK_NOSWITCH(p); DROP_GIANT_NOSWITCH(); + p->p_stats->p_ru.ru_nivcsw++; mi_switch(); mtx_unlock_spin(&sched_lock); PICKUP_GIANT(); @@ -1464,6 +1461,7 @@ issignal(p) stop(p); PROC_UNLOCK_NOSWITCH(p); DROP_GIANT_NOSWITCH(); + p->p_stats->p_ru.ru_nivcsw++; mi_switch(); mtx_unlock_spin(&sched_lock); PICKUP_GIANT(); @@ -1536,10 +1534,12 @@ postsig(sig) KASSERT(sig != 0, ("postsig")); + PROC_LOCK_ASSERT(p, MA_OWNED); #ifdef KTRACE + PROC_UNLOCK(p); mtx_lock(&Giant); -#endif PROC_LOCK(p); +#endif ps = p->p_sigacts; SIGDELSET(p->p_siglist, sig); action = ps->ps_sigact[_SIG_IDX(sig)]; @@ -1603,6 +1603,7 @@ postsig(sig) } PROC_UNLOCK(p); (*p->p_sysent->sv_sendsig)(action, sig, &returnmask, code); + PROC_LOCK(p); } } |