* Called every second for proc, uidinfo, loginclass, and jail containers. * If the limit isn't exceeded, it decreases the usage amount to zero. * Otherwise, it decreases it by the value of the limit. This way * resource consumption exceeding the limit "carries over" to the next * period. */
| 380 | * period. |
| 381 | */ |
| 382 | void |
| 383 | rctl_throttle_decay(struct racct *racct, int resource) |
| 384 | { |
| 385 | struct rctl_rule *rule; |
| 386 | struct rctl_rule_link *link; |
| 387 | int64_t minavailable; |
| 388 | |
| 389 | ASSERT_RACCT_ENABLED(); |
| 390 | RACCT_LOCK_ASSERT(); |
| 391 | |
| 392 | minavailable = INT64_MAX; |
| 393 | |
| 394 | LIST_FOREACH(link, &racct->r_rule_links, rrl_next) { |
| 395 | rule = link->rrl_rule; |
| 396 | |
| 397 | if (rule->rr_resource != resource) |
| 398 | continue; |
| 399 | if (rule->rr_action != RCTL_ACTION_THROTTLE) |
| 400 | continue; |
| 401 | |
| 402 | if (rule->rr_amount < minavailable) |
| 403 | minavailable = rule->rr_amount; |
| 404 | } |
| 405 | |
| 406 | if (racct->r_resources[resource] < minavailable) { |
| 407 | racct->r_resources[resource] = 0; |
| 408 | } else { |
| 409 | /* |
| 410 | * Cap utilization counter at ten times the limit. Otherwise, |
| 411 | * if we changed the rule lowering the allowed amount, it could |
| 412 | * take unreasonably long time for the accumulated resource |
| 413 | * usage to drop. |
| 414 | */ |
| 415 | if (racct->r_resources[resource] > minavailable * 10) |
| 416 | racct->r_resources[resource] = minavailable * 10; |
| 417 | |
| 418 | racct->r_resources[resource] -= minavailable; |
| 419 | } |
| 420 | } |
| 421 | |
| 422 | /* |
| 423 | * Special version of rctl_get_available() for the %CPU resource. |
no outgoing calls
no test coverage detected