kern_racct.c (260817) | kern_racct.c (284665) |
---|---|
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: stable/10/sys/kern/kern_racct.c 260817 2014-01-17 10:58:59Z avg $ | 29 * $FreeBSD: stable/10/sys/kern/kern_racct.c 284665 2015-06-21 06:28:26Z trasz $ |
30 */ 31 32#include <sys/cdefs.h> | 30 */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: stable/10/sys/kern/kern_racct.c 260817 2014-01-17 10:58:59Z avg $"); | 33__FBSDID("$FreeBSD: stable/10/sys/kern/kern_racct.c 284665 2015-06-21 06:28:26Z trasz $"); |
34 35#include "opt_kdtrace.h" 36#include "opt_sched.h" 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/eventhandler.h> 41#include <sys/jail.h> --- 24 unchanged lines hidden (view full) --- 66#ifdef RACCT 67 68FEATURE(racct, "Resource Accounting"); 69 70/* 71 * Do not block processes that have their %cpu usage <= pcpu_threshold. 72 */ 73static int pcpu_threshold = 1; | 34 35#include "opt_kdtrace.h" 36#include "opt_sched.h" 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/eventhandler.h> 41#include <sys/jail.h> --- 24 unchanged lines hidden (view full) --- 66#ifdef RACCT 67 68FEATURE(racct, "Resource Accounting"); 69 70/* 71 * Do not block processes that have their %cpu usage <= pcpu_threshold. 72 */ 73static int pcpu_threshold = 1; |
74#ifdef RACCT_DEFAULT_TO_DISABLED 75int racct_enable = 0; 76#else 77int racct_enable = 1; 78#endif |
|
74 75SYSCTL_NODE(_kern, OID_AUTO, racct, CTLFLAG_RW, 0, "Resource Accounting"); | 79 80SYSCTL_NODE(_kern, OID_AUTO, racct, CTLFLAG_RW, 0, "Resource Accounting"); |
81SYSCTL_UINT(_kern_racct, OID_AUTO, enable, CTLFLAG_RDTUN, &racct_enable, 82 0, "Enable RACCT/RCTL"); |
|
76SYSCTL_UINT(_kern_racct, OID_AUTO, pcpu_threshold, CTLFLAG_RW, &pcpu_threshold, 77 0, "Processes with higher %cpu usage than this value can be throttled."); 78 79/* 80 * How many seconds it takes to use the scheduler %cpu calculations. When a 81 * process starts, we compute its %cpu usage by dividing its runtime by the 82 * process wall clock time. After RACCT_PCPU_SECS pass, we use the value 83 * provided by the scheduler. --- 225 unchanged lines hidden (view full) --- 309#endif 310#ifdef SMP 311 struct pcpu *pc; 312 int found; 313#endif 314 fixpt_t p_pctcpu; 315 struct thread *td; 316 | 83SYSCTL_UINT(_kern_racct, OID_AUTO, pcpu_threshold, CTLFLAG_RW, &pcpu_threshold, 84 0, "Processes with higher %cpu usage than this value can be throttled."); 85 86/* 87 * How many seconds it takes to use the scheduler %cpu calculations. When a 88 * process starts, we compute its %cpu usage by dividing its runtime by the 89 * process wall clock time. After RACCT_PCPU_SECS pass, we use the value 90 * provided by the scheduler. --- 225 unchanged lines hidden (view full) --- 316#endif 317#ifdef SMP 318 struct pcpu *pc; 319 int found; 320#endif 321 fixpt_t p_pctcpu; 322 struct thread *td; 323 |
324 ASSERT_RACCT_ENABLED(); 325 |
|
317 /* 318 * If the process is swapped out, we count its %cpu usage as zero. 319 * This behaviour is consistent with the userland ps(1) tool. 320 */ 321 if ((p->p_flag & P_INMEM) == 0) 322 return (0); 323 swtime = (ticks - p->p_swtick) / hz; 324 --- 48 unchanged lines hidden (view full) --- 373 return ((100 * (uint64_t)p_pctcpu * 1000000) / FSCALE); 374} 375 376static void 377racct_add_racct(struct racct *dest, const struct racct *src) 378{ 379 int i; 380 | 326 /* 327 * If the process is swapped out, we count its %cpu usage as zero. 328 * This behaviour is consistent with the userland ps(1) tool. 329 */ 330 if ((p->p_flag & P_INMEM) == 0) 331 return (0); 332 swtime = (ticks - p->p_swtick) / hz; 333 --- 48 unchanged lines hidden (view full) --- 382 return ((100 * (uint64_t)p_pctcpu * 1000000) / FSCALE); 383} 384 385static void 386racct_add_racct(struct racct *dest, const struct racct *src) 387{ 388 int i; 389 |
390 ASSERT_RACCT_ENABLED(); |
|
381 mtx_assert(&racct_lock, MA_OWNED); 382 383 /* 384 * Update resource usage in dest. 385 */ 386 for (i = 0; i <= RACCT_MAX; i++) { 387 KASSERT(dest->r_resources[i] >= 0, 388 ("%s: resource %d propagation meltdown: dest < 0", --- 5 unchanged lines hidden (view full) --- 394 } 395} 396 397static void 398racct_sub_racct(struct racct *dest, const struct racct *src) 399{ 400 int i; 401 | 391 mtx_assert(&racct_lock, MA_OWNED); 392 393 /* 394 * Update resource usage in dest. 395 */ 396 for (i = 0; i <= RACCT_MAX; i++) { 397 KASSERT(dest->r_resources[i] >= 0, 398 ("%s: resource %d propagation meltdown: dest < 0", --- 5 unchanged lines hidden (view full) --- 404 } 405} 406 407static void 408racct_sub_racct(struct racct *dest, const struct racct *src) 409{ 410 int i; 411 |
412 ASSERT_RACCT_ENABLED(); |
|
402 mtx_assert(&racct_lock, MA_OWNED); 403 404 /* 405 * Update resource usage in dest. 406 */ 407 for (i = 0; i <= RACCT_MAX; i++) { 408 if (!RACCT_IS_SLOPPY(i) && !RACCT_IS_DECAYING(i)) { 409 KASSERT(dest->r_resources[i] >= 0, --- 17 unchanged lines hidden (view full) --- 427 } 428 } 429} 430 431void 432racct_create(struct racct **racctp) 433{ 434 | 413 mtx_assert(&racct_lock, MA_OWNED); 414 415 /* 416 * Update resource usage in dest. 417 */ 418 for (i = 0; i <= RACCT_MAX; i++) { 419 if (!RACCT_IS_SLOPPY(i) && !RACCT_IS_DECAYING(i)) { 420 KASSERT(dest->r_resources[i] >= 0, --- 17 unchanged lines hidden (view full) --- 438 } 439 } 440} 441 442void 443racct_create(struct racct **racctp) 444{ 445 |
446 if (!racct_enable) 447 return; 448 |
|
435 SDT_PROBE(racct, kernel, racct, create, racctp, 0, 0, 0, 0); 436 437 KASSERT(*racctp == NULL, ("racct already allocated")); 438 439 *racctp = uma_zalloc(racct_zone, M_WAITOK | M_ZERO); 440} 441 442static void 443racct_destroy_locked(struct racct **racctp) 444{ 445 int i; 446 struct racct *racct; 447 | 449 SDT_PROBE(racct, kernel, racct, create, racctp, 0, 0, 0, 0); 450 451 KASSERT(*racctp == NULL, ("racct already allocated")); 452 453 *racctp = uma_zalloc(racct_zone, M_WAITOK | M_ZERO); 454} 455 456static void 457racct_destroy_locked(struct racct **racctp) 458{ 459 int i; 460 struct racct *racct; 461 |
462 ASSERT_RACCT_ENABLED(); 463 |
|
448 SDT_PROBE(racct, kernel, racct, destroy, racctp, 0, 0, 0, 0); 449 450 mtx_assert(&racct_lock, MA_OWNED); 451 KASSERT(racctp != NULL, ("NULL racctp")); 452 KASSERT(*racctp != NULL, ("NULL racct")); 453 454 racct = *racctp; 455 --- 10 unchanged lines hidden (view full) --- 466 uma_zfree(racct_zone, racct); 467 *racctp = NULL; 468} 469 470void 471racct_destroy(struct racct **racct) 472{ 473 | 464 SDT_PROBE(racct, kernel, racct, destroy, racctp, 0, 0, 0, 0); 465 466 mtx_assert(&racct_lock, MA_OWNED); 467 KASSERT(racctp != NULL, ("NULL racctp")); 468 KASSERT(*racctp != NULL, ("NULL racct")); 469 470 racct = *racctp; 471 --- 10 unchanged lines hidden (view full) --- 482 uma_zfree(racct_zone, racct); 483 *racctp = NULL; 484} 485 486void 487racct_destroy(struct racct **racct) 488{ 489 |
490 if (!racct_enable) 491 return; 492 |
|
474 mtx_lock(&racct_lock); 475 racct_destroy_locked(racct); 476 mtx_unlock(&racct_lock); 477} 478 479/* 480 * Increase consumption of 'resource' by 'amount' for 'racct' 481 * and all its parents. Differently from other cases, 'amount' here 482 * may be less than zero. 483 */ 484static void 485racct_alloc_resource(struct racct *racct, int resource, 486 uint64_t amount) 487{ 488 | 493 mtx_lock(&racct_lock); 494 racct_destroy_locked(racct); 495 mtx_unlock(&racct_lock); 496} 497 498/* 499 * Increase consumption of 'resource' by 'amount' for 'racct' 500 * and all its parents. Differently from other cases, 'amount' here 501 * may be less than zero. 502 */ 503static void 504racct_alloc_resource(struct racct *racct, int resource, 505 uint64_t amount) 506{ 507 |
508 ASSERT_RACCT_ENABLED(); |
|
489 mtx_assert(&racct_lock, MA_OWNED); 490 KASSERT(racct != NULL, ("NULL racct")); 491 492 racct->r_resources[resource] += amount; 493 if (racct->r_resources[resource] < 0) { 494 KASSERT(RACCT_IS_SLOPPY(resource) || RACCT_IS_DECAYING(resource), 495 ("%s: resource %d usage < 0", __func__, resource)); 496 racct->r_resources[resource] = 0; --- 15 unchanged lines hidden (view full) --- 512 513static int 514racct_add_locked(struct proc *p, int resource, uint64_t amount) 515{ 516#ifdef RCTL 517 int error; 518#endif 519 | 509 mtx_assert(&racct_lock, MA_OWNED); 510 KASSERT(racct != NULL, ("NULL racct")); 511 512 racct->r_resources[resource] += amount; 513 if (racct->r_resources[resource] < 0) { 514 KASSERT(RACCT_IS_SLOPPY(resource) || RACCT_IS_DECAYING(resource), 515 ("%s: resource %d usage < 0", __func__, resource)); 516 racct->r_resources[resource] = 0; --- 15 unchanged lines hidden (view full) --- 532 533static int 534racct_add_locked(struct proc *p, int resource, uint64_t amount) 535{ 536#ifdef RCTL 537 int error; 538#endif 539 |
540 ASSERT_RACCT_ENABLED(); 541 |
|
520 SDT_PROBE(racct, kernel, rusage, add, p, resource, amount, 0, 0); 521 522 /* 523 * We need proc lock to dereference p->p_ucred. 524 */ 525 PROC_LOCK_ASSERT(p, MA_OWNED); 526 527#ifdef RCTL --- 14 unchanged lines hidden (view full) --- 542 * Increase allocation of 'resource' by 'amount' for process 'p'. 543 * Return 0 if it's below limits, or errno, if it's not. 544 */ 545int 546racct_add(struct proc *p, int resource, uint64_t amount) 547{ 548 int error; 549 | 542 SDT_PROBE(racct, kernel, rusage, add, p, resource, amount, 0, 0); 543 544 /* 545 * We need proc lock to dereference p->p_ucred. 546 */ 547 PROC_LOCK_ASSERT(p, MA_OWNED); 548 549#ifdef RCTL --- 14 unchanged lines hidden (view full) --- 564 * Increase allocation of 'resource' by 'amount' for process 'p'. 565 * Return 0 if it's below limits, or errno, if it's not. 566 */ 567int 568racct_add(struct proc *p, int resource, uint64_t amount) 569{ 570 int error; 571 |
572 if (!racct_enable) 573 return (0); 574 |
|
550 mtx_lock(&racct_lock); 551 error = racct_add_locked(p, resource, amount); 552 mtx_unlock(&racct_lock); 553 return (error); 554} 555 556static void 557racct_add_cred_locked(struct ucred *cred, int resource, uint64_t amount) 558{ 559 struct prison *pr; 560 | 575 mtx_lock(&racct_lock); 576 error = racct_add_locked(p, resource, amount); 577 mtx_unlock(&racct_lock); 578 return (error); 579} 580 581static void 582racct_add_cred_locked(struct ucred *cred, int resource, uint64_t amount) 583{ 584 struct prison *pr; 585 |
586 ASSERT_RACCT_ENABLED(); 587 |
|
561 SDT_PROBE(racct, kernel, rusage, add__cred, cred, resource, amount, 562 0, 0); 563 564 racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, amount); 565 for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) 566 racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource, 567 amount); 568 racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, amount); --- 4 unchanged lines hidden (view full) --- 573 * Doesn't check for limits and never fails. 574 * 575 * XXX: Shouldn't this ever return an error? 576 */ 577void 578racct_add_cred(struct ucred *cred, int resource, uint64_t amount) 579{ 580 | 588 SDT_PROBE(racct, kernel, rusage, add__cred, cred, resource, amount, 589 0, 0); 590 591 racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, amount); 592 for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) 593 racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource, 594 amount); 595 racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, amount); --- 4 unchanged lines hidden (view full) --- 600 * Doesn't check for limits and never fails. 601 * 602 * XXX: Shouldn't this ever return an error? 603 */ 604void 605racct_add_cred(struct ucred *cred, int resource, uint64_t amount) 606{ 607 |
608 if (!racct_enable) 609 return; 610 |
|
581 mtx_lock(&racct_lock); 582 racct_add_cred_locked(cred, resource, amount); 583 mtx_unlock(&racct_lock); 584} 585 586/* 587 * Increase allocation of 'resource' by 'amount' for process 'p'. 588 * Doesn't check for limits and never fails. 589 */ 590void 591racct_add_force(struct proc *p, int resource, uint64_t amount) 592{ 593 | 611 mtx_lock(&racct_lock); 612 racct_add_cred_locked(cred, resource, amount); 613 mtx_unlock(&racct_lock); 614} 615 616/* 617 * Increase allocation of 'resource' by 'amount' for process 'p'. 618 * Doesn't check for limits and never fails. 619 */ 620void 621racct_add_force(struct proc *p, int resource, uint64_t amount) 622{ 623 |
624 if (!racct_enable) 625 return; 626 |
|
594 SDT_PROBE(racct, kernel, rusage, add__force, p, resource, amount, 0, 0); 595 596 /* 597 * We need proc lock to dereference p->p_ucred. 598 */ 599 PROC_LOCK_ASSERT(p, MA_OWNED); 600 601 mtx_lock(&racct_lock); --- 6 unchanged lines hidden (view full) --- 608racct_set_locked(struct proc *p, int resource, uint64_t amount) 609{ 610 int64_t old_amount, decayed_amount; 611 int64_t diff_proc, diff_cred; 612#ifdef RCTL 613 int error; 614#endif 615 | 627 SDT_PROBE(racct, kernel, rusage, add__force, p, resource, amount, 0, 0); 628 629 /* 630 * We need proc lock to dereference p->p_ucred. 631 */ 632 PROC_LOCK_ASSERT(p, MA_OWNED); 633 634 mtx_lock(&racct_lock); --- 6 unchanged lines hidden (view full) --- 641racct_set_locked(struct proc *p, int resource, uint64_t amount) 642{ 643 int64_t old_amount, decayed_amount; 644 int64_t diff_proc, diff_cred; 645#ifdef RCTL 646 int error; 647#endif 648 |
649 ASSERT_RACCT_ENABLED(); 650 |
|
616 SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0); 617 618 /* 619 * We need proc lock to dereference p->p_ucred. 620 */ 621 PROC_LOCK_ASSERT(p, MA_OWNED); 622 623 old_amount = p->p_racct->r_resources[resource]; --- 43 unchanged lines hidden (view full) --- 667 * Note that decreasing the allocation always returns 0, 668 * even if it's above the limit. 669 */ 670int 671racct_set(struct proc *p, int resource, uint64_t amount) 672{ 673 int error; 674 | 651 SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0); 652 653 /* 654 * We need proc lock to dereference p->p_ucred. 655 */ 656 PROC_LOCK_ASSERT(p, MA_OWNED); 657 658 old_amount = p->p_racct->r_resources[resource]; --- 43 unchanged lines hidden (view full) --- 702 * Note that decreasing the allocation always returns 0, 703 * even if it's above the limit. 704 */ 705int 706racct_set(struct proc *p, int resource, uint64_t amount) 707{ 708 int error; 709 |
710 if (!racct_enable) 711 return (0); 712 |
|
675 mtx_lock(&racct_lock); 676 error = racct_set_locked(p, resource, amount); 677 mtx_unlock(&racct_lock); 678 return (error); 679} 680 681static void 682racct_set_force_locked(struct proc *p, int resource, uint64_t amount) 683{ 684 int64_t old_amount, decayed_amount; 685 int64_t diff_proc, diff_cred; 686 | 713 mtx_lock(&racct_lock); 714 error = racct_set_locked(p, resource, amount); 715 mtx_unlock(&racct_lock); 716 return (error); 717} 718 719static void 720racct_set_force_locked(struct proc *p, int resource, uint64_t amount) 721{ 722 int64_t old_amount, decayed_amount; 723 int64_t diff_proc, diff_cred; 724 |
725 ASSERT_RACCT_ENABLED(); 726 |
|
687 SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0); 688 689 /* 690 * We need proc lock to dereference p->p_ucred. 691 */ 692 PROC_LOCK_ASSERT(p, MA_OWNED); 693 694 old_amount = p->p_racct->r_resources[resource]; --- 18 unchanged lines hidden (view full) --- 713 racct_add_cred_locked(p->p_ucred, resource, diff_cred); 714 else if (diff_cred < 0) 715 racct_sub_cred_locked(p->p_ucred, resource, -diff_cred); 716} 717 718void 719racct_set_force(struct proc *p, int resource, uint64_t amount) 720{ | 727 SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0); 728 729 /* 730 * We need proc lock to dereference p->p_ucred. 731 */ 732 PROC_LOCK_ASSERT(p, MA_OWNED); 733 734 old_amount = p->p_racct->r_resources[resource]; --- 18 unchanged lines hidden (view full) --- 753 racct_add_cred_locked(p->p_ucred, resource, diff_cred); 754 else if (diff_cred < 0) 755 racct_sub_cred_locked(p->p_ucred, resource, -diff_cred); 756} 757 758void 759racct_set_force(struct proc *p, int resource, uint64_t amount) 760{ |
761 762 if (!racct_enable) 763 return; 764 |
|
721 mtx_lock(&racct_lock); 722 racct_set_force_locked(p, resource, amount); 723 mtx_unlock(&racct_lock); 724} 725 726/* 727 * Returns amount of 'resource' the process 'p' can keep allocated. 728 * Allocating more than that would be denied, unless the resource 729 * is marked undeniable. Amount of already allocated resource does 730 * not matter. 731 */ 732uint64_t 733racct_get_limit(struct proc *p, int resource) 734{ 735 | 765 mtx_lock(&racct_lock); 766 racct_set_force_locked(p, resource, amount); 767 mtx_unlock(&racct_lock); 768} 769 770/* 771 * Returns amount of 'resource' the process 'p' can keep allocated. 772 * Allocating more than that would be denied, unless the resource 773 * is marked undeniable. Amount of already allocated resource does 774 * not matter. 775 */ 776uint64_t 777racct_get_limit(struct proc *p, int resource) 778{ 779 |
780 if (!racct_enable) 781 return (UINT64_MAX); 782 |
|
736#ifdef RCTL 737 return (rctl_get_limit(p, resource)); 738#else 739 return (UINT64_MAX); 740#endif 741} 742 743/* 744 * Returns amount of 'resource' the process 'p' can keep allocated. 745 * Allocating more than that would be denied, unless the resource 746 * is marked undeniable. Amount of already allocated resource does 747 * matter. 748 */ 749uint64_t 750racct_get_available(struct proc *p, int resource) 751{ 752 | 783#ifdef RCTL 784 return (rctl_get_limit(p, resource)); 785#else 786 return (UINT64_MAX); 787#endif 788} 789 790/* 791 * Returns amount of 'resource' the process 'p' can keep allocated. 792 * Allocating more than that would be denied, unless the resource 793 * is marked undeniable. Amount of already allocated resource does 794 * matter. 795 */ 796uint64_t 797racct_get_available(struct proc *p, int resource) 798{ 799 |
800 if (!racct_enable) 801 return (UINT64_MAX); 802 |
|
753#ifdef RCTL 754 return (rctl_get_available(p, resource)); 755#else 756 return (UINT64_MAX); 757#endif 758} 759 760/* 761 * Returns amount of the %cpu resource that process 'p' can add to its %cpu 762 * utilization. Adding more than that would lead to the process being 763 * throttled. 764 */ 765static int64_t 766racct_pcpu_available(struct proc *p) 767{ 768 | 803#ifdef RCTL 804 return (rctl_get_available(p, resource)); 805#else 806 return (UINT64_MAX); 807#endif 808} 809 810/* 811 * Returns amount of the %cpu resource that process 'p' can add to its %cpu 812 * utilization. Adding more than that would lead to the process being 813 * throttled. 814 */ 815static int64_t 816racct_pcpu_available(struct proc *p) 817{ 818 |
819 ASSERT_RACCT_ENABLED(); 820 |
|
769#ifdef RCTL 770 return (rctl_pcpu_available(p)); 771#else 772 return (INT64_MAX); 773#endif 774} 775 776/* 777 * Decrease allocation of 'resource' by 'amount' for process 'p'. 778 */ 779void 780racct_sub(struct proc *p, int resource, uint64_t amount) 781{ 782 | 821#ifdef RCTL 822 return (rctl_pcpu_available(p)); 823#else 824 return (INT64_MAX); 825#endif 826} 827 828/* 829 * Decrease allocation of 'resource' by 'amount' for process 'p'. 830 */ 831void 832racct_sub(struct proc *p, int resource, uint64_t amount) 833{ 834 |
835 if (!racct_enable) 836 return; 837 |
|
783 SDT_PROBE(racct, kernel, rusage, sub, p, resource, amount, 0, 0); 784 785 /* 786 * We need proc lock to dereference p->p_ucred. 787 */ 788 PROC_LOCK_ASSERT(p, MA_OWNED); 789 KASSERT(RACCT_CAN_DROP(resource), 790 ("%s: called for non-droppable resource %d", __func__, resource)); --- 9 unchanged lines hidden (view full) --- 800 mtx_unlock(&racct_lock); 801} 802 803static void 804racct_sub_cred_locked(struct ucred *cred, int resource, uint64_t amount) 805{ 806 struct prison *pr; 807 | 838 SDT_PROBE(racct, kernel, rusage, sub, p, resource, amount, 0, 0); 839 840 /* 841 * We need proc lock to dereference p->p_ucred. 842 */ 843 PROC_LOCK_ASSERT(p, MA_OWNED); 844 KASSERT(RACCT_CAN_DROP(resource), 845 ("%s: called for non-droppable resource %d", __func__, resource)); --- 9 unchanged lines hidden (view full) --- 855 mtx_unlock(&racct_lock); 856} 857 858static void 859racct_sub_cred_locked(struct ucred *cred, int resource, uint64_t amount) 860{ 861 struct prison *pr; 862 |
863 ASSERT_RACCT_ENABLED(); 864 |
|
808 SDT_PROBE(racct, kernel, rusage, sub__cred, cred, resource, amount, 809 0, 0); 810 811#ifdef notyet 812 KASSERT(RACCT_CAN_DROP(resource), 813 ("%s: called for resource %d which can not drop", __func__, 814 resource)); 815#endif --- 7 unchanged lines hidden (view full) --- 823 824/* 825 * Decrease allocation of 'resource' by 'amount' for credential 'cred'. 826 */ 827void 828racct_sub_cred(struct ucred *cred, int resource, uint64_t amount) 829{ 830 | 865 SDT_PROBE(racct, kernel, rusage, sub__cred, cred, resource, amount, 866 0, 0); 867 868#ifdef notyet 869 KASSERT(RACCT_CAN_DROP(resource), 870 ("%s: called for resource %d which can not drop", __func__, 871 resource)); 872#endif --- 7 unchanged lines hidden (view full) --- 880 881/* 882 * Decrease allocation of 'resource' by 'amount' for credential 'cred'. 883 */ 884void 885racct_sub_cred(struct ucred *cred, int resource, uint64_t amount) 886{ 887 |
888 if (!racct_enable) 889 return; 890 |
|
831 mtx_lock(&racct_lock); 832 racct_sub_cred_locked(cred, resource, amount); 833 mtx_unlock(&racct_lock); 834} 835 836/* 837 * Inherit resource usage information from the parent process. 838 */ 839int 840racct_proc_fork(struct proc *parent, struct proc *child) 841{ 842 int i, error = 0; 843 | 891 mtx_lock(&racct_lock); 892 racct_sub_cred_locked(cred, resource, amount); 893 mtx_unlock(&racct_lock); 894} 895 896/* 897 * Inherit resource usage information from the parent process. 898 */ 899int 900racct_proc_fork(struct proc *parent, struct proc *child) 901{ 902 int i, error = 0; 903 |
904 if (!racct_enable) 905 return (0); 906 |
|
844 /* 845 * Create racct for the child process. 846 */ 847 racct_create(&child->p_racct); 848 849 PROC_LOCK(parent); 850 PROC_LOCK(child); 851 mtx_lock(&racct_lock); --- 40 unchanged lines hidden (view full) --- 892 * Called at the end of fork1(), to handle rules that require the process 893 * to be fully initialized. 894 */ 895void 896racct_proc_fork_done(struct proc *child) 897{ 898 899#ifdef RCTL | 907 /* 908 * Create racct for the child process. 909 */ 910 racct_create(&child->p_racct); 911 912 PROC_LOCK(parent); 913 PROC_LOCK(child); 914 mtx_lock(&racct_lock); --- 40 unchanged lines hidden (view full) --- 955 * Called at the end of fork1(), to handle rules that require the process 956 * to be fully initialized. 957 */ 958void 959racct_proc_fork_done(struct proc *child) 960{ 961 962#ifdef RCTL |
963 if (!racct_enable) 964 return; 965 |
|
900 PROC_LOCK(child); 901 mtx_lock(&racct_lock); 902 rctl_enforce(child, RACCT_NPROC, 0); 903 rctl_enforce(child, RACCT_NTHR, 0); 904 mtx_unlock(&racct_lock); 905 PROC_UNLOCK(child); 906#endif 907} 908 909void 910racct_proc_exit(struct proc *p) 911{ 912 int i; 913 uint64_t runtime; 914 struct timeval wallclock; 915 uint64_t pct_estimate, pct; 916 | 966 PROC_LOCK(child); 967 mtx_lock(&racct_lock); 968 rctl_enforce(child, RACCT_NPROC, 0); 969 rctl_enforce(child, RACCT_NTHR, 0); 970 mtx_unlock(&racct_lock); 971 PROC_UNLOCK(child); 972#endif 973} 974 975void 976racct_proc_exit(struct proc *p) 977{ 978 int i; 979 uint64_t runtime; 980 struct timeval wallclock; 981 uint64_t pct_estimate, pct; 982 |
983 if (!racct_enable) 984 return; 985 |
|
917 PROC_LOCK(p); 918 /* 919 * We don't need to calculate rux, proc_reap() has already done this. 920 */ 921 runtime = cputick2usec(p->p_rux.rux_runtime); 922#ifdef notyet 923 KASSERT(runtime >= p->p_prev_runtime, ("runtime < p_prev_runtime")); 924#else --- 38 unchanged lines hidden (view full) --- 963void 964racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred, 965 struct ucred *newcred) 966{ 967 struct uidinfo *olduip, *newuip; 968 struct loginclass *oldlc, *newlc; 969 struct prison *oldpr, *newpr, *pr; 970 | 986 PROC_LOCK(p); 987 /* 988 * We don't need to calculate rux, proc_reap() has already done this. 989 */ 990 runtime = cputick2usec(p->p_rux.rux_runtime); 991#ifdef notyet 992 KASSERT(runtime >= p->p_prev_runtime, ("runtime < p_prev_runtime")); 993#else --- 38 unchanged lines hidden (view full) --- 1032void 1033racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred, 1034 struct ucred *newcred) 1035{ 1036 struct uidinfo *olduip, *newuip; 1037 struct loginclass *oldlc, *newlc; 1038 struct prison *oldpr, *newpr, *pr; 1039 |
1040 if (!racct_enable) 1041 return; 1042 |
|
971 PROC_LOCK_ASSERT(p, MA_NOTOWNED); 972 973 newuip = newcred->cr_ruidinfo; 974 olduip = oldcred->cr_ruidinfo; 975 newlc = newcred->cr_loginclass; 976 oldlc = oldcred->cr_loginclass; 977 newpr = newcred->cr_prison; 978 oldpr = oldcred->cr_prison; --- 21 unchanged lines hidden (view full) --- 1000 rctl_proc_ucred_changed(p, newcred); 1001#endif 1002} 1003 1004void 1005racct_move(struct racct *dest, struct racct *src) 1006{ 1007 | 1043 PROC_LOCK_ASSERT(p, MA_NOTOWNED); 1044 1045 newuip = newcred->cr_ruidinfo; 1046 olduip = oldcred->cr_ruidinfo; 1047 newlc = newcred->cr_loginclass; 1048 oldlc = oldcred->cr_loginclass; 1049 newpr = newcred->cr_prison; 1050 oldpr = oldcred->cr_prison; --- 21 unchanged lines hidden (view full) --- 1072 rctl_proc_ucred_changed(p, newcred); 1073#endif 1074} 1075 1076void 1077racct_move(struct racct *dest, struct racct *src) 1078{ 1079 |
1080 ASSERT_RACCT_ENABLED(); 1081 |
|
1008 mtx_lock(&racct_lock); 1009 1010 racct_add_racct(dest, src); 1011 racct_sub_racct(src, src); 1012 1013 mtx_unlock(&racct_lock); 1014} 1015 1016static void 1017racct_proc_throttle(struct proc *p) 1018{ 1019 struct thread *td; 1020#ifdef SMP 1021 int cpuid; 1022#endif 1023 | 1082 mtx_lock(&racct_lock); 1083 1084 racct_add_racct(dest, src); 1085 racct_sub_racct(src, src); 1086 1087 mtx_unlock(&racct_lock); 1088} 1089 1090static void 1091racct_proc_throttle(struct proc *p) 1092{ 1093 struct thread *td; 1094#ifdef SMP 1095 int cpuid; 1096#endif 1097 |
1098 ASSERT_RACCT_ENABLED(); |
|
1024 PROC_LOCK_ASSERT(p, MA_OWNED); 1025 1026 /* 1027 * Do not block kernel processes. Also do not block processes with 1028 * low %cpu utilization to improve interactivity. 1029 */ 1030 if (((p->p_flag & (P_SYSTEM | P_KTHREAD)) != 0) || 1031 (p->p_racct->r_resources[RACCT_PCTCPU] <= pcpu_threshold)) --- 29 unchanged lines hidden (view full) --- 1061 } 1062 thread_unlock(td); 1063 } 1064} 1065 1066static void 1067racct_proc_wakeup(struct proc *p) 1068{ | 1099 PROC_LOCK_ASSERT(p, MA_OWNED); 1100 1101 /* 1102 * Do not block kernel processes. Also do not block processes with 1103 * low %cpu utilization to improve interactivity. 1104 */ 1105 if (((p->p_flag & (P_SYSTEM | P_KTHREAD)) != 0) || 1106 (p->p_racct->r_resources[RACCT_PCTCPU] <= pcpu_threshold)) --- 29 unchanged lines hidden (view full) --- 1136 } 1137 thread_unlock(td); 1138 } 1139} 1140 1141static void 1142racct_proc_wakeup(struct proc *p) 1143{ |
1144 1145 ASSERT_RACCT_ENABLED(); 1146 |
|
1069 PROC_LOCK_ASSERT(p, MA_OWNED); 1070 1071 if (p->p_throttled) { 1072 p->p_throttled = 0; 1073 wakeup(p->p_racct); 1074 } 1075} 1076 1077static void 1078racct_decay_resource(struct racct *racct, void * res, void* dummy) 1079{ 1080 int resource; 1081 int64_t r_old, r_new; 1082 | 1147 PROC_LOCK_ASSERT(p, MA_OWNED); 1148 1149 if (p->p_throttled) { 1150 p->p_throttled = 0; 1151 wakeup(p->p_racct); 1152 } 1153} 1154 1155static void 1156racct_decay_resource(struct racct *racct, void * res, void* dummy) 1157{ 1158 int resource; 1159 int64_t r_old, r_new; 1160 |
1161 ASSERT_RACCT_ENABLED(); 1162 |
|
1083 resource = *(int *)res; 1084 r_old = racct->r_resources[resource]; 1085 1086 /* If there is nothing to decay, just exit. */ 1087 if (r_old <= 0) 1088 return; 1089 1090 mtx_lock(&racct_lock); 1091 r_new = r_old * RACCT_DECAY_FACTOR / FSCALE; 1092 racct->r_resources[resource] = r_new; 1093 mtx_unlock(&racct_lock); 1094} 1095 1096static void 1097racct_decay(int resource) 1098{ | 1163 resource = *(int *)res; 1164 r_old = racct->r_resources[resource]; 1165 1166 /* If there is nothing to decay, just exit. */ 1167 if (r_old <= 0) 1168 return; 1169 1170 mtx_lock(&racct_lock); 1171 r_new = r_old * RACCT_DECAY_FACTOR / FSCALE; 1172 racct->r_resources[resource] = r_new; 1173 mtx_unlock(&racct_lock); 1174} 1175 1176static void 1177racct_decay(int resource) 1178{ |
1179 1180 ASSERT_RACCT_ENABLED(); 1181 |
|
1099 ui_racct_foreach(racct_decay_resource, &resource, NULL); 1100 loginclass_racct_foreach(racct_decay_resource, &resource, NULL); 1101 prison_racct_foreach(racct_decay_resource, &resource, NULL); 1102} 1103 1104static void 1105racctd(void) 1106{ 1107 struct thread *td; 1108 struct proc *p; 1109 struct timeval wallclock; 1110 uint64_t runtime; 1111 uint64_t pct, pct_estimate; 1112 | 1182 ui_racct_foreach(racct_decay_resource, &resource, NULL); 1183 loginclass_racct_foreach(racct_decay_resource, &resource, NULL); 1184 prison_racct_foreach(racct_decay_resource, &resource, NULL); 1185} 1186 1187static void 1188racctd(void) 1189{ 1190 struct thread *td; 1191 struct proc *p; 1192 struct timeval wallclock; 1193 uint64_t runtime; 1194 uint64_t pct, pct_estimate; 1195 |
1196 ASSERT_RACCT_ENABLED(); 1197 |
|
1113 for (;;) { 1114 racct_decay(RACCT_PCTCPU); 1115 1116 sx_slock(&allproc_lock); 1117 1118 LIST_FOREACH(p, &zombproc, p_list) { 1119 PROC_LOCK(p); 1120 racct_set(p, RACCT_PCTCPU, 0); --- 63 unchanged lines hidden (view full) --- 1184 } 1185} 1186 1187static struct kproc_desc racctd_kp = { 1188 "racctd", 1189 racctd, 1190 NULL 1191}; | 1198 for (;;) { 1199 racct_decay(RACCT_PCTCPU); 1200 1201 sx_slock(&allproc_lock); 1202 1203 LIST_FOREACH(p, &zombproc, p_list) { 1204 PROC_LOCK(p); 1205 racct_set(p, RACCT_PCTCPU, 0); --- 63 unchanged lines hidden (view full) --- 1269 } 1270} 1271 1272static struct kproc_desc racctd_kp = { 1273 "racctd", 1274 racctd, 1275 NULL 1276}; |
1192SYSINIT(racctd, SI_SUB_RACCTD, SI_ORDER_FIRST, kproc_start, &racctd_kp); | |
1193 1194static void | 1277 1278static void |
1279racctd_init(void) 1280{ 1281 if (!racct_enable) 1282 return; 1283 1284 kproc_start(&racctd_kp); 1285} 1286SYSINIT(racctd, SI_SUB_RACCTD, SI_ORDER_FIRST, racctd_init, NULL); 1287 1288static void |
|
1195racct_init(void) 1196{ | 1289racct_init(void) 1290{ |
1291 if (!racct_enable) 1292 return; |
|
1197 1198 racct_zone = uma_zcreate("racct", sizeof(struct racct), 1199 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); 1200 /* 1201 * XXX: Move this somewhere. 1202 */ 1203 prison0.pr_prison_racct = prison_racct_find("0"); 1204} --- 87 unchanged lines hidden --- | 1293 1294 racct_zone = uma_zcreate("racct", sizeof(struct racct), 1295 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); 1296 /* 1297 * XXX: Move this somewhere. 1298 */ 1299 prison0.pr_prison_racct = prison_racct_find("0"); 1300} --- 87 unchanged lines hidden --- |