single_thread_clear() manipulates the same data structures as
single_thread_set() and, as such, doesn't need the KERNEL_LOCK().

However cursig() does need some sort of serialization to ensure that
per-process data structures like signals, flags and traced-signum stay
consistent.  So the diff below move the assertion up in preparation for
more mp work.

ok?

Index: kern/kern_sig.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sig.c,v
retrieving revision 1.274
diff -u -p -r1.274 kern_sig.c
--- kern/kern_sig.c     4 Mar 2021 09:02:37 -0000       1.274
+++ kern/kern_sig.c     4 Mar 2021 09:35:47 -0000
@@ -1182,6 +1182,8 @@ cursig(struct proc *p)
        int dolock = (p->p_flag & P_SINTR) == 0;
        int s;
 
+       KERNEL_ASSERT_LOCKED();
+
        sigpending = (p->p_siglist | pr->ps_siglist);
        if (sigpending == 0)
                return 0;
@@ -1225,11 +1227,7 @@ cursig(struct proc *p)
                        if (dolock)
                                SCHED_UNLOCK(s);
 
-                       if (dolock)
-                               KERNEL_LOCK();
                        single_thread_clear(p, 0);
-                       if (dolock)
-                               KERNEL_UNLOCK();
 
                        /*
                         * If we are no longer being traced, or the parent
@@ -2128,7 +2126,6 @@ single_thread_clear(struct proc *p, int 
 
        KASSERT(pr->ps_single == p);
        KASSERT(curproc == p);
-       KERNEL_ASSERT_LOCKED();
 
        SCHED_LOCK(s);
        pr->ps_single = NULL;

Reply via email to