Index | Thread | Search

From:
Vitaliy Makkoveev <mvs@openbsd.org>
Subject:
Re: sysctl(2): unlock KERN_MAXPROC
To:
tech@openbsd.org
Date:
Mon, 19 Aug 2024 13:28:01 +0300

Download raw body.

Thread
On Mon, Aug 19, 2024 at 11:56:40AM +0200, Martin Pieuchot wrote:
> On 18/08/24(Sun) 23:51, Vitaliy Makkoveev wrote:
> > I want to unlock atomically accessed integers from `kern_vars' and
> > remove corresponding cases from the 'switch' block.
> > 
> > `maxprocess' is atomically accessed integer. procinit() called during
> > bootstrap, so no atomic_load_int(9) required.
> 
> Could you keep maxthread in sync?
>

Sure.

> What about the hashinit() calls in kern/kern_proc.c ?
> 

procinit() called during kernel bootstrap, you can't have concurrent
sysctl(2) threads this time. This is also true for pmap_bootstrap().

Index: sys/conf/param.c
===================================================================
RCS file: /cvs/src/sys/conf/param.c,v
diff -u -p -r1.50 param.c
--- sys/conf/param.c	5 May 2024 06:14:37 -0000	1.50
+++ sys/conf/param.c	19 Aug 2024 10:23:58 -0000
@@ -50,6 +50,11 @@
 #endif
 
 /*
+ * Locks used to protect data:
+ *	a	atomic
+ */
+
+/*
  * System parameter formulae.
  *
  * This file is copied into each directory where we compile
@@ -67,8 +72,8 @@ int	utc_offset = 0;
 #define	NTEXT (80 + NPROCESS / 8)		/* actually the object cache */
 #define	NVNODE (NPROCESS * 2 + NTEXT + 100)
 int	initialvnodes = NVNODE;
-int	maxprocess = NPROCESS;
-int	maxthread = 2 * NPROCESS;
+int	maxprocess = NPROCESS;				/* [a] */
+int	maxthread = 2 * NPROCESS;			/* [a] */
 int	maxfiles = 5 * (NPROCESS + MAXUSERS) + 80;
 long	nmbclust = NMBCLUSTERS;
 
Index: sys/kern/kern_fork.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_fork.c,v
diff -u -p -r1.263 kern_fork.c
--- sys/kern/kern_fork.c	16 Aug 2024 16:19:03 -0000	1.263
+++ sys/kern/kern_fork.c	19 Aug 2024 10:23:59 -0000
@@ -307,7 +307,7 @@ struct timeval fork_tfmrate = { 10, 0 };
 int
 fork_check_maxthread(uid_t uid)
 {
-	int val;
+	int maxthread_local, val;
 
 	/*
 	 * Although process entries are dynamically created, we still keep
@@ -318,8 +318,10 @@ fork_check_maxthread(uid_t uid)
 	 * the variable nthreads is the current number of procs, maxthread is
 	 * the limit.
 	 */
+	maxthread_local = atomic_load_int(&maxthread);
 	val = atomic_inc_int_nv(&nthreads);
-	if ((val > maxthread - 5 && uid != 0) || val > maxthread) {
+	if ((val > maxthread_local - 5 && uid != 0) ||
+	    val > maxthread_local) {
 		static struct timeval lasttfm;
 
 		if (ratecheck(&lasttfm, &fork_tfmrate))
@@ -353,7 +355,7 @@ fork1(struct proc *curp, int flags, void
 	struct proc *p;
 	uid_t uid = curp->p_ucred->cr_ruid;
 	struct vmspace *vm;
-	int count;
+	int count, maxprocess_local;
 	vaddr_t uaddr;
 	int error;
 	struct  ptrace_state *newptstat = NULL;
@@ -366,8 +368,9 @@ fork1(struct proc *curp, int flags, void
 	if ((error = fork_check_maxthread(uid)))
 		return error;
 
-	if ((nprocesses >= maxprocess - 5 && uid != 0) ||
-	    nprocesses >= maxprocess) {
+	maxprocess_local = atomic_load_int(&maxprocess);
+	if ((nprocesses >= maxprocess_local - 5 && uid != 0) ||
+	    nprocesses >= maxprocess_local) {
 		static struct timeval lasttfm;
 
 		if (ratecheck(&lasttfm, &fork_tfmrate))
Index: sys/kern/kern_resource.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_resource.c,v
diff -u -p -r1.86 kern_resource.c
--- sys/kern/kern_resource.c	9 Jul 2024 15:20:15 -0000	1.86
+++ sys/kern/kern_resource.c	19 Aug 2024 10:23:59 -0000
@@ -278,7 +278,7 @@ dosetrlimit(struct proc *p, u_int which,
 		maxlim = maxfiles;
 		break;
 	case RLIMIT_NPROC:
-		maxlim = maxprocess;
+		maxlim = atomic_load_int(&maxprocess);
 		break;
 	default:
 		maxlim = RLIM_INFINITY;
Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sysctl.c,v
diff -u -p -r1.439 kern_sysctl.c
--- sys/kern/kern_sysctl.c	14 Aug 2024 17:52:47 -0000	1.439
+++ sys/kern/kern_sysctl.c	19 Aug 2024 10:23:59 -0000
@@ -549,6 +549,7 @@ kern_sysctl(int *name, u_int namelen, vo
 		return (sysctl_rdint(oldp, oldlenp, newp, mp->msg_bufs));
 	}
 	case KERN_OSREV:
+	case KERN_MAXPROC:
 	case KERN_NFILES:
 	case KERN_TTYCOUNT:
 	case KERN_ARGMAX:
@@ -558,6 +559,7 @@ kern_sysctl(int *name, u_int namelen, vo
 	case KERN_SAVED_IDS:
 	case KERN_MAXPARTITIONS:
 	case KERN_RAWPARTITION:
+	case KERN_MAXTHREAD:
 	case KERN_NTHREADS:
 	case KERN_SOMAXCONN:
 	case KERN_SOMINCONN: