PERFORCE change 167035 for review
Edward Tomasz Napierala
trasz at FreeBSD.org
Wed Aug 5 16:12:25 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=167035
Change 167035 by trasz at trasz_anger on 2009/08/05 16:11:26
Improve locking.
Affected files ...
.. //depot/projects/soc2009/trasz_limits/TODO#9 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#43 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#20 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#27 edit
Differences ...
==== //depot/projects/soc2009/trasz_limits/TODO#9 (text+ko) ====
@@ -4,6 +4,9 @@
- Why did I put the loginclass pointer into the proc and not into the cred?
+ - Make the limits lists protected by the subjects lock (e.g. process lock)
+ instead of hrl_lock.
+
- Make sure we have all the gidinfos we need in the 'struct ucred'.
- Fix up (add/remove resource counters) when:
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#43 (text+ko) ====
@@ -682,26 +682,23 @@
mtx_unlock(&hrl_lock);
}
-#if 0
static int
-hrl_limit_remove(struct hrl_limits_head *limits_head, struct hrl_rule *rule)
+hrl_limit_add_locked(struct hrl_limits_head *limits_head, struct hrl_rule *rule)
{
- struct hrl_limit *limit, *limittmp;
+ struct hrl_limit *limit;
+
+ KASSERT(hrl_rule_fully_specified(rule), ("rule not fully specified"));
+ mtx_assert(&hrl_lock, MA_OWNED);
+
+ limit = uma_zalloc(hrl_limit_zone, M_NOWAIT);
+ if (limit == NULL)
+ return (ENOMEM);
+ hrl_rule_acquire(rule);
+ limit->hl_rule = rule;
- mtx_lock(&hrl_lock);
- LIST_FOREACH_SAFE(limit, limits_head, hl_next, limittmp) {
- if (limit->hl_rule == rule) {
- LIST_REMOVE(limit, hl_next);
- mtx_unlock(&hrl_lock);
- uma_zfree(hrl_limit_zone, limit);
- hrl_rule_release(rule);
- return (1);
- }
- }
- mtx_unlock(&hrl_lock);
+ LIST_INSERT_HEAD(limits_head, limit, hl_next);
return (0);
}
-#endif
/*
* Remove limits for a rules matching the filter and release
@@ -715,29 +712,28 @@
int removed = 0;
struct hrl_limit *limit, *limittmp;
-again:
mtx_lock(&hrl_lock);
LIST_FOREACH_SAFE(limit, limits_head, hl_next, limittmp) {
if (!hrl_rule_matches(limit->hl_rule, filter))
continue;
LIST_REMOVE(limit, hl_next);
- mtx_unlock(&hrl_lock);
hrl_rule_release(limit->hl_rule);
uma_zfree(hrl_limit_zone, limit);
removed++;
- goto again;
}
mtx_unlock(&hrl_lock);
return (removed);
}
struct hrl_rule *
-hrl_rule_alloc(void)
+hrl_rule_alloc(int flags)
{
struct hrl_rule *rule;
- rule = uma_zalloc(hrl_rule_zone, M_WAITOK);
+ rule = uma_zalloc(hrl_rule_zone, flags);
+ if (rule == NULL)
+ return (NULL);
rule->hr_subject = HRL_SUBJECT_UNDEFINED;
rule->hr_subject_id = HRL_SUBJECT_ID_UNDEFINED;
rule->hr_per = HRL_SUBJECT_UNDEFINED;
@@ -750,11 +746,13 @@
}
struct hrl_rule *
-hrl_rule_duplicate(const struct hrl_rule *rule)
+hrl_rule_duplicate(const struct hrl_rule *rule, int flags)
{
struct hrl_rule *copy;
- copy = uma_zalloc(hrl_rule_zone, M_WAITOK);
+ copy = uma_zalloc(hrl_rule_zone, flags);
+ if (copy == NULL)
+ return (NULL);
copy->hr_subject = rule->hr_subject;
copy->hr_subject_id = rule->hr_subject_id;
copy->hr_per = rule->hr_per;
@@ -819,7 +817,7 @@
struct loginclass *lc;
struct hrl_rule *rule;
- rule = hrl_rule_alloc();
+ rule = hrl_rule_alloc(M_WAITOK);
subjectstr = strsep(&rulestr, ":");
subject_idstr = strsep(&rulestr, ":");
@@ -1066,10 +1064,6 @@
error = gi_limits_foreach(hrl_rule_remove_callback, filter, (void *)&found, NULL);
KASSERT(error == 0, ("gi_limits_foreach failed"));
- /*
- * XXX: per-process, per-group, per-jail and per-class limits.
- */
-
sx_slock(&proctree_lock);
FOREACH_PROC_IN_SYSTEM(p) {
found += hrl_limit_remove_matching(&p->p_limits, filter);
@@ -1527,35 +1521,40 @@
hrl_proc_fork(void *arg __unused, struct proc *parent, struct proc *child,
int flags __unused)
{
- int i;
+ int error, i;
struct hrl_limit *limit;
struct hrl_rule *rule;
PROC_LOCK(parent);
PROC_LOCK(child);
+ mtx_lock(&hrl_lock);
+
for (i = 0; i < HRL_RESOURCE_MAX; i++) {
if (parent->p_usage.hu_resources[i] != 0 &&
hrl_resource_inheritable(i))
hrl_allocated_proc(child, i,
parent->p_usage.hu_resources[i]);
}
- PROC_UNLOCK(child);
- PROC_UNLOCK(parent);
- /*
- * XXX: What about locking the parent?
- */
LIST_FOREACH(limit, &parent->p_limits, hl_next) {
if (limit->hl_rule->hr_subject == HRL_SUBJECT_PROCESS) {
- rule = hrl_rule_duplicate(limit->hl_rule);
+ rule = hrl_rule_duplicate(limit->hl_rule, M_NOWAIT);
+ KASSERT(rule != NULL, ("XXX: better error handling needed"));
KASSERT(rule->hr_subject_id == parent->p_pid,
("rule->hr_subject_id == parent->p_pid"));
rule->hr_subject_id = child->p_pid;
- hrl_limit_add(&child->p_limits, rule);
+ error = hrl_limit_add_locked(&child->p_limits, rule);
+ KASSERT(error == 0, ("XXX: better error handling needed"));
hrl_rule_release(rule);
- } else
- hrl_limit_add(&child->p_limits, limit->hl_rule);
+ } else {
+ error = hrl_limit_add_locked(&child->p_limits, limit->hl_rule);
+ KASSERT(error == 0, ("XXX: better error handling needed"));
+ }
}
+
+ mtx_unlock(&hrl_lock);
+ PROC_UNLOCK(child);
+ PROC_UNLOCK(parent);
}
/*
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#20 (text+ko) ====
@@ -655,7 +655,7 @@
int error;
struct hrl_rule *rule, *rule2;
- rule = hrl_rule_alloc();
+ rule = hrl_rule_alloc(M_WAITOK);
rule->hr_subject = HRL_SUBJECT_PROCESS;
rule->hr_subject_id = td->td_proc->p_pid;
rule->hr_per = HRL_SUBJECT_PROCESS;
@@ -724,7 +724,7 @@
* rule, "deny".
*/
if (rule->hr_action != HRL_ACTION_DENY) {
- rule2 = hrl_rule_duplicate(rule);
+ rule2 = hrl_rule_duplicate(rule, M_WAITOK);
rule2->hr_action = HRL_ACTION_DENY;
hrl_rule_remove(rule2);
==== //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#27 (text+ko) ====
@@ -138,8 +138,8 @@
void hrl_usage_subtract(struct hrl_usage *dest, const struct hrl_usage *src);
void hrl_proc_exiting(struct proc *p);
-struct hrl_rule *hrl_rule_alloc(void);
-struct hrl_rule *hrl_rule_duplicate(const struct hrl_rule *rule);
+struct hrl_rule *hrl_rule_alloc(int flags);
+struct hrl_rule *hrl_rule_duplicate(const struct hrl_rule *rule, int flags);
void hrl_rule_acquire(struct hrl_rule *rule);
void hrl_rule_release(struct hrl_rule *rule);
int hrl_rule_add(struct hrl_rule *rule);
More information about the p4-projects
mailing list