svn commit: r298414 - in head/sys: kern sys

Edward Tomasz Napierala trasz at FreeBSD.org
Thu Apr 21 16:22:53 UTC 2016


Author: trasz
Date: Thu Apr 21 16:22:52 2016
New Revision: 298414
URL: https://svnweb.freebsd.org/changeset/base/298414

Log:
  Get rid of rctl_lock; use racct_lock where appropriate. The fast paths
  already required both of them, so having a separate rctl_lock didn't
  buy us anything.
  
  Reviewed by:	mjg@
  MFC after:	1 month
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D5914

Modified:
  head/sys/kern/kern_racct.c
  head/sys/kern/kern_rctl.c
  head/sys/sys/racct.h

Modified: head/sys/kern/kern_racct.c
==============================================================================
--- head/sys/kern/kern_racct.c	Thu Apr 21 16:12:55 2016	(r298413)
+++ head/sys/kern/kern_racct.c	Thu Apr 21 16:22:52 2016	(r298414)
@@ -91,13 +91,9 @@ SYSCTL_UINT(_kern_racct, OID_AUTO, pcpu_
  */
 #define RACCT_PCPU_SECS		3
 
-static struct mtx racct_lock;
+struct mtx racct_lock;
 MTX_SYSINIT(racct_lock, &racct_lock, "racct lock", MTX_DEF);
 
-#define RACCT_LOCK()		mtx_lock(&racct_lock)
-#define RACCT_UNLOCK()		mtx_unlock(&racct_lock)
-#define RACCT_LOCK_ASSERT()	mtx_assert(&racct_lock, MA_OWNED)
-
 static uma_zone_t racct_zone;
 
 static void racct_sub_racct(struct racct *dest, const struct racct *src);
@@ -111,6 +107,8 @@ SDT_PROBE_DEFINE3(racct, , rusage, add,
     "struct proc *", "int", "uint64_t");
 SDT_PROBE_DEFINE3(racct, , rusage, add__failure,
     "struct proc *", "int", "uint64_t");
+SDT_PROBE_DEFINE3(racct, , rusage, add__buf,
+    "struct proc *", "const struct buf *", "int");
 SDT_PROBE_DEFINE3(racct, , rusage, add__cred,
     "struct ucred *", "int", "uint64_t");
 SDT_PROBE_DEFINE3(racct, , rusage, add__force,
@@ -618,8 +616,6 @@ racct_add_cred_locked(struct ucred *cred
 
 	ASSERT_RACCT_ENABLED();
 
-	SDT_PROBE3(racct, , rusage, add__cred, cred, resource, amount);
-
 	racct_adjust_resource(cred->cr_ruidinfo->ui_racct, resource, amount);
 	for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
 		racct_adjust_resource(pr->pr_prison_racct->prr_racct, resource,
@@ -638,6 +634,8 @@ racct_add_cred(struct ucred *cred, int r
 	if (!racct_enable)
 		return;
 
+	SDT_PROBE3(racct, , rusage, add__cred, cred, resource, amount);
+
 	RACCT_LOCK();
 	racct_add_cred_locked(cred, resource, amount);
 	RACCT_UNLOCK();
@@ -654,6 +652,8 @@ racct_add_buf(struct proc *p, const stru
 	ASSERT_RACCT_ENABLED();
 	PROC_LOCK_ASSERT(p, MA_OWNED);
 
+	SDT_PROBE3(racct, , rusage, add__buf, p, bp, is_write);
+
 	RACCT_LOCK();
 	if (is_write) {
 		racct_add_locked(curproc, RACCT_WRITEBPS, bp->b_bcount, 1);
@@ -766,13 +766,19 @@ racct_set_force(struct proc *p, int reso
 uint64_t
 racct_get_limit(struct proc *p, int resource)
 {
+#ifdef RCTL
+	uint64_t available;
 
 	if (!racct_enable)
 		return (UINT64_MAX);
 
-#ifdef RCTL
-	return (rctl_get_limit(p, resource));
+	RACCT_LOCK();
+	available = rctl_get_limit(p, resource);
+	RACCT_UNLOCK();
+
+	return (available);
 #else
+
 	return (UINT64_MAX);
 #endif
 }
@@ -786,13 +792,19 @@ racct_get_limit(struct proc *p, int reso
 uint64_t
 racct_get_available(struct proc *p, int resource)
 {
+#ifdef RCTL
+	uint64_t available;
 
 	if (!racct_enable)
 		return (UINT64_MAX);
 
-#ifdef RCTL
-	return (rctl_get_available(p, resource));
+	RACCT_LOCK();
+	available = rctl_get_available(p, resource);
+	RACCT_UNLOCK();
+
+	return (available);
 #else
+
 	return (UINT64_MAX);
 #endif
 }
@@ -805,12 +817,18 @@ racct_get_available(struct proc *p, int 
 static int64_t
 racct_pcpu_available(struct proc *p)
 {
+#ifdef RCTL
+	uint64_t available;
 
 	ASSERT_RACCT_ENABLED();
 
-#ifdef RCTL
-	return (rctl_pcpu_available(p));
+	RACCT_LOCK();
+	available = rctl_pcpu_available(p);
+	RACCT_UNLOCK();
+
+	return (available);
 #else
+
 	return (INT64_MAX);
 #endif
 }
@@ -852,14 +870,6 @@ racct_sub_cred_locked(struct ucred *cred
 
 	ASSERT_RACCT_ENABLED();
 
-	SDT_PROBE3(racct, , rusage, sub__cred, cred, resource, amount);
-
-#ifdef notyet
-	KASSERT(RACCT_CAN_DROP(resource),
-	    ("%s: called for resource %d which can not drop", __func__,
-	     resource));
-#endif
-
 	racct_adjust_resource(cred->cr_ruidinfo->ui_racct, resource, -amount);
 	for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
 		racct_adjust_resource(pr->pr_prison_racct->prr_racct, resource,
@@ -877,6 +887,14 @@ racct_sub_cred(struct ucred *cred, int r
 	if (!racct_enable)
 		return;
 
+	SDT_PROBE3(racct, , rusage, sub__cred, cred, resource, amount);
+
+#ifdef notyet
+	KASSERT(RACCT_CAN_DROP(resource),
+	    ("%s: called for resource %d which can not drop", __func__,
+	     resource));
+#endif
+
 	RACCT_LOCK();
 	racct_sub_cred_locked(cred, resource, amount);
 	RACCT_UNLOCK();
@@ -948,11 +966,12 @@ void
 racct_proc_fork_done(struct proc *child)
 {
 
-	PROC_LOCK_ASSERT(child, MA_OWNED);
-#ifdef RCTL
 	if (!racct_enable)
 		return;
 
+	PROC_LOCK_ASSERT(child, MA_OWNED);
+
+#ifdef RCTL
 	RACCT_LOCK();
 	rctl_enforce(child, RACCT_NPROC, 0);
 	rctl_enforce(child, RACCT_NTHR, 0);
@@ -1003,13 +1022,12 @@ racct_proc_exit(struct proc *p)
 		racct_set_locked(p, i, 0, 0);
 	}
 
-	RACCT_UNLOCK();
-	PROC_UNLOCK(p);
-
 #ifdef RCTL
 	rctl_racct_release(p->p_racct);
 #endif
-	racct_destroy(&p->p_racct);
+	racct_destroy_locked(&p->p_racct);
+	RACCT_UNLOCK();
+	PROC_UNLOCK(p);
 }
 
 /*

Modified: head/sys/kern/kern_rctl.c
==============================================================================
--- head/sys/kern/kern_rctl.c	Thu Apr 21 16:12:55 2016	(r298413)
+++ head/sys/kern/kern_rctl.c	Thu Apr 21 16:22:52 2016	(r298414)
@@ -212,15 +212,6 @@ SYSINIT(rctl, SI_SUB_RACCT, SI_ORDER_FIR
 
 static uma_zone_t rctl_rule_zone;
 static uma_zone_t rctl_rule_link_zone;
-static struct rwlock rctl_lock;
-RW_SYSINIT(rctl_lock, &rctl_lock, "RCTL lock");
-
-#define RCTL_RLOCK()		rw_rlock(&rctl_lock)
-#define RCTL_RUNLOCK()		rw_runlock(&rctl_lock)
-#define RCTL_WLOCK()		rw_wlock(&rctl_lock)
-#define RCTL_WUNLOCK()		rw_wunlock(&rctl_lock)
-#define RCTL_LOCK_ASSERT()	rw_assert(&rctl_lock, RA_LOCKED)
-#define RCTL_WLOCK_ASSERT()	rw_assert(&rctl_lock, RA_WLOCKED)
 
 static int rctl_rule_fully_specified(const struct rctl_rule *rule);
 static void rctl_rule_to_sbuf(struct sbuf *sb, const struct rctl_rule *rule);
@@ -237,9 +228,9 @@ static int rctl_throttle_min_sysctl(SYSC
 	if (val < 1 || val > rctl_throttle_max)
 		return (EINVAL);
 
-	RCTL_WLOCK();
+	RACCT_LOCK();
 	rctl_throttle_min = val;
-	RCTL_WUNLOCK();
+	RACCT_UNLOCK();
 
 	return (0);
 }
@@ -254,9 +245,9 @@ static int rctl_throttle_max_sysctl(SYSC
 	if (val < rctl_throttle_min)
 		return (EINVAL);
 
-	RCTL_WLOCK();
+	RACCT_LOCK();
 	rctl_throttle_max = val;
-	RCTL_WUNLOCK();
+	RACCT_UNLOCK();
 
 	return (0);
 }
@@ -271,9 +262,9 @@ static int rctl_throttle_pct_sysctl(SYSC
 	if (val < 0)
 		return (EINVAL);
 
-	RCTL_WLOCK();
+	RACCT_LOCK();
 	rctl_throttle_pct = val;
-	RCTL_WUNLOCK();
+	RACCT_UNLOCK();
 
 	return (0);
 }
@@ -288,9 +279,9 @@ static int rctl_throttle_pct2_sysctl(SYS
 	if (val < 0)
 		return (EINVAL);
 
-	RCTL_WLOCK();
+	RACCT_LOCK();
 	rctl_throttle_pct2 = val;
-	RCTL_WUNLOCK();
+	RACCT_UNLOCK();
 
 	return (0);
 }
@@ -340,7 +331,7 @@ rctl_proc_rule_to_racct(const struct pro
 	struct ucred *cred = p->p_ucred;
 
 	ASSERT_RACCT_ENABLED();
-	RCTL_LOCK_ASSERT();
+	RACCT_LOCK_ASSERT();
 
 	switch (rule->rr_per) {
 	case RCTL_SUBJECT_TYPE_PROCESS:
@@ -367,7 +358,7 @@ rctl_available_resource(const struct pro
 	int64_t available;
 
 	ASSERT_RACCT_ENABLED();
-	RCTL_LOCK_ASSERT();
+	RACCT_LOCK_ASSERT();
 
 	racct = rctl_proc_rule_to_racct(p, rule);
 	available = rule->rr_amount - racct->r_resources[rule->rr_resource];
@@ -390,11 +381,10 @@ rctl_throttle_decay(struct racct *racct,
 	int64_t minavailable;
 
 	ASSERT_RACCT_ENABLED();
+	RACCT_LOCK_ASSERT();
 
 	minavailable = INT64_MAX;
 
-	RCTL_RLOCK();
-
 	LIST_FOREACH(link, &racct->r_rule_links, rrl_next) {
 		rule = link->rrl_rule;
 
@@ -407,8 +397,6 @@ rctl_throttle_decay(struct racct *racct,
 			minavailable = rule->rr_amount;
 	}
 
-	RCTL_RUNLOCK();
-
 	if (racct->r_resources[resource] < minavailable) {
 		racct->r_resources[resource] = 0;
 	} else {
@@ -436,12 +424,11 @@ rctl_pcpu_available(const struct proc *p
 	int64_t available, minavailable, limit;
 
 	ASSERT_RACCT_ENABLED();
+	RACCT_LOCK_ASSERT();
 
 	minavailable = INT64_MAX;
 	limit = 0;
 
-	RCTL_RLOCK();
-
 	LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
 		rule = link->rrl_rule;
 		if (rule->rr_resource != RACCT_PCTCPU)
@@ -455,8 +442,6 @@ rctl_pcpu_available(const struct proc *p
 		}
 	}
 
-	RCTL_RUNLOCK();
-
 	/*
 	 * Return slightly less than actual value of the available
 	 * %cpu resource.  This makes %cpu throttling more agressive
@@ -516,10 +501,8 @@ rctl_enforce(struct proc *p, int resourc
 	uint64_t sleep_ms, sleep_ratio;
 	int should_deny = 0;
 
-
 	ASSERT_RACCT_ENABLED();
-
-	RCTL_RLOCK();
+	RACCT_LOCK_ASSERT();
 
 	/*
 	 * There may be more than one matching rule; go through all of them.
@@ -693,8 +676,6 @@ rctl_enforce(struct proc *p, int resourc
 		}
 	}
 
-	RCTL_RUNLOCK();
-
 	if (should_deny) {
 		/*
 		 * Return fake error code; the caller should change it
@@ -714,8 +695,7 @@ rctl_get_limit(struct proc *p, int resou
 	uint64_t amount = UINT64_MAX;
 
 	ASSERT_RACCT_ENABLED();
-
-	RCTL_RLOCK();
+	RACCT_LOCK_ASSERT();
 
 	/*
 	 * There may be more than one matching rule; go through all of them.
@@ -731,8 +711,6 @@ rctl_get_limit(struct proc *p, int resou
 			amount = rule->rr_amount;
 	}
 
-	RCTL_RUNLOCK();
-
 	return (amount);
 }
 
@@ -746,8 +724,7 @@ rctl_get_available(struct proc *p, int r
 	minavailable = INT64_MAX;
 
 	ASSERT_RACCT_ENABLED();
-
-	RCTL_RLOCK();
+	RACCT_LOCK_ASSERT();
 
 	/*
 	 * There may be more than one matching rule; go through all of them.
@@ -764,8 +741,6 @@ rctl_get_available(struct proc *p, int r
 			minavailable = available;
 	}
 
-	RCTL_RUNLOCK();
-
 	/*
 	 * XXX: Think about this _hard_.
 	 */
@@ -774,6 +749,7 @@ rctl_get_available(struct proc *p, int r
 		minavailable += allocated;
 	if (minavailable < 0)
 		minavailable = 0;
+
 	return (minavailable);
 }
 
@@ -908,9 +884,9 @@ rctl_racct_add_rule(struct racct *racct,
 	link->rrl_rule = rule;
 	link->rrl_exceeded = 0;
 
-	RCTL_WLOCK();
+	RACCT_LOCK();
 	LIST_INSERT_HEAD(&racct->r_rule_links, link, rrl_next);
-	RCTL_WUNLOCK();
+	RACCT_UNLOCK();
 }
 
 static int
@@ -920,7 +896,7 @@ rctl_racct_add_rule_locked(struct racct 
 
 	ASSERT_RACCT_ENABLED();
 	KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified"));
-	RCTL_WLOCK_ASSERT();
+	RACCT_LOCK_ASSERT();
 
 	link = uma_zalloc(rctl_rule_link_zone, M_NOWAIT);
 	if (link == NULL)
@@ -930,6 +906,7 @@ rctl_racct_add_rule_locked(struct racct 
 	link->rrl_exceeded = 0;
 
 	LIST_INSERT_HEAD(&racct->r_rule_links, link, rrl_next);
+
 	return (0);
 }
 
@@ -946,7 +923,7 @@ rctl_racct_remove_rules(struct racct *ra
 	int removed = 0;
 
 	ASSERT_RACCT_ENABLED();
-	RCTL_WLOCK_ASSERT();
+	RACCT_LOCK_ASSERT();
 
 	LIST_FOREACH_SAFE(link, &racct->r_rule_links, rrl_next, linktmp) {
 		if (!rctl_rule_matches(link->rrl_rule, filter))
@@ -1417,14 +1394,14 @@ static void
 rctl_rule_pre_callback(void)
 {
 
-	RCTL_WLOCK();
+	RACCT_LOCK();
 }
 
 static void
 rctl_rule_post_callback(void)
 {
 
-	RCTL_WUNLOCK();
+	RACCT_UNLOCK();
 }
 
 static void
@@ -1434,7 +1411,7 @@ rctl_rule_remove_callback(struct racct *
 	int found = 0;
 
 	ASSERT_RACCT_ENABLED();
-	RCTL_WLOCK_ASSERT();
+	RACCT_LOCK_ASSERT();
 
 	found += rctl_racct_remove_rules(racct, filter);
 
@@ -1455,9 +1432,9 @@ rctl_rule_remove(struct rctl_rule *filte
 	if (filter->rr_subject_type == RCTL_SUBJECT_TYPE_PROCESS &&
 	    filter->rr_subject.rs_proc != NULL) {
 		p = filter->rr_subject.rs_proc;
-		RCTL_WLOCK();
+		RACCT_LOCK();
 		found = rctl_racct_remove_rules(p->p_racct, filter);
-		RCTL_WUNLOCK();
+		RACCT_UNLOCK();
 		if (found)
 			return (0);
 		return (ESRCH);
@@ -1474,11 +1451,11 @@ rctl_rule_remove(struct rctl_rule *filte
 	    filter, (void *)&found);
 
 	sx_assert(&allproc_lock, SA_LOCKED);
-	RCTL_WLOCK();
+	RACCT_LOCK();
 	FOREACH_PROC_IN_SYSTEM(p) {
 		found += rctl_racct_remove_rules(p->p_racct, filter);
 	}
-	RCTL_WUNLOCK();
+	RACCT_UNLOCK();
 
 	if (found)
 		return (0);
@@ -1610,7 +1587,9 @@ rctl_racct_to_sbuf(struct racct *racct, 
 	for (i = 0; i <= RACCT_MAX; i++) {
 		if (sloppy == 0 && RACCT_IS_SLOPPY(i))
 			continue;
+		RACCT_LOCK();
 		amount = racct->r_resources[i];
+		RACCT_UNLOCK();
 		if (RACCT_IS_IN_MILLIONS(i))
 			amount /= 1000000;
 		sbuf_printf(sb, "%s=%jd,", rctl_resource_name(i), amount);
@@ -1705,7 +1684,7 @@ rctl_get_rules_callback(struct racct *ra
 	struct sbuf *sb = (struct sbuf *)arg3;
 
 	ASSERT_RACCT_ENABLED();
-	RCTL_LOCK_ASSERT();
+	RACCT_LOCK_ASSERT();
 
 	LIST_FOREACH(link, &racct->r_rule_links, rrl_next) {
 		if (!rctl_rule_matches(link->rrl_rule, filter))
@@ -1756,7 +1735,7 @@ sys_rctl_get_rules(struct thread *td, st
 	KASSERT(sb != NULL, ("sbuf_new failed"));
 
 	FOREACH_PROC_IN_SYSTEM(p) {
-		RCTL_RLOCK();
+		RACCT_LOCK();
 		LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
 			/*
 			 * Non-process rules will be added to the buffer later.
@@ -1770,7 +1749,7 @@ sys_rctl_get_rules(struct thread *td, st
 			rctl_rule_to_sbuf(sb, link->rrl_rule);
 			sbuf_printf(sb, ",");
 		}
-		RCTL_RUNLOCK();
+		RACCT_UNLOCK();
 	}
 
 	loginclass_racct_foreach(rctl_get_rules_callback,
@@ -1857,13 +1836,13 @@ sys_rctl_get_limits(struct thread *td, s
 	sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN);
 	KASSERT(sb != NULL, ("sbuf_new failed"));
 
-	RCTL_RLOCK();
+	RACCT_LOCK();
 	LIST_FOREACH(link, &filter->rr_subject.rs_proc->p_racct->r_rule_links,
 	    rrl_next) {
 		rctl_rule_to_sbuf(sb, link->rrl_rule);
 		sbuf_printf(sb, ",");
 	}
-	RCTL_RUNLOCK();
+	RACCT_UNLOCK();
 	if (sbuf_error(sb) == ENOMEM) {
 		error = ERANGE;
 		sbuf_delete(sb);
@@ -1989,7 +1968,7 @@ again:
 	 * credentials.
 	 */
 	rulecnt = 0;
-	RCTL_RLOCK();
+	RACCT_LOCK();
 	LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
 		if (link->rrl_rule->rr_subject_type ==
 		    RCTL_SUBJECT_TYPE_PROCESS)
@@ -2001,7 +1980,7 @@ again:
 		rulecnt++;
 	LIST_FOREACH(link, &newprr->prr_racct->r_rule_links, rrl_next)
 		rulecnt++;
-	RCTL_RUNLOCK();
+	RACCT_UNLOCK();
 
 	/*
 	 * Create temporary list.  We've dropped the rctl_lock in order
@@ -2019,7 +1998,7 @@ again:
 	/*
 	 * Assign rules to the newly allocated list entries.
 	 */
-	RCTL_WLOCK();
+	RACCT_LOCK();
 	LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
 		if (link->rrl_rule->rr_subject_type ==
 		    RCTL_SUBJECT_TYPE_PROCESS) {
@@ -2087,13 +2066,13 @@ again:
 			    newlink, rrl_next);
 		}
 
-		RCTL_WUNLOCK();
+		RACCT_UNLOCK();
 
 		return;
 	}
 
 goaround:
-	RCTL_WUNLOCK();
+	RACCT_UNLOCK();
 
 	/*
 	 * Rule list changed while we were not holding the rctl_lock.
@@ -2120,12 +2099,11 @@ rctl_proc_fork(struct proc *parent, stru
 	struct rctl_rule_link *link;
 	int error;
 
-	LIST_INIT(&child->p_racct->r_rule_links);
-
 	ASSERT_RACCT_ENABLED();
+	RACCT_LOCK_ASSERT();
 	KASSERT(parent->p_racct != NULL, ("process without racct; p = %p", parent));
 
-	RCTL_WLOCK();
+	LIST_INIT(&child->p_racct->r_rule_links);
 
 	/*
 	 * Go through limits applicable to the parent and assign them
@@ -2154,7 +2132,6 @@ rctl_proc_fork(struct proc *parent, stru
 		}
 	}
 
-	RCTL_WUNLOCK();
 	return (0);
 
 fail:
@@ -2164,7 +2141,7 @@ fail:
 		rctl_rule_release(link->rrl_rule);
 		uma_zfree(rctl_rule_link_zone, link);
 	}
-	RCTL_WUNLOCK();
+
 	return (EAGAIN);
 }
 
@@ -2177,15 +2154,14 @@ rctl_racct_release(struct racct *racct)
 	struct rctl_rule_link *link;
 
 	ASSERT_RACCT_ENABLED();
+	RACCT_LOCK_ASSERT();
 
-	RCTL_WLOCK();
 	while (!LIST_EMPTY(&racct->r_rule_links)) {
 		link = LIST_FIRST(&racct->r_rule_links);
 		LIST_REMOVE(link, rrl_next);
 		rctl_rule_release(link->rrl_rule);
 		uma_zfree(rctl_rule_link_zone, link);
 	}
-	RCTL_WUNLOCK();
 }
 
 static void

Modified: head/sys/sys/racct.h
==============================================================================
--- head/sys/sys/racct.h	Thu Apr 21 16:12:55 2016	(r298413)
+++ head/sys/sys/racct.h	Thu Apr 21 16:22:52 2016	(r298414)
@@ -156,6 +156,12 @@ SYSCTL_DECL(_kern_racct);
 
 #ifdef RACCT
 
+extern struct mtx racct_lock;
+
+#define RACCT_LOCK()		mtx_lock(&racct_lock)
+#define RACCT_UNLOCK()		mtx_unlock(&racct_lock)
+#define RACCT_LOCK_ASSERT()	mtx_assert(&racct_lock, MA_OWNED)
+
 int	racct_add(struct proc *p, int resource, uint64_t amount);
 void	racct_add_cred(struct ucred *cred, int resource, uint64_t amount);
 void	racct_add_force(struct proc *p, int resource, uint64_t amount);


More information about the svn-src-all mailing list