PERFORCE change 187828 for review

Edward Tomasz Napierala trasz at FreeBSD.org
Sat Jan 15 09:05:10 UTC 2011


http://p4web.freebsd.org/@@187828?ac=10

Change 187828 by trasz at trasz_victim on 2011/01/15 09:04:04

	Protect rctl structures with rwlock; they rarely change
	(on fork/setwhateverid/exit and when rules get added or removed).

Affected files ...

.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_rctl.c#7 edit

Differences ...

==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_rctl.c#7 (text+ko) ====

@@ -53,6 +53,7 @@
 #include <sys/eventhandler.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
+#include <sys/rwlock.h>
 #include <sys/sbuf.h>
 #include <sys/tree.h>
 #include <vm/uma.h>
@@ -135,8 +136,8 @@
 
 static uma_zone_t rctl_rule_link_zone;
 static uma_zone_t rctl_rule_zone;
-static struct mtx rctl_lock;
-MTX_SYSINIT(rctl_lock, &rctl_lock, "RCTL lock", MTX_DEF);
+static struct rwlock rctl_lock;
+RW_SYSINIT(rctl_lock, &rctl_lock, "RCTL lock");
 
 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);
@@ -211,7 +212,7 @@
 	int64_t available = INT64_MAX;
 	struct ucred *cred = p->p_ucred;
 
