summaryrefslogtreecommitdiffstats
path: root/sys/compat/ia32
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2004-02-04 21:52:57 +0000
committerjhb <jhb@FreeBSD.org>2004-02-04 21:52:57 +0000
commit279b2b827810d149b5b8453900cdea57874ae234 (patch)
treed9c0a05d62914174d6f00ab22300e935c3e6d983 /sys/compat/ia32
parentf7b1079809c2529c50447de59fdce77a7f5a08f5 (diff)
downloadFreeBSD-src-279b2b827810d149b5b8453900cdea57874ae234.zip
FreeBSD-src-279b2b827810d149b5b8453900cdea57874ae234.tar.gz
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
Diffstat (limited to 'sys/compat/ia32')
-rw-r--r--sys/compat/ia32/ia32_sysvec.c63
1 files changed, 23 insertions, 40 deletions
diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c
index 0b2d777..2210cec 100644
--- a/sys/compat/ia32/ia32_sysvec.c
+++ b/sys/compat/ia32/ia32_sysvec.c
@@ -273,50 +273,33 @@ static void
ia32_fixlimits(struct image_params *imgp)
{
struct proc *p = imgp->proc;
-
+ struct plimit *oldlim, *newlim;
+
+ if (ia32_maxdsiz == 0 && ia32_maxssiz == 0 && ia32_maxvmem == 0)
+ return;
+ newlim = lim_alloc();
+ PROC_LOCK(p);
+ oldlim = p->p_limit;
+ lim_copy(newlim, oldlim);
if (ia32_maxdsiz != 0) {
- if (p->p_rlimit[RLIMIT_DATA].rlim_cur > ia32_maxdsiz ||
- p->p_rlimit[RLIMIT_DATA].rlim_max > ia32_maxdsiz) {
- if (p->p_limit->p_refcnt > 1) {
- p->p_limit->p_refcnt--;
- p->p_limit = limcopy(p->p_limit);
- }
- if (p->p_rlimit[RLIMIT_DATA].rlim_cur > ia32_maxdsiz)
- p->p_rlimit[RLIMIT_DATA].rlim_cur =
- ia32_maxdsiz;
- if (p->p_rlimit[RLIMIT_DATA].rlim_max > ia32_maxdsiz)
- p->p_rlimit[RLIMIT_DATA].rlim_max =
- ia32_maxdsiz;
- }
+ if (newlim->pl_rlimit[RLIMIT_DATA].rlim_cur > ia32_maxdsiz)
+ newlim->pl_rlimit[RLIMIT_DATA].rlim_cur = ia32_maxdsiz;
+ if (newlim->pl_rlimit[RLIMIT_DATA].rlim_max > ia32_maxdsiz)
+ newlim->pl_rlimit[RLIMIT_DATA].rlim_max = ia32_maxdsiz;
}
if (ia32_maxssiz != 0) {
- if (p->p_rlimit[RLIMIT_STACK].rlim_cur > ia32_maxssiz ||
- p->p_rlimit[RLIMIT_STACK].rlim_max > ia32_maxssiz) {
- if (p->p_limit->p_refcnt > 1) {
- p->p_limit->p_refcnt--;
- p->p_limit = limcopy(p->p_limit);
- }
- if (p->p_rlimit[RLIMIT_STACK].rlim_cur > ia32_maxssiz)
- p->p_rlimit[RLIMIT_STACK].rlim_cur =
- ia32_maxssiz;
- if (p->p_rlimit[RLIMIT_STACK].rlim_max > ia32_maxssiz)
- p->p_rlimit[RLIMIT_STACK].rlim_max =
- ia32_maxssiz;
- }
+ if (newlim->pl_rlimit[RLIMIT_STACK].rlim_cur > ia32_maxssiz)
+ newlim->pl_rlimit[RLIMIT_STACK].rlim_cur = ia32_maxssiz;
+ if (newlim->pl_rlimit[RLIMIT_STACK].rlim_max > ia32_maxssiz)
+ newlim->pl_rlimit[RLIMIT_STACK].rlim_max = ia32_maxssiz;
}
if (ia32_maxvmem != 0) {
- if (p->p_rlimit[RLIMIT_VMEM].rlim_cur > ia32_maxvmem ||
- p->p_rlimit[RLIMIT_VMEM].rlim_max > ia32_maxvmem) {
- if (p->p_limit->p_refcnt > 1) {
- p->p_limit->p_refcnt--;
- p->p_limit = limcopy(p->p_limit);
- }
- if (p->p_rlimit[RLIMIT_VMEM].rlim_cur > ia32_maxvmem)
- p->p_rlimit[RLIMIT_VMEM].rlim_cur =
- ia32_maxvmem;
- if (p->p_rlimit[RLIMIT_VMEM].rlim_max > ia32_maxvmem)
- p->p_rlimit[RLIMIT_VMEM].rlim_max =
- ia32_maxvmem;
- }
+ if (newlim->pl_rlimit[RLIMIT_VMEM].rlim_cur > ia32_maxvmem)
+ newlim->pl_rlimit[RLIMIT_VMEM].rlim_cur = ia32_maxvmem;
+ if (newlim->pl_rlimit[RLIMIT_VMEM].rlim_max > ia32_maxvmem)
+ newlim->pl_rlimit[RLIMIT_VMEM].rlim_max = ia32_maxvmem;
}
+ p->p_limit = newlim;
+ PROC_UNLOCK(p);
+ lim_free(oldlim);
}
OpenPOWER on IntegriCloud