From 3304f1bb08518636ed17363effbbe2394bb46a49 Mon Sep 17 00:00:00 2001 From: mpi Date: Fri, 16 Aug 2024 16:19:03 +0000 Subject: [PATCH] Atomically modify `nthreads' and move proc_free() out of KERNEL_LOCK(). ok jca@ --- sys/kern/kern_exit.c | 6 ++---- sys/kern/kern_fork.c | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index a1d1456328d..fb611534bf8 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exit.c,v 1.231 2024/08/11 15:10:53 mvs Exp $ */ +/* $OpenBSD: kern_exit.c,v 1.232 2024/08/16 16:19:03 mpi Exp $ */ /* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */ /* @@ -432,7 +432,7 @@ proc_free(struct proc *p) { crfree(p->p_ucred); pool_put(&proc_pool, p); - nthreads--; + atomic_dec_int(&nthreads); } /* @@ -471,9 +471,7 @@ reaper(void *arg) if (p->p_flag & P_THREAD) { /* Just a thread */ - KERNEL_LOCK(); proc_free(p); - KERNEL_UNLOCK(); } else { struct process *pr = p->p_p; diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index e148c814380..d0d465babb6 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.262 2024/08/11 15:10:53 mvs Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.263 2024/08/16 16:19:03 mpi Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -65,7 +65,7 @@ #include int nprocesses = 1; /* process 0 */ -int nthreads = 1; /* proc 0 */ +int nthreads = 1; /* [a] proc 0 */ struct forkstat forkstat; void fork_return(void *); @@ -307,6 +307,8 @@ struct timeval fork_tfmrate = { 10, 0 }; int fork_check_maxthread(uid_t uid) { + int val; + /* * Although process entries are dynamically created, we still keep * a global limit on the maximum number we will create. We reserve @@ -316,14 +318,15 @@ fork_check_maxthread(uid_t uid) * the variable nthreads is the current number of procs, maxthread is * the limit. */ - if ((nthreads >= maxthread - 5 && uid != 0) || nthreads >= maxthread) { + val = atomic_inc_int_nv(&nthreads); + if ((val > maxthread - 5 && uid != 0) || val > maxthread) { static struct timeval lasttfm; if (ratecheck(&lasttfm, &fork_tfmrate)) tablefull("thread"); + atomic_dec_int(&nthreads); return EAGAIN; } - nthreads++; return 0; } @@ -369,7 +372,7 @@ fork1(struct proc *curp, int flags, void (*func)(void *), void *arg, if (ratecheck(&lasttfm, &fork_tfmrate)) tablefull("process"); - nthreads--; + atomic_dec_int(&nthreads); return EAGAIN; } nprocesses++; @@ -382,7 +385,7 @@ fork1(struct proc *curp, int flags, void (*func)(void *), void *arg, if (uid != 0 && count > lim_cur(RLIMIT_NPROC)) { (void)chgproccnt(uid, -1); nprocesses--; - nthreads--; + atomic_dec_int(&nthreads); return EAGAIN; } @@ -390,7 +393,7 @@ fork1(struct proc *curp, int flags, void (*func)(void *), void *arg, if (uaddr == 0) { (void)chgproccnt(uid, -1); nprocesses--; - nthreads--; + atomic_dec_int(&nthreads); return (ENOMEM); } @@ -547,7 +550,7 @@ thread_fork(struct proc *curp, void *stack, void *tcb, pid_t *tidptr, uaddr = uvm_uarea_alloc(); if (uaddr == 0) { - nthreads--; + atomic_dec_int(&nthreads); return ENOMEM; } -- 2.20.1