t/rw/msleep(9) functions call CURSIG() which needs the KERNEL_LOCK().
To remove this requirement I'd like to start by merging CURSIG() with
its underlying function issignal(). The goal of this merge is to avoid
accessing shared value like `ps_siglist' multiple times.
The diff below moves the content of the CURSIG() macro into issignal()
which shows that many checks are redundant.
Comments, oks?
Index: kern/kern_sig.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sig.c,v
retrieving revision 1.273
diff -u -p -r1.273 kern_sig.c
--- kern/kern_sig.c 15 Feb 2021 09:35:59 -0000 1.273
+++ kern/kern_sig.c 2 Mar 2021 10:50:49 -0000
@@ -1035,7 +1035,7 @@ ptsignal(struct proc *p, int signum, enu
goto out;
/*
* Process is sleeping and traced... make it runnable
- * so it can discover the signal in issignal() and stop
+ * so it can discover the signal in cursig() and stop
* for the parent.
*/
if (pr->ps_flags & PS_TRACED)
@@ -1159,28 +1159,36 @@ out:
}
/*
+ * Determine signal that should be delivered to process p, the current
+ * process, 0 if none.
+ *
* If the current process has received a signal (should be caught or cause
* termination, should interrupt current syscall), return the signal number.
* Stop signals with default action are processed immediately, then cleared;
* they aren't returned. This is checked after each entry to the system for
- * a syscall or trap (though this can usually be done without calling issignal
- * by checking the pending signal masks in the CURSIG macro.) The normal call
- * sequence is
+ * a syscall or trap. The normal call sequence is
*
- * while (signum = CURSIG(curproc))
+ * while (signum = cursig(curproc))
* postsig(signum);
*
* Assumes that if the P_SINTR flag is set, we're holding both the
* kernel and scheduler locks.
*/
int
-issignal(struct proc *p)
+cursig(struct proc *p)
{
struct process *pr = p->p_p;
- int signum, mask, prop;
+ int sigpending, signum, mask, prop;
int dolock = (p->p_flag & P_SINTR) == 0;
int s;
+ sigpending = (p->p_siglist | pr->ps_siglist);
+ if (sigpending == 0)
+ return 0;
+
+ if (!ISSET(pr->ps_flags, PS_TRACED) && SIGPENDING(p) == 0)
+ return 0;
+
for (;;) {
mask = SIGPENDING(p);
if (pr->ps_flags & PS_PPWAIT)
@@ -1304,7 +1312,7 @@ issignal(struct proc *p)
*/
if ((prop & SA_CONT) == 0 &&
(pr->ps_flags & PS_TRACED) == 0)
- printf("issignal\n");
+ printf("%s\n", __func__);
break; /* == ignore */
default:
/*
@@ -1766,7 +1774,7 @@ sys___thrsigdivert(struct proc *p, void
dosigsuspend(p, p->p_sigmask &~ mask);
for (;;) {
- si.si_signo = CURSIG(p);
+ si.si_signo = cursig(p);
if (si.si_signo != 0) {
sigset_t smask = sigmask(si.si_signo);
if (smask & mask) {
@@ -1907,7 +1915,7 @@ userret(struct proc *p)
if (SIGPENDING(p) != 0) {
KERNEL_LOCK();
- while ((signum = CURSIG(p)) != 0)
+ while ((signum = cursig(p)) != 0)
postsig(p, signum);
KERNEL_UNLOCK();
}
@@ -1923,7 +1931,7 @@ userret(struct proc *p)
p->p_sigmask = p->p_oldmask;
KERNEL_LOCK();
- while ((signum = CURSIG(p)) != 0)
+ while ((signum = cursig(p)) != 0)
postsig(p, signum);
KERNEL_UNLOCK();
}
Index: kern/kern_synch.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_synch.c,v
retrieving revision 1.176
diff -u -p -r1.176 kern_synch.c
--- kern/kern_synch.c 8 Feb 2021 10:51:02 -0000 1.176
+++ kern/kern_synch.c 2 Mar 2021 10:49:15 -0000
@@ -479,7 +479,7 @@ sleep_signal_check(void)
if ((err = single_thread_check(p, 1)) != 0)
return err;
- if ((sig = CURSIG(p)) != 0) {
+ if ((sig = cursig(p)) != 0) {
if (p->p_p->ps_sigacts->ps_sigintr & sigmask(sig))
return EINTR;
else
Index: sys/signalvar.h
===================================================================
RCS file: /cvs/src/sys/sys/signalvar.h,v
retrieving revision 1.45
diff -u -p -r1.45 signalvar.h
--- sys/signalvar.h 8 Nov 2020 20:37:24 -0000 1.45
+++ sys/signalvar.h 2 Mar 2021 10:49:41 -0000
@@ -72,17 +72,6 @@ struct sigacts {
(((p)->p_siglist | (p)->p_p->ps_siglist) & ~(p)->p_sigmask)
/*
- * Determine signal that should be delivered to process p, the current
- * process, 0 if none. If there is a pending stop signal with default
- * action, the process stops in issignal().
- */
-#define CURSIG(p) \
- ((((p)->p_siglist | (p)->p_p->ps_siglist) == 0 || \
- (((p)->p_p->ps_flags & PS_TRACED) == 0 && \
- SIGPENDING(p) == 0)) ? \
- 0 : issignal(p))
-
-/*
* Clear a pending signal from a process.
*/
#define CLRSIG(p, sig) do { \
@@ -116,7 +105,7 @@ struct sigio_ref;
*/
int coredump(struct proc *p);
void execsigs(struct proc *p);
-int issignal(struct proc *p);
+int cursig(struct proc *p);
void pgsigio(struct sigio_ref *sir, int sig, int checkctty);
void pgsignal(struct pgrp *pgrp, int sig, int checkctty);
void psignal(struct proc *p, int sig);
Index: ufs/mfs/mfs_vfsops.c
===================================================================
RCS file: /cvs/src/sys/ufs/mfs/mfs_vfsops.c,v
retrieving revision 1.59
diff -u -p -r1.59 mfs_vfsops.c
--- ufs/mfs/mfs_vfsops.c 18 Feb 2020 12:13:40 -0000 1.59
+++ ufs/mfs/mfs_vfsops.c 2 Mar 2021 10:49:26 -0000
@@ -188,7 +188,7 @@ mfs_start(struct mount *mp, int flags, s
* EINTR/ERESTART.
*/
if (sleepreturn != 0) {
- sig = CURSIG(p);
+ sig = cursig(p);
if (vfs_busy(mp, VB_WRITE|VB_NOWAIT) ||
dounmount(mp, (sig == SIGKILL) ? MNT_FORCE : 0, p))
CLRSIG(p, sig);