Diff below extends the scope of the SCHED_LOCK() to no longer require
the KERNEL_LOCK() when iterating over `ps_thread'.  This is enough to
make progress without having to introduce new mechanism.

ok?

Index: kern/kern_exit.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_exit.c,v
retrieving revision 1.195
diff -u -p -r1.195 kern_exit.c
--- kern/kern_exit.c    8 Feb 2021 10:51:01 -0000       1.195
+++ kern/kern_exit.c    8 Feb 2021 10:55:18 -0000
@@ -124,6 +124,7 @@ exit1(struct proc *p, int xexit, int xsi
 {
        struct process *pr, *qr, *nqr;
        struct rusage *rup;
+       int s;
 
        atomic_setbits_int(&p->p_flag, P_WEXIT);
 
@@ -161,7 +162,9 @@ exit1(struct proc *p, int xexit, int xsi
        }
 
        /* unlink ourselves from the active threads */
+       SCHED_LOCK(s);
        TAILQ_REMOVE(&pr->ps_threads, p, p_thr_link);
+       SCHED_UNLOCK(s);
        if ((p->p_flag & P_THREAD) == 0) {
                /* main thread gotta wait because it has the pid, et al */
                while (pr->ps_refcnt > 1)
Index: kern/kern_fork.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_fork.c,v
retrieving revision 1.232
diff -u -p -r1.232 kern_fork.c
--- kern/kern_fork.c    8 Feb 2021 10:51:01 -0000       1.232
+++ kern/kern_fork.c    8 Feb 2021 10:54:49 -0000
@@ -558,13 +558,13 @@ thread_fork(struct proc *curp, void *sta
 
        LIST_INSERT_HEAD(&allproc, p, p_list);
        LIST_INSERT_HEAD(TIDHASH(p->p_tid), p, p_hash);
-       TAILQ_INSERT_TAIL(&pr->ps_threads, p, p_thr_link);
 
+       SCHED_LOCK(s);
+       TAILQ_INSERT_TAIL(&pr->ps_threads, p, p_thr_link);
        /*
         * if somebody else wants to take us to single threaded mode,
         * count ourselves in.
         */
-       SCHED_LOCK(s);
        if (pr->ps_single) {
                atomic_inc_int(&pr->ps_singlecount);
                atomic_setbits_int(&p->p_flag, P_SUSPSINGLE);
Index: kern/kern_sig.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sig.c,v
retrieving revision 1.272
diff -u -p -r1.272 kern_sig.c
--- kern/kern_sig.c     8 Feb 2021 10:51:01 -0000       1.272
+++ kern/kern_sig.c     8 Feb 2021 10:56:26 -0000
@@ -1209,11 +1209,7 @@ issignal(struct proc *p)
                    signum != SIGKILL) {
                        pr->ps_xsig = signum;
 
-                       if (dolock)
-                               KERNEL_LOCK();
                        single_thread_set(p, SINGLE_PTRACE, 0);
-                       if (dolock)
-                               KERNEL_UNLOCK();
 
                        if (dolock)
                                SCHED_LOCK(s);
@@ -2009,7 +2005,6 @@ single_thread_set(struct proc *p, enum s
        struct proc *q;
        int error, s;
 
-       KERNEL_ASSERT_LOCKED();
        KASSERT(curproc == p);
 
        SCHED_LOCK(s);
Index: sys/proc.h
===================================================================
RCS file: /cvs/src/sys/sys/proc.h,v
retrieving revision 1.308
diff -u -p -r1.308 proc.h
--- sys/proc.h  8 Feb 2021 10:51:02 -0000       1.308
+++ sys/proc.h  8 Feb 2021 10:55:45 -0000
@@ -167,7 +167,7 @@ struct process {
        struct  ucred *ps_ucred;        /* Process owner's identity. */
 
        LIST_ENTRY(process) ps_list;    /* List of all processes. */
-       TAILQ_HEAD(,proc) ps_threads;   /* Threads in this process. */
+       TAILQ_HEAD(,proc) ps_threads;   /* [K|S] Threads in this process. */
 
        LIST_ENTRY(process) ps_pglist;  /* List of processes in pgrp. */
        struct  process *ps_pptr;       /* Pointer to parent process. */

Reply via email to