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. */