aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2018-11-29 02:52:08 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2018-11-29 02:52:08 +0000
commit1e9a1bf5898bc27122358e03ab20aa1c96f44336 (patch)
tree1c86d42b212b0be36f23bdaebe6997f6fc557d98 /sys/kern
parent78afed13969ff5911565681047b9da781991d7a4 (diff)
downloadsrc-1e9a1bf5898bc27122358e03ab20aa1c96f44336.tar.gz
src-1e9a1bf5898bc27122358e03ab20aa1c96f44336.zip
proc: create a dedicated lock for zombproc to ligthen the load on allproc_lock
waitpid always takes proctree to evaluate the list, but only takes allproc if it can reap. With this patch allproc is no longer taken, which helps during poudriere -j 128. Discussed with: kib Sponsored by: The FreeBSD Foundation
Notes
Notes: svn path=/head/; revision=341176
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_exit.c6
-rw-r--r--sys/kern/kern_fork.c8
-rw-r--r--sys/kern/kern_proc.c6
-rw-r--r--sys/kern/kern_racct.c2
4 files changed, 18 insertions, 4 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index f88c7cf28f59..11610de083ce 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -432,8 +432,10 @@ exit1(struct thread *td, int rval, int signo)
* Move proc from allproc queue to zombproc.
*/
sx_xlock(&allproc_lock);
+ sx_xlock(&zombproc_lock);
LIST_REMOVE(p, p_list);
LIST_INSERT_HEAD(&zombproc, p, p_list);
+ sx_xunlock(&zombproc_lock);
sx_xunlock(&allproc_lock);
/*
@@ -871,9 +873,9 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options)
* Remove other references to this process to ensure we have an
* exclusive reference.
*/
- sx_xlock(&allproc_lock);
+ sx_xlock(&zombproc_lock);
LIST_REMOVE(p, p_list); /* off zombproc */
- sx_xunlock(&allproc_lock);
+ sx_xunlock(&zombproc_lock);
sx_xlock(PIDHASHLOCK(p->p_pid));
LIST_REMOVE(p, p_hash);
sx_xunlock(PIDHASHLOCK(p->p_pid));
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 050e4651d098..e0d1299ba78f 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -238,6 +238,7 @@ fork_findpid(int flags)
struct proc *p;
int trypid;
static int pidchecked = 0;
+ bool locked_zomb = false;
/*
* Requires allproc_lock in order to iterate over the list
@@ -318,6 +319,10 @@ again:
}
if (!doingzomb) {
doingzomb = 1;
+ if (!locked_zomb) {
+ sx_slock(&zombproc_lock);
+ locked_zomb = true;
+ }
p = LIST_FIRST(&zombproc);
goto again;
}
@@ -331,6 +336,9 @@ again:
else
lastpid = trypid;
+ if (locked_zomb)
+ sx_sunlock(&zombproc_lock);
+
return (trypid);
}
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 4dfa374ad3e6..68eb2a28616e 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -125,6 +125,7 @@ u_long pgrphash;
struct proclist allproc;
struct proclist zombproc;
struct sx __exclusive_cache_line allproc_lock;
+struct sx __exclusive_cache_line zombproc_lock;
struct sx __exclusive_cache_line proctree_lock;
struct mtx __exclusive_cache_line ppeers_lock;
uma_zone_t proc_zone;
@@ -177,6 +178,7 @@ procinit(void)
u_long i;
sx_init(&allproc_lock, "allproc");
+ sx_init(&zombproc_lock, "zombproc");
sx_init(&proctree_lock, "proctree");
mtx_init(&ppeers_lock, "p_peers", NULL, MTX_DEF);
LIST_INIT(&allproc);
@@ -1194,14 +1196,14 @@ zpfind(pid_t pid)
{
struct proc *p;
- sx_slock(&allproc_lock);
+ sx_slock(&zombproc_lock);
LIST_FOREACH(p, &zombproc, p_list) {
if (p->p_pid == pid) {
PROC_LOCK(p);
break;
}
}
- sx_sunlock(&allproc_lock);
+ sx_sunlock(&zombproc_lock);
return (p);
}
diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c
index 644d514bb08e..f80bb64fa029 100644
--- a/sys/kern/kern_racct.c
+++ b/sys/kern/kern_racct.c
@@ -1228,11 +1228,13 @@ racctd(void)
sx_slock(&allproc_lock);
+ sx_slock(&zombproc_lock);
LIST_FOREACH(p, &zombproc, p_list) {
PROC_LOCK(p);
racct_set(p, RACCT_PCTCPU, 0);
PROC_UNLOCK(p);
}
+ sx_sunlock(&zombproc_lock);
FOREACH_PROC_IN_SYSTEM(p) {
PROC_LOCK(p);