diff options
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. |