diff options
author | Edward Tomasz Napierala <trasz@FreeBSD.org> | 2012-10-26 16:01:08 +0000 |
---|---|---|
committer | Edward Tomasz Napierala <trasz@FreeBSD.org> | 2012-10-26 16:01:08 +0000 |
commit | 36af98697d92141dcd4f4cca56da38a426ccb089 (patch) | |
tree | 842a8cfc3ef8239e42a28dbb369918bc9a00b13e /sys/kern/kern_rctl.c | |
parent | 6cff4e07c15477db7747f98dc7ecbedfe7563d40 (diff) | |
download | src-36af98697d92141dcd4f4cca56da38a426ccb089.tar.gz src-36af98697d92141dcd4f4cca56da38a426ccb089.zip |
Add CPU percentage limit enforcement to RCTL. The resouce name is "pcpu".
It was implemented by Rudolf Tomori during Google Summer of Code 2012.
Notes
Notes:
svn path=/head/; revision=242139
Diffstat (limited to 'sys/kern/kern_rctl.c')
-rw-r--r-- | sys/kern/kern_rctl.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/sys/kern/kern_rctl.c b/sys/kern/kern_rctl.c index 1d0a440da7a2..934327a41d82 100644 --- a/sys/kern/kern_rctl.c +++ b/sys/kern/kern_rctl.c @@ -76,6 +76,8 @@ FEATURE(rctl, "Resource Limits"); #define RCTL_MAX_INBUFLEN 4096 #define RCTL_LOG_BUFSIZE 128 +#define RCTL_PCPU_SHIFT (10 * 1000000) + /* * 'rctl_rule_link' connects a rule with every racct it's related to. * For example, rule 'user:X:openfiles:deny=N/process' is linked @@ -120,6 +122,7 @@ static struct dict resourcenames[] = { { "nshm", RACCT_NSHM }, { "shmsize", RACCT_SHMSIZE }, { "wallclock", RACCT_WALLCLOCK }, + { "pcpu", RACCT_PCTCPU }, { NULL, -1 }}; static struct dict actionnames[] = { @@ -271,6 +274,51 @@ rctl_would_exceed(const struct proc *p, const struct rctl_rule *rule, } /* + * Special version of rctl_available() function for the %cpu resource. + * We slightly cheat here and return less than we normally would. + */ +int64_t +rctl_pcpu_available(const struct proc *p) { + struct rctl_rule *rule; + struct rctl_rule_link *link; + int64_t available, minavailable, limit; + + minavailable = INT64_MAX; + limit = 0; + + rw_rlock(&rctl_lock); + + LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { + rule = link->rrl_rule; + if (rule->rr_resource != RACCT_PCTCPU) + continue; + if (rule->rr_action != RCTL_ACTION_DENY) + continue; + available = rctl_available_resource(p, rule); + if (available < minavailable) { + minavailable = available; + limit = rule->rr_amount; + } + } + + rw_runlock(&rctl_lock); + + /* + * Return slightly less than actual value of the available + * %cpu resource. This makes %cpu throttling more agressive + * and lets us act sooner than the limits are already exceeded. + */ + if (limit != 0) { + if (limit > 2 * RCTL_PCPU_SHIFT) + minavailable -= RCTL_PCPU_SHIFT; + else + minavailable -= (limit / 2); + } + + return (minavailable); +} + +/* * Check whether the proc 'p' can allocate 'amount' of 'resource' in addition * to what it keeps allocated now. Returns non-zero if the allocation should * be denied, 0 otherwise. |