From owner-p4-projects@FreeBSD.ORG Sat Aug 7 15:09:57 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D72C81065674; Sat, 7 Aug 2010 15:09:56 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 92406106564A for ; Sat, 7 Aug 2010 15:09:56 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 7F1AD8FC18 for ; Sat, 7 Aug 2010 15:09:56 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.4/8.14.4) with ESMTP id o77F9uwd006235 for ; Sat, 7 Aug 2010 15:09:56 GMT (envelope-from trasz@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.4/8.14.4/Submit) id o77F9uAa006233 for perforce@freebsd.org; Sat, 7 Aug 2010 15:09:56 GMT (envelope-from trasz@freebsd.org) Date: Sat, 7 Aug 2010 15:09:56 GMT Message-Id: <201008071509.o77F9uAa006233@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to trasz@freebsd.org using -f From: Edward Tomasz Napierala To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 182028 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 Aug 2010 15:09:57 -0000 http://p4web.freebsd.org/@@182028?ac=10 Change 182028 by trasz@trasz_victim on 2010/08/07 15:09:03 Enforce RUSAGE_RSS. Affected files ... .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_container.c#26 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#91 edit .. //depot/projects/soc2009/trasz_limits/sys/sys/container.h#10 edit .. //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#48 edit .. //depot/projects/soc2009/trasz_limits/sys/vm/vm_pageout.c#11 edit Differences ... ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_container.c#26 (text+ko) ==== @@ -98,6 +98,18 @@ } static int +container_resource_deniable(int resource) +{ + + switch (resource) { + case RUSAGE_RSS: + return (0); + default: + return (1); + } +} + +static int container_add(struct container *dest, const struct container *src) { int i, error; @@ -361,7 +373,7 @@ mtx_lock(&container_lock); #ifdef HRL error = hrl_enforce_proc(p, resource, amount); - if (error) { + if (error && container_resource_deniable(resource)) { SDT_PROBE(container, kernel, rusage, add_failure, p, resource, amount, 0, 0); mtx_unlock(&container_lock); return (error); @@ -398,7 +410,7 @@ #ifdef HRL if (diff > 0) { error = hrl_enforce_proc(p, resource, diff); - if (error) { + if (error && container_resource_deniable(resource)) { SDT_PROBE(container, kernel, rusage, set_failure, p, resource, amount, 0, 0); return (error); } @@ -427,6 +439,22 @@ return (error); } + +/* + * Returns amount of 'resource' the process 'p' can keep allocated. + * Allocating more than that would be denied, unless the resource + * is marked undeniable. + */ +uint64_t +rusage_get_limit(struct proc *p, int resource) +{ + +#ifdef HRL + return (hrl_available_proc(p, resource)); +#else + return (UINT64_MAX); +#endif +} /* * Decrease allocation of 'resource' by 'amount' for process 'p'. ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#91 (text+ko) ==== @@ -247,7 +247,8 @@ */ if (available < 0) { #ifdef notyet - KASSERT(rule->hr_action != HRL_ACTION_DENY, + KASSERT(rule->hr_action != HRL_ACTION_DENY || + !container_resource_deniable(rule->hr_resource), ("hrl_would_exceed: deny rule already exceeded")); #endif return (0); @@ -339,6 +340,34 @@ return (0); } +uint64_t +hrl_available_proc(struct proc *p, int resource) +{ + struct hrl_rule *rule; + struct hrl_rule_link *link; + uint64_t amount = UINT64_MAX; + + mtx_lock(&hrl_lock); + + /* + * There may be more than one matching rule; go through all of them. + * Denial should be done last, after logging and sending signals. + */ + LIST_FOREACH(link, &p->p_container.c_rule_links, hrl_next) { + rule = link->hrl_rule; + if (rule->hr_resource != resource) + continue; + if (rule->hr_action != HRL_ACTION_DENY) + continue; + if (rule->hr_amount < amount) + amount = rule->hr_amount; + } + + mtx_unlock(&hrl_lock); + + return (amount); +} + static int hrl_rule_matches(const struct hrl_rule *rule, const struct hrl_rule *filter) { ==== //depot/projects/soc2009/trasz_limits/sys/sys/container.h#10 (text+ko) ==== @@ -95,6 +95,7 @@ int rusage_add(struct proc *p, int object, uint64_t amount); int rusage_set(struct proc *p, int object, uint64_t amount); void rusage_sub(struct proc *p, int object, uint64_t amount); +uint64_t rusage_get_limit(struct proc *p, int object); void container_create(struct container *container); void container_destroy(struct container *container); ==== //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#48 (text+ko) ==== @@ -118,7 +118,8 @@ int hrl_rule_remove(const struct hrl_rule *filter); int hrl_enforce_proc(struct proc *p, int resource, uint64_t amount); -const char *hrl_resource_name(int resource); +uint64_t hrl_available_proc(struct proc *p, int resource); +const char *hrl_resource_name(int resource); int hrl_proc_fork(struct proc *parent, struct proc *child); void hrl_proc_exit(struct proc *p); #else /* !_KERNEL */ ==== //depot/projects/soc2009/trasz_limits/sys/vm/vm_pageout.c#11 (text+ko) ==== @@ -79,6 +79,7 @@ #include #include #include +#include #include #include #include @@ -1620,6 +1621,9 @@ struct thread *td; struct vmspace *vm; int breakout, swapout_flags; +#ifdef CONTAINERS + uint64_t maxsize; +#endif while (TRUE) { mtx_lock(&vm_daemon_mtx); @@ -1691,6 +1695,14 @@ vm_pageout_map_deactivate_pages( &vm->vm_map, limit); } +#ifdef CONTAINERS + rusage_set(p, RUSAGE_RSS, IDX_TO_OFF(size)); + maxsize = OFF_TO_IDX(rusage_get_limit(p, RUSAGE_RSS)); + if (size > maxsize) { + vm_pageout_map_deactivate_pages( + &vm->vm_map, limit); + } +#endif vmspace_free(vm); } sx_sunlock(&allproc_lock);