aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_descrip.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2004-02-04 21:52:57 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2004-02-04 21:52:57 +0000
commit91d5354a2ce810d848eca6ecf9da1027aeb2be6d (patch)
treed9c0a05d62914174d6f00ab22300e935c3e6d983 /sys/kern/kern_descrip.c
parent890cefab5b3dd6f2a1fbfffae44730a0434b2e84 (diff)
downloadsrc-91d5354a2ce810d848eca6ecf9da1027aeb2be6d.tar.gz
src-91d5354a2ce810d848eca6ecf9da1027aeb2be6d.zip
Locking for the per-process resource limits structure.
- struct plimit includes a mutex to protect a reference count. The plimit structure is treated similarly to struct ucred in that is is always copy on write, so having a reference to a structure is sufficient to read from it without needing a further lock. - The proc lock protects the p_limit pointer and must be held while reading limits from a process to keep the limit structure from changing out from under you while reading from it. - Various global limits that are ints are not protected by a lock since int writes are atomic on all the archs we support and thus a lock wouldn't buy us anything. - All accesses to individual resource limits from a process are abstracted behind a simple lim_rlimit(), lim_max(), and lim_cur() API that return either an rlimit, or the current or max individual limit of the specified resource from a process. - dosetrlimit() was renamed to kern_setrlimit() to match existing style of other similar syscall helper functions. - The alpha OSF/1 compat layer no longer calls getrlimit() and setrlimit() (it didn't used the stackgap when it should have) but uses lim_rlimit() and kern_setrlimit() instead. - The svr4 compat no longer uses the stackgap for resource limits calls, but uses lim_rlimit() and kern_setrlimit() instead. - The ibcs2 compat no longer uses the stackgap for resource limits. It also no longer uses the stackgap for accessing sysctl's for the ibcs2_sysconf() syscall but uses kernel_sysctl() instead. As a result, ibcs2_sysconf() no longer needs Giant. - The p_rlimit macro no longer exists. Submitted by: mtm (mostly, I only did a few cleanups and catchups) Tested on: i386 Compiled on: alpha, amd64
Notes
Notes: svn path=/head/; revision=125454
Diffstat (limited to 'sys/kern/kern_descrip.c')
-rw-r--r--sys/kern/kern_descrip.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index b6eaee271a6c..abaac90655e6 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -224,10 +224,10 @@ getdtablesize(td, uap)
{
struct proc *p = td->td_proc;
- mtx_lock(&Giant);
+ PROC_LOCK(p);
td->td_retval[0] =
- min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
- mtx_unlock(&Giant);
+ min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc);
+ PROC_UNLOCK(p);
return (0);
}
@@ -353,11 +353,14 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
case F_DUPFD:
FILEDESC_UNLOCK(fdp);
newmin = arg;
- if (newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
+ PROC_LOCK(p);
+ if (newmin >= lim_cur(p, RLIMIT_NOFILE) ||
newmin >= maxfilesperproc) {
+ PROC_UNLOCK(p);
error = EINVAL;
break;
}
+ PROC_UNLOCK(p);
error = do_dup(td, DUP_VARIABLE, fd, newmin, td->td_retval);
break;
@@ -572,7 +575,9 @@ do_dup(td, type, old, new, retval)
*/
if (old < 0 || new < 0)
return (EBADF);
- maxfd = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
+ PROC_LOCK(p);
+ maxfd = min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc);
+ PROC_UNLOCK(p);
if (new >= maxfd)
return (EMFILE);
@@ -1213,7 +1218,9 @@ fdalloc(struct thread *td, int minfd, int *result)
FILEDESC_LOCK_ASSERT(fdp, MA_OWNED);
- maxfd = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
+ PROC_LOCK(p);
+ maxfd = min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc);
+ PROC_UNLOCK(p);
/*
* Search the bitmap for a free descriptor. If none is found, try
@@ -1261,7 +1268,9 @@ fdavail(td, n)
FILEDESC_LOCK_ASSERT(fdp, MA_OWNED);
- lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
+ PROC_LOCK(p);
+ lim = min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc);
+ PROC_UNLOCK(p);
if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0)
return (1);
last = min(fdp->fd_nfiles, lim);