From 91d5354a2ce810d848eca6ecf9da1027aeb2be6d Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 4 Feb 2004 21:52:57 +0000 Subject: 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 --- sys/compat/ia32/ia32_sysvec.c | 63 ++++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 40 deletions(-) (limited to 'sys/compat/ia32') diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c index 0b2d777da5843..2210cec4e17fb 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); } -- cgit v1.2.3