Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Feb 2014 21:52:40 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r262260 - stable/10/sys/kern
Message-ID:  <201402202152.s1KLqe9s073893@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjg
Date: Thu Feb 20 21:52:39 2014
New Revision: 262260
URL: http://svnweb.freebsd.org/changeset/base/262260

Log:
  MFC r259330,r259331:
  
  rlimit: add and utilize lim_shared
  
  rlimit: avoid unnecessary copying of rlimits
  
  If refcount is 1 just modify rlimits in place.

Modified:
  stable/10/sys/kern/kern_resource.c

Modified: stable/10/sys/kern/kern_resource.c
==============================================================================
--- stable/10/sys/kern/kern_resource.c	Thu Feb 20 21:36:05 2014	(r262259)
+++ stable/10/sys/kern/kern_resource.c	Thu Feb 20 21:52:39 2014	(r262260)
@@ -80,6 +80,8 @@ static int	donice(struct thread *td, str
 static struct uidinfo *uilookup(uid_t uid);
 static void	ruxagg_locked(struct rusage_ext *rux, struct thread *td);
 
+static __inline int	lim_shared(struct plimit *limp);
+
 /*
  * Resource controls and accounting.
  */
@@ -677,21 +679,29 @@ kern_proc_setrlimit(struct thread *td, s
 		limp->rlim_max = RLIM_INFINITY;
 
 	oldssiz.rlim_cur = 0;
-	newlim = lim_alloc();
+	newlim = NULL;
 	PROC_LOCK(p);
+	if (lim_shared(p->p_limit)) {
+		PROC_UNLOCK(p);
+		newlim = lim_alloc();
+		PROC_LOCK(p);
+	}
 	oldlim = p->p_limit;
 	alimp = &oldlim->pl_rlimit[which];
 	if (limp->rlim_cur > alimp->rlim_max ||
 	    limp->rlim_max > alimp->rlim_max)
 		if ((error = priv_check(td, PRIV_PROC_SETRLIMIT))) {
 			PROC_UNLOCK(p);
-			lim_free(newlim);
+			if (newlim != NULL)
+				lim_free(newlim);
 			return (error);
 		}
 	if (limp->rlim_cur > limp->rlim_max)
 		limp->rlim_cur = limp->rlim_max;
-	lim_copy(newlim, oldlim);
-	alimp = &newlim->pl_rlimit[which];
+	if (newlim != NULL) {
+		lim_copy(newlim, oldlim);
+		alimp = &newlim->pl_rlimit[which];
+	}
 
 	switch (which) {
 
@@ -741,9 +751,11 @@ kern_proc_setrlimit(struct thread *td, s
 	if (p->p_sysent->sv_fixlimit != NULL)
 		p->p_sysent->sv_fixlimit(limp, which);
 	*alimp = *limp;
-	p->p_limit = newlim;
+	if (newlim != NULL)
+		p->p_limit = newlim;
 	PROC_UNLOCK(p);
-	lim_free(oldlim);
+	if (newlim != NULL)
+		lim_free(oldlim);
 
 	if (which == RLIMIT_STACK) {
 		/*
@@ -1129,6 +1141,14 @@ lim_hold(limp)
 	return (limp);
 }
 
+static __inline int
+lim_shared(limp)
+	struct plimit *limp;
+{
+
+	return (limp->pl_refcnt > 1);
+}
+
 void
 lim_fork(struct proc *p1, struct proc *p2)
 {
@@ -1162,7 +1182,7 @@ lim_copy(dst, src)
 	struct plimit *dst, *src;
 {
 
-	KASSERT(dst->pl_refcnt == 1, ("lim_copy to shared limit"));
+	KASSERT(!lim_shared(dst), ("lim_copy to shared limit"));
 	bcopy(src->pl_rlimit, dst->pl_rlimit, sizeof(src->pl_rlimit));
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201402202152.s1KLqe9s073893>