-	mtx_assert(&rctl_lock, MA_OWNED);
+	rw_assert(&rctl_lock, RA_LOCKED);
 
 	resource = rule->hr_resource;
 	switch (rule->hr_per) {
@@ -249,7 +250,7 @@
 {
 	int64_t available;
 
-	mtx_assert(&rctl_lock, MA_OWNED);
+	rw_assert(&rctl_lock, RA_LOCKED);
 
 	available = rctl_available_resource(p, rule);
 	if (available >= amount)
@@ -286,7 +287,7 @@
 	static int curtime = 0;
 	static struct timeval lasttime;
 
-	mtx_lock(&rctl_lock);
+	rw_rlock(&rctl_lock);
 
 	/*
 	 * There may be more than one matching rule; go through all of them.
@@ -345,7 +346,7 @@
 		}
 	}
 
-	mtx_unlock(&rctl_lock);
+	rw_runlock(&rctl_lock);
 
 	if (should_deny) {
 		/*
@@ -365,7 +366,7 @@
 	struct rctl_rule_link *link;
 	uint64_t amount = UINT64_MAX;
 
-	mtx_lock(&rctl_lock);
+	rw_rlock(&rctl_lock);
 
 	/*
 	 * There may be more than one matching rule; go through all of them.
@@ -381,7 +382,7 @@
 			amount = rule->hr_amount;
 	}
 
-	mtx_unlock(&rctl_lock);
+	rw_runlock(&rctl_lock);
 
 	return (amount);
 }
@@ -510,9 +511,9 @@
 	link = uma_zalloc(rctl_rule_link_zone, M_WAITOK);
 	link->rctl_rule = rule;
 
-	mtx_lock(&rctl_lock);
+	rw_wlock(&rctl_lock);
 	LIST_INSERT_HEAD(&container->c_rule_links, link, rctl_next);
-	mtx_unlock(&rctl_lock);
+	rw_wunlock(&rctl_lock);
 }
 
 static int
@@ -521,7 +522,7 @@
 	struct rctl_rule_link *link;
 
 	KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified"));
-	mtx_assert(&rctl_lock, MA_OWNED);
+	rw_assert(&rctl_lock, RA_WLOCKED);
 
 	link = uma_zalloc(rctl_rule_link_zone, M_NOWAIT);
 	if (link == NULL)
@@ -545,7 +546,7 @@
 	int removed = 0;
 	struct rctl_rule_link *link, *linktmp;
 
-	mtx_assert(&rctl_lock, MA_OWNED);
+	rw_assert(&rctl_lock, RA_WLOCKED);
 
 	LIST_FOREACH_SAFE(link, &container->c_rule_links, rctl_next, linktmp) {
 		if (!rctl_rule_matches(link->rctl_rule, filter))
@@ -941,9 +942,9 @@
 	struct rctl_rule *filter = (struct rctl_rule *)arg2;
 	int found = 0;
 
-	mtx_lock(&rctl_lock);
+	rw_wlock(&rctl_lock);
 	found += rctl_container_remove_rules(container, filter);
-	mtx_unlock(&rctl_lock);
+	rw_wunlock(&rctl_lock);
 
 	*((int *)arg3) += found;
 
@@ -962,9 +963,9 @@
 	if (filter->hr_subject_type == RCTL_SUBJECT_TYPE_PROCESS &&
 	    filter->hr_subject.hs_proc != NULL) {
 		p = filter->hr_subject.hs_proc;
-		mtx_lock(&rctl_lock);
+		rw_wlock(&rctl_lock);
 		found = rctl_container_remove_rules(&p->p_container, filter);
-		mtx_unlock(&rctl_lock);
+		rw_wunlock(&rctl_lock);
 		if (found)
 			return (0);
 		return (ESRCH);
@@ -981,11 +982,11 @@
 	KASSERT(error == 0, ("prison_container_foreach failed"));
 
 	sx_assert(&allproc_lock, SA_LOCKED);
-	mtx_lock(&rctl_lock);
+	rw_wlock(&rctl_lock);
 	FOREACH_PROC_IN_SYSTEM(p) {
 		found += rctl_container_remove_rules(&p->p_container, filter);
 	}
-	mtx_unlock(&rctl_lock);
+	rw_wunlock(&rctl_lock);
 
 	if (found)
 		return (0);
@@ -1179,14 +1180,14 @@
 	struct rctl_rule_link *link;
 	struct sbuf *sb = (struct sbuf *)arg3;
 
-	mtx_lock(&rctl_lock);
+	rw_rlock(&rctl_lock);
 	LIST_FOREACH(link, &container->c_rule_links, rctl_next) {
 		if (!rctl_rule_matches(link->rctl_rule, filter))
 			continue;
 		rctl_rule_to_sbuf(sb, link->rctl_rule);
 		sbuf_printf(sb, ",");
 	}
-	mtx_unlock(&rctl_lock);
+	rw_runlock(&rctl_lock);
 
 	return (0);
 }
@@ -1221,7 +1222,7 @@
 
 	sx_assert(&allproc_lock, SA_LOCKED);
 	FOREACH_PROC_IN_SYSTEM(p) {
-		mtx_lock(&rctl_lock);
+		rw_rlock(&rctl_lock);
 		LIST_FOREACH(link, &p->p_container.c_rule_links, rctl_next) {
 			/*
 			 * Non-process rules will be added to the buffer later.
@@ -1234,7 +1235,7 @@
 			rctl_rule_to_sbuf(sb, link->rctl_rule);
 			sbuf_printf(sb, ",");
 		}
-		mtx_unlock(&rctl_lock);
+		rw_runlock(&rctl_lock);
 	}
 
 	loginclass_container_foreach(rctl_get_rules_callback, filter, sb);
@@ -1304,12 +1305,12 @@
 	sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN);
 	KASSERT(sb != NULL, ("sbuf_new failed"));
 
-	mtx_lock(&rctl_lock);
+	rw_rlock(&rctl_lock);
 	LIST_FOREACH(link, &filter->hr_subject.hs_proc->p_container.c_rule_links, rctl_next) {
 		rctl_rule_to_sbuf(sb, link->rctl_rule);
 		sbuf_printf(sb, ",");
 	}
-	mtx_unlock(&rctl_lock);
+	rw_runlock(&rctl_lock);
 	if (sbuf_error(sb) == ENOMEM) {
 		sbuf_delete(sb);
 		free(buf, M_RCTL);
@@ -1432,7 +1433,7 @@
 	/*
 	 * Remove rules that are no longer applicable with the new ucred.
 	 */
-	mtx_lock(&rctl_lock);
+	rw_wlock(&rctl_lock);
 	LIST_FOREACH(link, &p->p_container.c_rule_links, rctl_next) {
 		switch (link->rctl_rule->hr_subject_type) {
 		case RCTL_SUBJECT_TYPE_PROCESS:
@@ -1458,34 +1459,34 @@
 		rctl_rule_release(link->rctl_rule);
 		uma_zfree(rctl_rule_link_zone, link);
 	}
-	mtx_unlock(&rctl_lock);
+	rw_wunlock(&rctl_lock);
 	
 	/*
 	 * Add rules for the new ucred and move between containers where applicable.
 	 */
 	if (newuip != olduip) {
-		mtx_lock(&rctl_lock);
+		rw_wlock(&rctl_lock);
 		LIST_FOREACH(link, &newuip->ui_container.c_rule_links, rctl_next) {
 			error = rctl_container_add_rule_locked(&p->p_container, link->rctl_rule);
 			KASSERT(error == 0, ("XXX: better error handling needed"));
 		}
-		mtx_unlock(&rctl_lock);
+		rw_wunlock(&rctl_lock);
 	}
 	if (newlc != oldlc) {
-		mtx_lock(&rctl_lock);
+		rw_wlock(&rctl_lock);
 		LIST_FOREACH(link, &newlc->lc_container.c_rule_links, rctl_next) {
 			error = rctl_container_add_rule_locked(&p->p_container, link->rctl_rule);
 			KASSERT(error == 0, ("XXX: better error handling needed"));
 		}
-		mtx_unlock(&rctl_lock);
+		rw_wunlock(&rctl_lock);
 	}
 	if (newpr != oldpr) {
-		mtx_lock(&rctl_lock);
+		rw_wlock(&rctl_lock);
 		LIST_FOREACH(link, &newpr->pr_container.c_rule_links, rctl_next) {
 			error = rctl_container_add_rule_locked(&p->p_container, link->rctl_rule);
 			KASSERT(error == 0, ("XXX: better error handling needed"));
 		}
-		mtx_unlock(&rctl_lock);
+		rw_wunlock(&rctl_lock);
 	}
 }
 
@@ -1505,7 +1506,7 @@
 	if (child->p_flag & P_SYSTEM)
 		return (0);
 
-	mtx_lock(&rctl_lock);
+	rw_wlock(&rctl_lock);
 
 	/*
 	 * Go through limits applicable to the parent and assign them to the child.
@@ -1531,7 +1532,7 @@
 		}
 	}
 
-	mtx_unlock(&rctl_lock);
+	rw_wunlock(&rctl_lock);
 	return (0);
 
 fail:
@@ -1541,7 +1542,7 @@
 		rctl_rule_release(link->rctl_rule);
 		uma_zfree(rctl_rule_link_zone, link);
 	}
-	mtx_unlock(&rctl_lock);
+	rw_wunlock(&rctl_lock);
 	return (EAGAIN);
 }
 
@@ -1553,14 +1554,14 @@
 {
 	struct rctl_rule_link *link;
 
-	mtx_lock(&rctl_lock);
+	rw_wlock(&rctl_lock);
 	while (!LIST_EMPTY(&p->p_container.c_rule_links)) {
 		link = LIST_FIRST(&p->p_container.c_rule_links);
 		LIST_REMOVE(link, rctl_next);
 		rctl_rule_release(link->rctl_rule);
 		uma_zfree(rctl_rule_link_zone, link);
 	}
-	mtx_unlock(&rctl_lock);
+	rw_wunlock(&rctl_lock);
 }
 
 static void


More information about the p4-projects mailing list