summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2001-06-22 23:02:37 +0000
committerjhb <jhb@FreeBSD.org>2001-06-22 23:02:37 +0000
commit8210b8d106096a99d54127a3dd7994fa47bf8a86 (patch)
tree899dc79ea3aef327a9778bbc1750e413800057ae
parentff768af1444daf52be91cb03270ce21515596ad7 (diff)
downloadFreeBSD-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.c19
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);
}
}
OpenPOWER on IntegriCloud