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