kern_rctl.c (298330) | kern_rctl.c (298414) |
---|---|
1/*- 2 * Copyright (c) 2010 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Edward Tomasz Napierala under sponsorship 6 * from the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 12 unchanged lines hidden (view full) --- 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * | 1/*- 2 * Copyright (c) 2010 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Edward Tomasz Napierala under sponsorship 6 * from the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 12 unchanged lines hidden (view full) --- 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * |
29 * $FreeBSD: head/sys/kern/kern_rctl.c 298330 2016-04-20 02:09:38Z cem $ | 29 * $FreeBSD: head/sys/kern/kern_rctl.c 298414 2016-04-21 16:22:52Z trasz $ |
30 */ 31 32#include <sys/cdefs.h> | 30 */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/kern/kern_rctl.c 298330 2016-04-20 02:09:38Z cem $"); | 33__FBSDID("$FreeBSD: head/sys/kern/kern_rctl.c 298414 2016-04-21 16:22:52Z trasz $"); |
34 35#include <sys/param.h> 36#include <sys/bus.h> 37#include <sys/malloc.h> 38#include <sys/queue.h> 39#include <sys/refcount.h> 40#include <sys/jail.h> 41#include <sys/kernel.h> --- 165 unchanged lines hidden (view full) --- 207 { "throttle", RCTL_ACTION_THROTTLE }, 208 { NULL, -1 }}; 209 210static void rctl_init(void); 211SYSINIT(rctl, SI_SUB_RACCT, SI_ORDER_FIRST, rctl_init, NULL); 212 213static uma_zone_t rctl_rule_zone; 214static uma_zone_t rctl_rule_link_zone; | 34 35#include <sys/param.h> 36#include <sys/bus.h> 37#include <sys/malloc.h> 38#include <sys/queue.h> 39#include <sys/refcount.h> 40#include <sys/jail.h> 41#include <sys/kernel.h> --- 165 unchanged lines hidden (view full) --- 207 { "throttle", RCTL_ACTION_THROTTLE }, 208 { NULL, -1 }}; 209 210static void rctl_init(void); 211SYSINIT(rctl, SI_SUB_RACCT, SI_ORDER_FIRST, rctl_init, NULL); 212 213static uma_zone_t rctl_rule_zone; 214static uma_zone_t rctl_rule_link_zone; |
215static struct rwlock rctl_lock; 216RW_SYSINIT(rctl_lock, &rctl_lock, "RCTL lock"); | |
217 | 215 |
218#define RCTL_RLOCK() rw_rlock(&rctl_lock) 219#define RCTL_RUNLOCK() rw_runlock(&rctl_lock) 220#define RCTL_WLOCK() rw_wlock(&rctl_lock) 221#define RCTL_WUNLOCK() rw_wunlock(&rctl_lock) 222#define RCTL_LOCK_ASSERT() rw_assert(&rctl_lock, RA_LOCKED) 223#define RCTL_WLOCK_ASSERT() rw_assert(&rctl_lock, RA_WLOCKED) 224 | |
225static int rctl_rule_fully_specified(const struct rctl_rule *rule); 226static void rctl_rule_to_sbuf(struct sbuf *sb, const struct rctl_rule *rule); 227 228static MALLOC_DEFINE(M_RCTL, "rctl", "Resource Limits"); 229 230static int rctl_throttle_min_sysctl(SYSCTL_HANDLER_ARGS) 231{ 232 int error, val = rctl_throttle_min; 233 234 error = sysctl_handle_int(oidp, &val, 0, req); 235 if (error || !req->newptr) 236 return (error); 237 if (val < 1 || val > rctl_throttle_max) 238 return (EINVAL); 239 | 216static int rctl_rule_fully_specified(const struct rctl_rule *rule); 217static void rctl_rule_to_sbuf(struct sbuf *sb, const struct rctl_rule *rule); 218 219static MALLOC_DEFINE(M_RCTL, "rctl", "Resource Limits"); 220 221static int rctl_throttle_min_sysctl(SYSCTL_HANDLER_ARGS) 222{ 223 int error, val = rctl_throttle_min; 224 225 error = sysctl_handle_int(oidp, &val, 0, req); 226 if (error || !req->newptr) 227 return (error); 228 if (val < 1 || val > rctl_throttle_max) 229 return (EINVAL); 230 |
240 RCTL_WLOCK(); | 231 RACCT_LOCK(); |
241 rctl_throttle_min = val; | 232 rctl_throttle_min = val; |
242 RCTL_WUNLOCK(); | 233 RACCT_UNLOCK(); |
243 244 return (0); 245} 246 247static int rctl_throttle_max_sysctl(SYSCTL_HANDLER_ARGS) 248{ 249 int error, val = rctl_throttle_max; 250 251 error = sysctl_handle_int(oidp, &val, 0, req); 252 if (error || !req->newptr) 253 return (error); 254 if (val < rctl_throttle_min) 255 return (EINVAL); 256 | 234 235 return (0); 236} 237 238static int rctl_throttle_max_sysctl(SYSCTL_HANDLER_ARGS) 239{ 240 int error, val = rctl_throttle_max; 241 242 error = sysctl_handle_int(oidp, &val, 0, req); 243 if (error || !req->newptr) 244 return (error); 245 if (val < rctl_throttle_min) 246 return (EINVAL); 247 |
257 RCTL_WLOCK(); | 248 RACCT_LOCK(); |
258 rctl_throttle_max = val; | 249 rctl_throttle_max = val; |
259 RCTL_WUNLOCK(); | 250 RACCT_UNLOCK(); |
260 261 return (0); 262} 263 264static int rctl_throttle_pct_sysctl(SYSCTL_HANDLER_ARGS) 265{ 266 int error, val = rctl_throttle_pct; 267 268 error = sysctl_handle_int(oidp, &val, 0, req); 269 if (error || !req->newptr) 270 return (error); 271 if (val < 0) 272 return (EINVAL); 273 | 251 252 return (0); 253} 254 255static int rctl_throttle_pct_sysctl(SYSCTL_HANDLER_ARGS) 256{ 257 int error, val = rctl_throttle_pct; 258 259 error = sysctl_handle_int(oidp, &val, 0, req); 260 if (error || !req->newptr) 261 return (error); 262 if (val < 0) 263 return (EINVAL); 264 |
274 RCTL_WLOCK(); | 265 RACCT_LOCK(); |
275 rctl_throttle_pct = val; | 266 rctl_throttle_pct = val; |
276 RCTL_WUNLOCK(); | 267 RACCT_UNLOCK(); |
277 278 return (0); 279} 280 281static int rctl_throttle_pct2_sysctl(SYSCTL_HANDLER_ARGS) 282{ 283 int error, val = rctl_throttle_pct2; 284 285 error = sysctl_handle_int(oidp, &val, 0, req); 286 if (error || !req->newptr) 287 return (error); 288 if (val < 0) 289 return (EINVAL); 290 | 268 269 return (0); 270} 271 272static int rctl_throttle_pct2_sysctl(SYSCTL_HANDLER_ARGS) 273{ 274 int error, val = rctl_throttle_pct2; 275 276 error = sysctl_handle_int(oidp, &val, 0, req); 277 if (error || !req->newptr) 278 return (error); 279 if (val < 0) 280 return (EINVAL); 281 |
291 RCTL_WLOCK(); | 282 RACCT_LOCK(); |
292 rctl_throttle_pct2 = val; | 283 rctl_throttle_pct2 = val; |
293 RCTL_WUNLOCK(); | 284 RACCT_UNLOCK(); |
294 295 return (0); 296} 297 298static const char * 299rctl_subject_type_name(int subject) 300{ 301 int i; --- 33 unchanged lines hidden (view full) --- 335} 336 337static struct racct * 338rctl_proc_rule_to_racct(const struct proc *p, const struct rctl_rule *rule) 339{ 340 struct ucred *cred = p->p_ucred; 341 342 ASSERT_RACCT_ENABLED(); | 285 286 return (0); 287} 288 289static const char * 290rctl_subject_type_name(int subject) 291{ 292 int i; --- 33 unchanged lines hidden (view full) --- 326} 327 328static struct racct * 329rctl_proc_rule_to_racct(const struct proc *p, const struct rctl_rule *rule) 330{ 331 struct ucred *cred = p->p_ucred; 332 333 ASSERT_RACCT_ENABLED(); |
343 RCTL_LOCK_ASSERT(); | 334 RACCT_LOCK_ASSERT(); |
344 345 switch (rule->rr_per) { 346 case RCTL_SUBJECT_TYPE_PROCESS: 347 return (p->p_racct); 348 case RCTL_SUBJECT_TYPE_USER: 349 return (cred->cr_ruidinfo->ui_racct); 350 case RCTL_SUBJECT_TYPE_LOGINCLASS: 351 return (cred->cr_loginclass->lc_racct); --- 10 unchanged lines hidden (view full) --- 362 */ 363static int64_t 364rctl_available_resource(const struct proc *p, const struct rctl_rule *rule) 365{ 366 const struct racct *racct; 367 int64_t available; 368 369 ASSERT_RACCT_ENABLED(); | 335 336 switch (rule->rr_per) { 337 case RCTL_SUBJECT_TYPE_PROCESS: 338 return (p->p_racct); 339 case RCTL_SUBJECT_TYPE_USER: 340 return (cred->cr_ruidinfo->ui_racct); 341 case RCTL_SUBJECT_TYPE_LOGINCLASS: 342 return (cred->cr_loginclass->lc_racct); --- 10 unchanged lines hidden (view full) --- 353 */ 354static int64_t 355rctl_available_resource(const struct proc *p, const struct rctl_rule *rule) 356{ 357 const struct racct *racct; 358 int64_t available; 359 360 ASSERT_RACCT_ENABLED(); |
370 RCTL_LOCK_ASSERT(); | 361 RACCT_LOCK_ASSERT(); |
371 372 racct = rctl_proc_rule_to_racct(p, rule); 373 available = rule->rr_amount - racct->r_resources[rule->rr_resource]; 374 375 return (available); 376} 377 378/* --- 6 unchanged lines hidden (view full) --- 385void 386rctl_throttle_decay(struct racct *racct, int resource) 387{ 388 struct rctl_rule *rule; 389 struct rctl_rule_link *link; 390 int64_t minavailable; 391 392 ASSERT_RACCT_ENABLED(); | 362 363 racct = rctl_proc_rule_to_racct(p, rule); 364 available = rule->rr_amount - racct->r_resources[rule->rr_resource]; 365 366 return (available); 367} 368 369/* --- 6 unchanged lines hidden (view full) --- 376void 377rctl_throttle_decay(struct racct *racct, int resource) 378{ 379 struct rctl_rule *rule; 380 struct rctl_rule_link *link; 381 int64_t minavailable; 382 383 ASSERT_RACCT_ENABLED(); |
384 RACCT_LOCK_ASSERT(); |
|
393 394 minavailable = INT64_MAX; 395 | 385 386 minavailable = INT64_MAX; 387 |
396 RCTL_RLOCK(); 397 | |
398 LIST_FOREACH(link, &racct->r_rule_links, rrl_next) { 399 rule = link->rrl_rule; 400 401 if (rule->rr_resource != resource) 402 continue; 403 if (rule->rr_action != RCTL_ACTION_THROTTLE) 404 continue; 405 406 if (rule->rr_amount < minavailable) 407 minavailable = rule->rr_amount; 408 } 409 | 388 LIST_FOREACH(link, &racct->r_rule_links, rrl_next) { 389 rule = link->rrl_rule; 390 391 if (rule->rr_resource != resource) 392 continue; 393 if (rule->rr_action != RCTL_ACTION_THROTTLE) 394 continue; 395 396 if (rule->rr_amount < minavailable) 397 minavailable = rule->rr_amount; 398 } 399 |
410 RCTL_RUNLOCK(); 411 | |
412 if (racct->r_resources[resource] < minavailable) { 413 racct->r_resources[resource] = 0; 414 } else { 415 /* 416 * Cap utilization counter at ten times the limit. Otherwise, 417 * if we changed the rule lowering the allowed amount, it could 418 * take unreasonably long time for the accumulated resource 419 * usage to drop. --- 11 unchanged lines hidden (view full) --- 431 */ 432int64_t 433rctl_pcpu_available(const struct proc *p) { 434 struct rctl_rule *rule; 435 struct rctl_rule_link *link; 436 int64_t available, minavailable, limit; 437 438 ASSERT_RACCT_ENABLED(); | 400 if (racct->r_resources[resource] < minavailable) { 401 racct->r_resources[resource] = 0; 402 } else { 403 /* 404 * Cap utilization counter at ten times the limit. Otherwise, 405 * if we changed the rule lowering the allowed amount, it could 406 * take unreasonably long time for the accumulated resource 407 * usage to drop. --- 11 unchanged lines hidden (view full) --- 419 */ 420int64_t 421rctl_pcpu_available(const struct proc *p) { 422 struct rctl_rule *rule; 423 struct rctl_rule_link *link; 424 int64_t available, minavailable, limit; 425 426 ASSERT_RACCT_ENABLED(); |
427 RACCT_LOCK_ASSERT(); |
|
439 440 minavailable = INT64_MAX; 441 limit = 0; 442 | 428 429 minavailable = INT64_MAX; 430 limit = 0; 431 |
443 RCTL_RLOCK(); 444 | |
445 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { 446 rule = link->rrl_rule; 447 if (rule->rr_resource != RACCT_PCTCPU) 448 continue; 449 if (rule->rr_action != RCTL_ACTION_DENY) 450 continue; 451 available = rctl_available_resource(p, rule); 452 if (available < minavailable) { 453 minavailable = available; 454 limit = rule->rr_amount; 455 } 456 } 457 | 432 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { 433 rule = link->rrl_rule; 434 if (rule->rr_resource != RACCT_PCTCPU) 435 continue; 436 if (rule->rr_action != RCTL_ACTION_DENY) 437 continue; 438 available = rctl_available_resource(p, rule); 439 if (available < minavailable) { 440 minavailable = available; 441 limit = rule->rr_amount; 442 } 443 } 444 |
458 RCTL_RUNLOCK(); 459 | |
460 /* 461 * Return slightly less than actual value of the available 462 * %cpu resource. This makes %cpu throttling more agressive 463 * and lets us act sooner than the limits are already exceeded. 464 */ 465 if (limit != 0) { 466 if (limit > 2 * RCTL_PCPU_SHIFT) 467 minavailable -= RCTL_PCPU_SHIFT; --- 43 unchanged lines hidden (view full) --- 511 struct rctl_rule *rule; 512 struct rctl_rule_link *link; 513 struct sbuf sb; 514 char *buf; 515 int64_t available; 516 uint64_t sleep_ms, sleep_ratio; 517 int should_deny = 0; 518 | 445 /* 446 * Return slightly less than actual value of the available 447 * %cpu resource. This makes %cpu throttling more agressive 448 * and lets us act sooner than the limits are already exceeded. 449 */ 450 if (limit != 0) { 451 if (limit > 2 * RCTL_PCPU_SHIFT) 452 minavailable -= RCTL_PCPU_SHIFT; --- 43 unchanged lines hidden (view full) --- 496 struct rctl_rule *rule; 497 struct rctl_rule_link *link; 498 struct sbuf sb; 499 char *buf; 500 int64_t available; 501 uint64_t sleep_ms, sleep_ratio; 502 int should_deny = 0; 503 |
519 | |
520 ASSERT_RACCT_ENABLED(); | 504 ASSERT_RACCT_ENABLED(); |
505 RACCT_LOCK_ASSERT(); |
|
521 | 506 |
522 RCTL_RLOCK(); 523 | |
524 /* 525 * There may be more than one matching rule; go through all of them. 526 * Denial should be done last, after logging and sending signals. 527 */ 528 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { 529 rule = link->rrl_rule; 530 if (rule->rr_resource != resource) 531 continue; --- 156 unchanged lines hidden (view full) --- 688 * are equal to their counterparts from sys/signal.h. 689 */ 690 kern_psignal(p, rule->rr_action); 691 link->rrl_exceeded = 1; 692 continue; 693 } 694 } 695 | 507 /* 508 * There may be more than one matching rule; go through all of them. 509 * Denial should be done last, after logging and sending signals. 510 */ 511 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { 512 rule = link->rrl_rule; 513 if (rule->rr_resource != resource) 514 continue; --- 156 unchanged lines hidden (view full) --- 671 * are equal to their counterparts from sys/signal.h. 672 */ 673 kern_psignal(p, rule->rr_action); 674 link->rrl_exceeded = 1; 675 continue; 676 } 677 } 678 |
696 RCTL_RUNLOCK(); 697 | |
698 if (should_deny) { 699 /* 700 * Return fake error code; the caller should change it 701 * into one proper for the situation - EFSIZ, ENOMEM etc. 702 */ 703 return (EDOOFUS); 704 } 705 706 return (0); 707} 708 709uint64_t 710rctl_get_limit(struct proc *p, int resource) 711{ 712 struct rctl_rule *rule; 713 struct rctl_rule_link *link; 714 uint64_t amount = UINT64_MAX; 715 716 ASSERT_RACCT_ENABLED(); | 679 if (should_deny) { 680 /* 681 * Return fake error code; the caller should change it 682 * into one proper for the situation - EFSIZ, ENOMEM etc. 683 */ 684 return (EDOOFUS); 685 } 686 687 return (0); 688} 689 690uint64_t 691rctl_get_limit(struct proc *p, int resource) 692{ 693 struct rctl_rule *rule; 694 struct rctl_rule_link *link; 695 uint64_t amount = UINT64_MAX; 696 697 ASSERT_RACCT_ENABLED(); |
698 RACCT_LOCK_ASSERT(); |
|
717 | 699 |
718 RCTL_RLOCK(); 719 | |
720 /* 721 * There may be more than one matching rule; go through all of them. 722 * Denial should be done last, after logging and sending signals. 723 */ 724 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { 725 rule = link->rrl_rule; 726 if (rule->rr_resource != resource) 727 continue; 728 if (rule->rr_action != RCTL_ACTION_DENY) 729 continue; 730 if (rule->rr_amount < amount) 731 amount = rule->rr_amount; 732 } 733 | 700 /* 701 * There may be more than one matching rule; go through all of them. 702 * Denial should be done last, after logging and sending signals. 703 */ 704 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { 705 rule = link->rrl_rule; 706 if (rule->rr_resource != resource) 707 continue; 708 if (rule->rr_action != RCTL_ACTION_DENY) 709 continue; 710 if (rule->rr_amount < amount) 711 amount = rule->rr_amount; 712 } 713 |
734 RCTL_RUNLOCK(); 735 | |
736 return (amount); 737} 738 739uint64_t 740rctl_get_available(struct proc *p, int resource) 741{ 742 struct rctl_rule *rule; 743 struct rctl_rule_link *link; 744 int64_t available, minavailable, allocated; 745 746 minavailable = INT64_MAX; 747 748 ASSERT_RACCT_ENABLED(); | 714 return (amount); 715} 716 717uint64_t 718rctl_get_available(struct proc *p, int resource) 719{ 720 struct rctl_rule *rule; 721 struct rctl_rule_link *link; 722 int64_t available, minavailable, allocated; 723 724 minavailable = INT64_MAX; 725 726 ASSERT_RACCT_ENABLED(); |
727 RACCT_LOCK_ASSERT(); |
|
749 | 728 |
750 RCTL_RLOCK(); 751 | |
752 /* 753 * There may be more than one matching rule; go through all of them. 754 * Denial should be done last, after logging and sending signals. 755 */ 756 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { 757 rule = link->rrl_rule; 758 if (rule->rr_resource != resource) 759 continue; 760 if (rule->rr_action != RCTL_ACTION_DENY) 761 continue; 762 available = rctl_available_resource(p, rule); 763 if (available < minavailable) 764 minavailable = available; 765 } 766 | 729 /* 730 * There may be more than one matching rule; go through all of them. 731 * Denial should be done last, after logging and sending signals. 732 */ 733 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { 734 rule = link->rrl_rule; 735 if (rule->rr_resource != resource) 736 continue; 737 if (rule->rr_action != RCTL_ACTION_DENY) 738 continue; 739 available = rctl_available_resource(p, rule); 740 if (available < minavailable) 741 minavailable = available; 742 } 743 |
767 RCTL_RUNLOCK(); 768 | |
769 /* 770 * XXX: Think about this _hard_. 771 */ 772 allocated = p->p_racct->r_resources[resource]; 773 if (minavailable < INT64_MAX - allocated) 774 minavailable += allocated; 775 if (minavailable < 0) 776 minavailable = 0; | 744 /* 745 * XXX: Think about this _hard_. 746 */ 747 allocated = p->p_racct->r_resources[resource]; 748 if (minavailable < INT64_MAX - allocated) 749 minavailable += allocated; 750 if (minavailable < 0) 751 minavailable = 0; |
752 |
|
777 return (minavailable); 778} 779 780static int 781rctl_rule_matches(const struct rctl_rule *rule, const struct rctl_rule *filter) 782{ 783 784 ASSERT_RACCT_ENABLED(); --- 118 unchanged lines hidden (view full) --- 903 ASSERT_RACCT_ENABLED(); 904 KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified")); 905 906 rctl_rule_acquire(rule); 907 link = uma_zalloc(rctl_rule_link_zone, M_WAITOK); 908 link->rrl_rule = rule; 909 link->rrl_exceeded = 0; 910 | 753 return (minavailable); 754} 755 756static int 757rctl_rule_matches(const struct rctl_rule *rule, const struct rctl_rule *filter) 758{ 759 760 ASSERT_RACCT_ENABLED(); --- 118 unchanged lines hidden (view full) --- 879 ASSERT_RACCT_ENABLED(); 880 KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified")); 881 882 rctl_rule_acquire(rule); 883 link = uma_zalloc(rctl_rule_link_zone, M_WAITOK); 884 link->rrl_rule = rule; 885 link->rrl_exceeded = 0; 886 |
911 RCTL_WLOCK(); | 887 RACCT_LOCK(); |
912 LIST_INSERT_HEAD(&racct->r_rule_links, link, rrl_next); | 888 LIST_INSERT_HEAD(&racct->r_rule_links, link, rrl_next); |
913 RCTL_WUNLOCK(); | 889 RACCT_UNLOCK(); |
914} 915 916static int 917rctl_racct_add_rule_locked(struct racct *racct, struct rctl_rule *rule) 918{ 919 struct rctl_rule_link *link; 920 921 ASSERT_RACCT_ENABLED(); 922 KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified")); | 890} 891 892static int 893rctl_racct_add_rule_locked(struct racct *racct, struct rctl_rule *rule) 894{ 895 struct rctl_rule_link *link; 896 897 ASSERT_RACCT_ENABLED(); 898 KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified")); |
923 RCTL_WLOCK_ASSERT(); | 899 RACCT_LOCK_ASSERT(); |
924 925 link = uma_zalloc(rctl_rule_link_zone, M_NOWAIT); 926 if (link == NULL) 927 return (ENOMEM); 928 rctl_rule_acquire(rule); 929 link->rrl_rule = rule; 930 link->rrl_exceeded = 0; 931 932 LIST_INSERT_HEAD(&racct->r_rule_links, link, rrl_next); | 900 901 link = uma_zalloc(rctl_rule_link_zone, M_NOWAIT); 902 if (link == NULL) 903 return (ENOMEM); 904 rctl_rule_acquire(rule); 905 link->rrl_rule = rule; 906 link->rrl_exceeded = 0; 907 908 LIST_INSERT_HEAD(&racct->r_rule_links, link, rrl_next); |
909 |
|
933 return (0); 934} 935 936/* 937 * Remove limits for a rules matching the filter and release 938 * the refcounts for the rules, possibly freeing them. Returns 939 * the number of limit structures removed. 940 */ 941static int 942rctl_racct_remove_rules(struct racct *racct, 943 const struct rctl_rule *filter) 944{ 945 struct rctl_rule_link *link, *linktmp; 946 int removed = 0; 947 948 ASSERT_RACCT_ENABLED(); | 910 return (0); 911} 912 913/* 914 * Remove limits for a rules matching the filter and release 915 * the refcounts for the rules, possibly freeing them. Returns 916 * the number of limit structures removed. 917 */ 918static int 919rctl_racct_remove_rules(struct racct *racct, 920 const struct rctl_rule *filter) 921{ 922 struct rctl_rule_link *link, *linktmp; 923 int removed = 0; 924 925 ASSERT_RACCT_ENABLED(); |
949 RCTL_WLOCK_ASSERT(); | 926 RACCT_LOCK_ASSERT(); |
950 951 LIST_FOREACH_SAFE(link, &racct->r_rule_links, rrl_next, linktmp) { 952 if (!rctl_rule_matches(link->rrl_rule, filter)) 953 continue; 954 955 LIST_REMOVE(link, rrl_next); 956 rctl_rule_release(link->rrl_rule); 957 uma_zfree(rctl_rule_link_zone, link); --- 454 unchanged lines hidden (view full) --- 1412 1413 return (0); 1414} 1415 1416static void 1417rctl_rule_pre_callback(void) 1418{ 1419 | 927 928 LIST_FOREACH_SAFE(link, &racct->r_rule_links, rrl_next, linktmp) { 929 if (!rctl_rule_matches(link->rrl_rule, filter)) 930 continue; 931 932 LIST_REMOVE(link, rrl_next); 933 rctl_rule_release(link->rrl_rule); 934 uma_zfree(rctl_rule_link_zone, link); --- 454 unchanged lines hidden (view full) --- 1389 1390 return (0); 1391} 1392 1393static void 1394rctl_rule_pre_callback(void) 1395{ 1396 |
1420 RCTL_WLOCK(); | 1397 RACCT_LOCK(); |
1421} 1422 1423static void 1424rctl_rule_post_callback(void) 1425{ 1426 | 1398} 1399 1400static void 1401rctl_rule_post_callback(void) 1402{ 1403 |
1427 RCTL_WUNLOCK(); | 1404 RACCT_UNLOCK(); |
1428} 1429 1430static void 1431rctl_rule_remove_callback(struct racct *racct, void *arg2, void *arg3) 1432{ 1433 struct rctl_rule *filter = (struct rctl_rule *)arg2; 1434 int found = 0; 1435 1436 ASSERT_RACCT_ENABLED(); | 1405} 1406 1407static void 1408rctl_rule_remove_callback(struct racct *racct, void *arg2, void *arg3) 1409{ 1410 struct rctl_rule *filter = (struct rctl_rule *)arg2; 1411 int found = 0; 1412 1413 ASSERT_RACCT_ENABLED(); |
1437 RCTL_WLOCK_ASSERT(); | 1414 RACCT_LOCK_ASSERT(); |
1438 1439 found += rctl_racct_remove_rules(racct, filter); 1440 1441 *((int *)arg3) += found; 1442} 1443 1444/* 1445 * Remove all rules that match the filter. --- 4 unchanged lines hidden (view full) --- 1450 struct proc *p; 1451 int found = 0; 1452 1453 ASSERT_RACCT_ENABLED(); 1454 1455 if (filter->rr_subject_type == RCTL_SUBJECT_TYPE_PROCESS && 1456 filter->rr_subject.rs_proc != NULL) { 1457 p = filter->rr_subject.rs_proc; | 1415 1416 found += rctl_racct_remove_rules(racct, filter); 1417 1418 *((int *)arg3) += found; 1419} 1420 1421/* 1422 * Remove all rules that match the filter. --- 4 unchanged lines hidden (view full) --- 1427 struct proc *p; 1428 int found = 0; 1429 1430 ASSERT_RACCT_ENABLED(); 1431 1432 if (filter->rr_subject_type == RCTL_SUBJECT_TYPE_PROCESS && 1433 filter->rr_subject.rs_proc != NULL) { 1434 p = filter->rr_subject.rs_proc; |
1458 RCTL_WLOCK(); | 1435 RACCT_LOCK(); |
1459 found = rctl_racct_remove_rules(p->p_racct, filter); | 1436 found = rctl_racct_remove_rules(p->p_racct, filter); |
1460 RCTL_WUNLOCK(); | 1437 RACCT_UNLOCK(); |
1461 if (found) 1462 return (0); 1463 return (ESRCH); 1464 } 1465 1466 loginclass_racct_foreach(rctl_rule_remove_callback, 1467 rctl_rule_pre_callback, rctl_rule_post_callback, 1468 filter, (void *)&found); 1469 ui_racct_foreach(rctl_rule_remove_callback, 1470 rctl_rule_pre_callback, rctl_rule_post_callback, 1471 filter, (void *)&found); 1472 prison_racct_foreach(rctl_rule_remove_callback, 1473 rctl_rule_pre_callback, rctl_rule_post_callback, 1474 filter, (void *)&found); 1475 1476 sx_assert(&allproc_lock, SA_LOCKED); | 1438 if (found) 1439 return (0); 1440 return (ESRCH); 1441 } 1442 1443 loginclass_racct_foreach(rctl_rule_remove_callback, 1444 rctl_rule_pre_callback, rctl_rule_post_callback, 1445 filter, (void *)&found); 1446 ui_racct_foreach(rctl_rule_remove_callback, 1447 rctl_rule_pre_callback, rctl_rule_post_callback, 1448 filter, (void *)&found); 1449 prison_racct_foreach(rctl_rule_remove_callback, 1450 rctl_rule_pre_callback, rctl_rule_post_callback, 1451 filter, (void *)&found); 1452 1453 sx_assert(&allproc_lock, SA_LOCKED); |
1477 RCTL_WLOCK(); | 1454 RACCT_LOCK(); |
1478 FOREACH_PROC_IN_SYSTEM(p) { 1479 found += rctl_racct_remove_rules(p->p_racct, filter); 1480 } | 1455 FOREACH_PROC_IN_SYSTEM(p) { 1456 found += rctl_racct_remove_rules(p->p_racct, filter); 1457 } |
1481 RCTL_WUNLOCK(); | 1458 RACCT_UNLOCK(); |
1482 1483 if (found) 1484 return (0); 1485 return (ESRCH); 1486} 1487 1488/* 1489 * Appends a rule to the sbuf. --- 115 unchanged lines hidden (view full) --- 1605 int i; 1606 1607 ASSERT_RACCT_ENABLED(); 1608 1609 sb = sbuf_new_auto(); 1610 for (i = 0; i <= RACCT_MAX; i++) { 1611 if (sloppy == 0 && RACCT_IS_SLOPPY(i)) 1612 continue; | 1459 1460 if (found) 1461 return (0); 1462 return (ESRCH); 1463} 1464 1465/* 1466 * Appends a rule to the sbuf. --- 115 unchanged lines hidden (view full) --- 1582 int i; 1583 1584 ASSERT_RACCT_ENABLED(); 1585 1586 sb = sbuf_new_auto(); 1587 for (i = 0; i <= RACCT_MAX; i++) { 1588 if (sloppy == 0 && RACCT_IS_SLOPPY(i)) 1589 continue; |
1590 RACCT_LOCK(); |
|
1613 amount = racct->r_resources[i]; | 1591 amount = racct->r_resources[i]; |
1592 RACCT_UNLOCK(); |
|
1614 if (RACCT_IS_IN_MILLIONS(i)) 1615 amount /= 1000000; 1616 sbuf_printf(sb, "%s=%jd,", rctl_resource_name(i), amount); 1617 } 1618 sbuf_setpos(sb, sbuf_len(sb) - 1); 1619 return (sb); 1620} 1621 --- 78 unchanged lines hidden (view full) --- 1700static void 1701rctl_get_rules_callback(struct racct *racct, void *arg2, void *arg3) 1702{ 1703 struct rctl_rule *filter = (struct rctl_rule *)arg2; 1704 struct rctl_rule_link *link; 1705 struct sbuf *sb = (struct sbuf *)arg3; 1706 1707 ASSERT_RACCT_ENABLED(); | 1593 if (RACCT_IS_IN_MILLIONS(i)) 1594 amount /= 1000000; 1595 sbuf_printf(sb, "%s=%jd,", rctl_resource_name(i), amount); 1596 } 1597 sbuf_setpos(sb, sbuf_len(sb) - 1); 1598 return (sb); 1599} 1600 --- 78 unchanged lines hidden (view full) --- 1679static void 1680rctl_get_rules_callback(struct racct *racct, void *arg2, void *arg3) 1681{ 1682 struct rctl_rule *filter = (struct rctl_rule *)arg2; 1683 struct rctl_rule_link *link; 1684 struct sbuf *sb = (struct sbuf *)arg3; 1685 1686 ASSERT_RACCT_ENABLED(); |
1708 RCTL_LOCK_ASSERT(); | 1687 RACCT_LOCK_ASSERT(); |
1709 1710 LIST_FOREACH(link, &racct->r_rule_links, rrl_next) { 1711 if (!rctl_rule_matches(link->rrl_rule, filter)) 1712 continue; 1713 rctl_rule_to_sbuf(sb, link->rrl_rule); 1714 sbuf_printf(sb, ","); 1715 } 1716} --- 34 unchanged lines hidden (view full) --- 1751 return (E2BIG); 1752 } 1753 1754 buf = malloc(bufsize, M_RCTL, M_WAITOK); 1755 sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN); 1756 KASSERT(sb != NULL, ("sbuf_new failed")); 1757 1758 FOREACH_PROC_IN_SYSTEM(p) { | 1688 1689 LIST_FOREACH(link, &racct->r_rule_links, rrl_next) { 1690 if (!rctl_rule_matches(link->rrl_rule, filter)) 1691 continue; 1692 rctl_rule_to_sbuf(sb, link->rrl_rule); 1693 sbuf_printf(sb, ","); 1694 } 1695} --- 34 unchanged lines hidden (view full) --- 1730 return (E2BIG); 1731 } 1732 1733 buf = malloc(bufsize, M_RCTL, M_WAITOK); 1734 sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN); 1735 KASSERT(sb != NULL, ("sbuf_new failed")); 1736 1737 FOREACH_PROC_IN_SYSTEM(p) { |
1759 RCTL_RLOCK(); | 1738 RACCT_LOCK(); |
1760 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { 1761 /* 1762 * Non-process rules will be added to the buffer later. 1763 * Adding them here would result in duplicated output. 1764 */ 1765 if (link->rrl_rule->rr_subject_type != 1766 RCTL_SUBJECT_TYPE_PROCESS) 1767 continue; 1768 if (!rctl_rule_matches(link->rrl_rule, filter)) 1769 continue; 1770 rctl_rule_to_sbuf(sb, link->rrl_rule); 1771 sbuf_printf(sb, ","); 1772 } | 1739 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { 1740 /* 1741 * Non-process rules will be added to the buffer later. 1742 * Adding them here would result in duplicated output. 1743 */ 1744 if (link->rrl_rule->rr_subject_type != 1745 RCTL_SUBJECT_TYPE_PROCESS) 1746 continue; 1747 if (!rctl_rule_matches(link->rrl_rule, filter)) 1748 continue; 1749 rctl_rule_to_sbuf(sb, link->rrl_rule); 1750 sbuf_printf(sb, ","); 1751 } |
1773 RCTL_RUNLOCK(); | 1752 RACCT_UNLOCK(); |
1774 } 1775 1776 loginclass_racct_foreach(rctl_get_rules_callback, 1777 rctl_rule_pre_callback, rctl_rule_post_callback, 1778 filter, sb); 1779 ui_racct_foreach(rctl_get_rules_callback, 1780 rctl_rule_pre_callback, rctl_rule_post_callback, 1781 filter, sb); --- 70 unchanged lines hidden (view full) --- 1852 sx_sunlock(&allproc_lock); 1853 return (E2BIG); 1854 } 1855 1856 buf = malloc(bufsize, M_RCTL, M_WAITOK); 1857 sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN); 1858 KASSERT(sb != NULL, ("sbuf_new failed")); 1859 | 1753 } 1754 1755 loginclass_racct_foreach(rctl_get_rules_callback, 1756 rctl_rule_pre_callback, rctl_rule_post_callback, 1757 filter, sb); 1758 ui_racct_foreach(rctl_get_rules_callback, 1759 rctl_rule_pre_callback, rctl_rule_post_callback, 1760 filter, sb); --- 70 unchanged lines hidden (view full) --- 1831 sx_sunlock(&allproc_lock); 1832 return (E2BIG); 1833 } 1834 1835 buf = malloc(bufsize, M_RCTL, M_WAITOK); 1836 sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN); 1837 KASSERT(sb != NULL, ("sbuf_new failed")); 1838 |
1860 RCTL_RLOCK(); | 1839 RACCT_LOCK(); |
1861 LIST_FOREACH(link, &filter->rr_subject.rs_proc->p_racct->r_rule_links, 1862 rrl_next) { 1863 rctl_rule_to_sbuf(sb, link->rrl_rule); 1864 sbuf_printf(sb, ","); 1865 } | 1840 LIST_FOREACH(link, &filter->rr_subject.rs_proc->p_racct->r_rule_links, 1841 rrl_next) { 1842 rctl_rule_to_sbuf(sb, link->rrl_rule); 1843 sbuf_printf(sb, ","); 1844 } |
1866 RCTL_RUNLOCK(); | 1845 RACCT_UNLOCK(); |
1867 if (sbuf_error(sb) == ENOMEM) { 1868 error = ERANGE; 1869 sbuf_delete(sb); 1870 goto out; 1871 } 1872 1873 /* 1874 * Remove trailing ",". --- 109 unchanged lines hidden (view full) --- 1984 LIST_INIT(&newrules); 1985 1986again: 1987 /* 1988 * First, count the rules that apply to the process with new 1989 * credentials. 1990 */ 1991 rulecnt = 0; | 1846 if (sbuf_error(sb) == ENOMEM) { 1847 error = ERANGE; 1848 sbuf_delete(sb); 1849 goto out; 1850 } 1851 1852 /* 1853 * Remove trailing ",". --- 109 unchanged lines hidden (view full) --- 1963 LIST_INIT(&newrules); 1964 1965again: 1966 /* 1967 * First, count the rules that apply to the process with new 1968 * credentials. 1969 */ 1970 rulecnt = 0; |
1992 RCTL_RLOCK(); | 1971 RACCT_LOCK(); |
1993 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { 1994 if (link->rrl_rule->rr_subject_type == 1995 RCTL_SUBJECT_TYPE_PROCESS) 1996 rulecnt++; 1997 } 1998 LIST_FOREACH(link, &newuip->ui_racct->r_rule_links, rrl_next) 1999 rulecnt++; 2000 LIST_FOREACH(link, &newlc->lc_racct->r_rule_links, rrl_next) 2001 rulecnt++; 2002 LIST_FOREACH(link, &newprr->prr_racct->r_rule_links, rrl_next) 2003 rulecnt++; | 1972 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { 1973 if (link->rrl_rule->rr_subject_type == 1974 RCTL_SUBJECT_TYPE_PROCESS) 1975 rulecnt++; 1976 } 1977 LIST_FOREACH(link, &newuip->ui_racct->r_rule_links, rrl_next) 1978 rulecnt++; 1979 LIST_FOREACH(link, &newlc->lc_racct->r_rule_links, rrl_next) 1980 rulecnt++; 1981 LIST_FOREACH(link, &newprr->prr_racct->r_rule_links, rrl_next) 1982 rulecnt++; |
2004 RCTL_RUNLOCK(); | 1983 RACCT_UNLOCK(); |
2005 2006 /* 2007 * Create temporary list. We've dropped the rctl_lock in order 2008 * to use M_WAITOK. 2009 */ 2010 for (i = 0; i < rulecnt; i++) { 2011 newlink = uma_zalloc(rctl_rule_link_zone, M_WAITOK); 2012 newlink->rrl_rule = NULL; 2013 newlink->rrl_exceeded = 0; 2014 LIST_INSERT_HEAD(&newrules, newlink, rrl_next); 2015 } 2016 2017 newlink = LIST_FIRST(&newrules); 2018 2019 /* 2020 * Assign rules to the newly allocated list entries. 2021 */ | 1984 1985 /* 1986 * Create temporary list. We've dropped the rctl_lock in order 1987 * to use M_WAITOK. 1988 */ 1989 for (i = 0; i < rulecnt; i++) { 1990 newlink = uma_zalloc(rctl_rule_link_zone, M_WAITOK); 1991 newlink->rrl_rule = NULL; 1992 newlink->rrl_exceeded = 0; 1993 LIST_INSERT_HEAD(&newrules, newlink, rrl_next); 1994 } 1995 1996 newlink = LIST_FIRST(&newrules); 1997 1998 /* 1999 * Assign rules to the newly allocated list entries. 2000 */ |
2022 RCTL_WLOCK(); | 2001 RACCT_LOCK(); |
2023 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { 2024 if (link->rrl_rule->rr_subject_type == 2025 RCTL_SUBJECT_TYPE_PROCESS) { 2026 if (newlink == NULL) 2027 goto goaround; 2028 rctl_rule_acquire(link->rrl_rule); 2029 newlink->rrl_rule = link->rrl_rule; 2030 newlink->rrl_exceeded = link->rrl_exceeded; --- 51 unchanged lines hidden (view full) --- 2082 */ 2083 while (!LIST_EMPTY(&newrules)) { 2084 newlink = LIST_FIRST(&newrules); 2085 LIST_REMOVE(newlink, rrl_next); 2086 LIST_INSERT_HEAD(&p->p_racct->r_rule_links, 2087 newlink, rrl_next); 2088 } 2089 | 2002 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { 2003 if (link->rrl_rule->rr_subject_type == 2004 RCTL_SUBJECT_TYPE_PROCESS) { 2005 if (newlink == NULL) 2006 goto goaround; 2007 rctl_rule_acquire(link->rrl_rule); 2008 newlink->rrl_rule = link->rrl_rule; 2009 newlink->rrl_exceeded = link->rrl_exceeded; --- 51 unchanged lines hidden (view full) --- 2061 */ 2062 while (!LIST_EMPTY(&newrules)) { 2063 newlink = LIST_FIRST(&newrules); 2064 LIST_REMOVE(newlink, rrl_next); 2065 LIST_INSERT_HEAD(&p->p_racct->r_rule_links, 2066 newlink, rrl_next); 2067 } 2068 |
2090 RCTL_WUNLOCK(); | 2069 RACCT_UNLOCK(); |
2091 2092 return; 2093 } 2094 2095goaround: | 2070 2071 return; 2072 } 2073 2074goaround: |
2096 RCTL_WUNLOCK(); | 2075 RACCT_UNLOCK(); |
2097 2098 /* 2099 * Rule list changed while we were not holding the rctl_lock. 2100 * Free the new list and try again. 2101 */ 2102 while (!LIST_EMPTY(&newrules)) { 2103 newlink = LIST_FIRST(&newrules); 2104 LIST_REMOVE(newlink, rrl_next); --- 10 unchanged lines hidden (view full) --- 2115 */ 2116int 2117rctl_proc_fork(struct proc *parent, struct proc *child) 2118{ 2119 struct rctl_rule *rule; 2120 struct rctl_rule_link *link; 2121 int error; 2122 | 2076 2077 /* 2078 * Rule list changed while we were not holding the rctl_lock. 2079 * Free the new list and try again. 2080 */ 2081 while (!LIST_EMPTY(&newrules)) { 2082 newlink = LIST_FIRST(&newrules); 2083 LIST_REMOVE(newlink, rrl_next); --- 10 unchanged lines hidden (view full) --- 2094 */ 2095int 2096rctl_proc_fork(struct proc *parent, struct proc *child) 2097{ 2098 struct rctl_rule *rule; 2099 struct rctl_rule_link *link; 2100 int error; 2101 |
2123 LIST_INIT(&child->p_racct->r_rule_links); 2124 | |
2125 ASSERT_RACCT_ENABLED(); | 2102 ASSERT_RACCT_ENABLED(); |
2103 RACCT_LOCK_ASSERT(); |
|
2126 KASSERT(parent->p_racct != NULL, ("process without racct; p = %p", parent)); 2127 | 2104 KASSERT(parent->p_racct != NULL, ("process without racct; p = %p", parent)); 2105 |
2128 RCTL_WLOCK(); | 2106 LIST_INIT(&child->p_racct->r_rule_links); |
2129 2130 /* 2131 * Go through limits applicable to the parent and assign them 2132 * to the child. Rules with 'process' subject have to be duplicated 2133 * in order to make their rr_subject point to the new process. 2134 */ 2135 LIST_FOREACH(link, &parent->p_racct->r_rule_links, rrl_next) { 2136 if (link->rrl_rule->rr_subject_type == --- 12 unchanged lines hidden (view full) --- 2149 } else { 2150 error = rctl_racct_add_rule_locked(child->p_racct, 2151 link->rrl_rule); 2152 if (error != 0) 2153 goto fail; 2154 } 2155 } 2156 | 2107 2108 /* 2109 * Go through limits applicable to the parent and assign them 2110 * to the child. Rules with 'process' subject have to be duplicated 2111 * in order to make their rr_subject point to the new process. 2112 */ 2113 LIST_FOREACH(link, &parent->p_racct->r_rule_links, rrl_next) { 2114 if (link->rrl_rule->rr_subject_type == --- 12 unchanged lines hidden (view full) --- 2127 } else { 2128 error = rctl_racct_add_rule_locked(child->p_racct, 2129 link->rrl_rule); 2130 if (error != 0) 2131 goto fail; 2132 } 2133 } 2134 |
2157 RCTL_WUNLOCK(); | |
2158 return (0); 2159 2160fail: 2161 while (!LIST_EMPTY(&child->p_racct->r_rule_links)) { 2162 link = LIST_FIRST(&child->p_racct->r_rule_links); 2163 LIST_REMOVE(link, rrl_next); 2164 rctl_rule_release(link->rrl_rule); 2165 uma_zfree(rctl_rule_link_zone, link); 2166 } | 2135 return (0); 2136 2137fail: 2138 while (!LIST_EMPTY(&child->p_racct->r_rule_links)) { 2139 link = LIST_FIRST(&child->p_racct->r_rule_links); 2140 LIST_REMOVE(link, rrl_next); 2141 rctl_rule_release(link->rrl_rule); 2142 uma_zfree(rctl_rule_link_zone, link); 2143 } |
2167 RCTL_WUNLOCK(); | 2144 |
2168 return (EAGAIN); 2169} 2170 2171/* 2172 * Release rules attached to the racct. 2173 */ 2174void 2175rctl_racct_release(struct racct *racct) 2176{ 2177 struct rctl_rule_link *link; 2178 2179 ASSERT_RACCT_ENABLED(); | 2145 return (EAGAIN); 2146} 2147 2148/* 2149 * Release rules attached to the racct. 2150 */ 2151void 2152rctl_racct_release(struct racct *racct) 2153{ 2154 struct rctl_rule_link *link; 2155 2156 ASSERT_RACCT_ENABLED(); |
2157 RACCT_LOCK_ASSERT(); |
|
2180 | 2158 |
2181 RCTL_WLOCK(); | |
2182 while (!LIST_EMPTY(&racct->r_rule_links)) { 2183 link = LIST_FIRST(&racct->r_rule_links); 2184 LIST_REMOVE(link, rrl_next); 2185 rctl_rule_release(link->rrl_rule); 2186 uma_zfree(rctl_rule_link_zone, link); 2187 } | 2159 while (!LIST_EMPTY(&racct->r_rule_links)) { 2160 link = LIST_FIRST(&racct->r_rule_links); 2161 LIST_REMOVE(link, rrl_next); 2162 rctl_rule_release(link->rrl_rule); 2163 uma_zfree(rctl_rule_link_zone, link); 2164 } |
2188 RCTL_WUNLOCK(); | |
2189} 2190 2191static void 2192rctl_init(void) 2193{ 2194 2195 if (!racct_enable) 2196 return; --- 61 unchanged lines hidden --- | 2165} 2166 2167static void 2168rctl_init(void) 2169{ 2170 2171 if (!racct_enable) 2172 return; --- 61 unchanged lines hidden --- |