Deleted Added
full compact
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 ---