Index | Thread | Search

From:
Vitaliy Makkoveev <mvs@openbsd.org>
Subject:
Re: sysctl(2): unlock KERN_MAXPROC
To:
tech@openbsd.org
Date:
Tue, 20 Aug 2024 12:41:00 +0300

Download raw body.

Thread
On Mon, Aug 19, 2024 at 02:46:31PM +0200, Martin Pieuchot wrote:
> On 19/08/24(Mon) 13:28, Vitaliy Makkoveev wrote:
> > On Mon, Aug 19, 2024 at 11:56:40AM +0200, Martin Pieuchot wrote:
> 
> `maxthread' is already accessed with atomic_load_int() via KERN_NTHREADS
> & sysctl_bounded_arr(), right?  Is there other global variables in this
> array whose accesses should be converted to atomic_load_int() as well?
> 

Yes, sure. The first obvious variable is `maxfiles', which is lockless
read-only accessed in file descriptors layer. This is the KERN_MAXFILES
case of kern_sysctl().

lim_startup() also called during kernel bootstrap, no need to
atomic_load_int() within.

Index: sys/conf/param.c
===================================================================
RCS file: /cvs/src/sys/conf/param.c,v
diff -u -p -r1.51 param.c
--- sys/conf/param.c	20 Aug 2024 07:48:23 -0000	1.51
+++ sys/conf/param.c	20 Aug 2024 08:37:41 -0000
@@ -74,7 +74,7 @@ int	utc_offset = 0;
 int	initialvnodes = NVNODE;
 int	maxprocess = NPROCESS;				/* [a] */
 int	maxthread = 2 * NPROCESS;			/* [a] */
-int	maxfiles = 5 * (NPROCESS + MAXUSERS) + 80;
+int	maxfiles = 5 * (NPROCESS + MAXUSERS) + 80;	/* [a] */
 long	nmbclust = NMBCLUSTERS;
 
 #ifndef BUFCACHEPERCENT
Index: sys/kern/kern_descrip.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_descrip.c,v
diff -u -p -r1.208 kern_descrip.c
--- sys/kern/kern_descrip.c	22 Jun 2024 10:22:29 -0000	1.208
+++ sys/kern/kern_descrip.c	20 Aug 2024 08:37:42 -0000
@@ -362,7 +362,7 @@ restart:
 		return (0);
 	}
 	if ((u_int)new >= lim_cur(RLIMIT_NOFILE) ||
-	    (u_int)new >= maxfiles) {
+	    (u_int)new >= atomic_load_int(&maxfiles)) {
 		FRELE(fp, p);
 		return (EBADF);
 	}
@@ -424,7 +424,7 @@ restart:
 	case F_DUPFD_CLOEXEC:
 		newmin = (long)SCARG(uap, arg);
 		if ((u_int)newmin >= lim_cur(RLIMIT_NOFILE) ||
-		    (u_int)newmin >= maxfiles) {
+		    (u_int)newmin >= atomic_load_int(&maxfiles)) {
 			error = EINVAL;
 			break;
 		}
@@ -877,7 +877,7 @@ fdalloc(struct proc *p, int want, int *r
 	 * expanding the ofile array.
 	 */
 restart:
-	lim = min((int)lim_cur(RLIMIT_NOFILE), maxfiles);
+	lim = min((int)lim_cur(RLIMIT_NOFILE), atomic_load_int(&maxfiles));
 	last = min(fdp->fd_nfiles, lim);
 	if ((i = want) < fdp->fd_freefile)
 		i = fdp->fd_freefile;
@@ -1037,7 +1037,7 @@ fnew(struct proc *p)
 	int nfiles;
 
 	nfiles = atomic_inc_int_nv(&numfiles);
-	if (nfiles > maxfiles) {
+	if (nfiles > atomic_load_int(&maxfiles)) {
 		atomic_dec_int(&numfiles);
 		tablefull("file");
 		return (NULL);
Index: sys/kern/kern_resource.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_resource.c,v
diff -u -p -r1.87 kern_resource.c
--- sys/kern/kern_resource.c	20 Aug 2024 07:48:23 -0000	1.87
+++ sys/kern/kern_resource.c	20 Aug 2024 08:37:42 -0000
@@ -275,7 +275,7 @@ dosetrlimit(struct proc *p, u_int which,
 		maxlim = maxsmap;
 		break;
 	case RLIMIT_NOFILE:
-		maxlim = maxfiles;
+		maxlim = atomic_load_int(&maxfiles);
 		break;
 	case RLIMIT_NPROC:
 		maxlim = atomic_load_int(&maxprocess);
Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sysctl.c,v
diff -u -p -r1.441 kern_sysctl.c
--- sys/kern/kern_sysctl.c	20 Aug 2024 07:48:23 -0000	1.441
+++ sys/kern/kern_sysctl.c	20 Aug 2024 08:37:42 -0000
@@ -555,6 +555,7 @@ kern_sysctl(int *name, u_int namelen, vo
 	}
 	case KERN_OSREV:
 	case KERN_MAXPROC:
+	case KERN_MAXFILES:
 	case KERN_NFILES:
 	case KERN_TTYCOUNT:
 	case KERN_ARGMAX: