diff options
-rw-r--r-- | sys/amd64/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/conf/options | 1 | ||||
-rw-r--r-- | sys/i386/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/kern/imgact_elf.c | 14 | ||||
-rw-r--r-- | sys/kern/kern_descrip.c | 36 | ||||
-rw-r--r-- | sys/kern/kern_exit.c | 8 | ||||
-rw-r--r-- | sys/kern/kern_jail.c | 22 | ||||
-rw-r--r-- | sys/kern/kern_racct.c | 98 | ||||
-rw-r--r-- | sys/kern/kern_rctl.c | 69 | ||||
-rw-r--r-- | sys/kern/kern_thr.c | 8 | ||||
-rw-r--r-- | sys/kern/sched_4bsd.c | 2 | ||||
-rw-r--r-- | sys/kern/subr_trap.c | 13 | ||||
-rw-r--r-- | sys/kern/sysv_msg.c | 42 | ||||
-rw-r--r-- | sys/kern/sysv_sem.c | 25 | ||||
-rw-r--r-- | sys/kern/sysv_shm.c | 30 | ||||
-rw-r--r-- | sys/pc98/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/powerpc/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/sparc64/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/sys/racct.h | 4 | ||||
-rw-r--r-- | sys/vm/swap_pager.c | 12 | ||||
-rw-r--r-- | sys/vm/vm_map.c | 55 | ||||
-rw-r--r-- | sys/vm/vm_mmap.c | 32 | ||||
-rw-r--r-- | sys/vm/vm_pageout.c | 59 | ||||
-rw-r--r-- | sys/vm/vm_unix.c | 81 | ||||
-rw-r--r-- | usr.bin/rctl/rctl.8 | 12 |
25 files changed, 456 insertions, 182 deletions
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index 5c217e9..4191bd1 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -72,6 +72,9 @@ options KDTRACE_FRAME # Ensure frames are compiled in options KDTRACE_HOOKS # Kernel DTrace hooks options DDB_CTF # Kernel ELF linker loads CTF data options INCLUDE_CONFIG_FILE # Include this file in kernel +options RACCT # Resource accounting framework +options RACCT_DEFAULT_TO_DISABLED # Set kern.racct.enable=0 by default +options RCTL # Resource limits # Debugging support. Always need this: options KDB # Enable kernel debugger support. diff --git a/sys/conf/options b/sys/conf/options index c8597bc..2e44c9a 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -925,6 +925,7 @@ IPOIB_CM opt_ofed.h # Resource Accounting RACCT opt_global.h +RACCT_DEFAULT_TO_DISABLED opt_global.h # Resource Limits RCTL opt_global.h diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index 2b00964..f637bce 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -72,6 +72,9 @@ options MAC # TrustedBSD MAC Framework options KDTRACE_HOOKS # Kernel DTrace hooks options DDB_CTF # Kernel ELF linker loads CTF data options INCLUDE_CONFIG_FILE # Include this file in kernel +options RACCT # Resource accounting framework +options RACCT_DEFAULT_TO_DISABLED # Set kern.racct.enable=0 by default +options RCTL # Resource limits # Debugging support. Always need this: options KDB # Enable kernel debugger support. diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index c8ad50e..e66d679 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -1231,12 +1231,14 @@ __elfN(coredump)(struct thread *td, struct vnode *vp, off_t limit, int flags) coresize = round_page(hdrsize + notesz) + seginfo.size; #ifdef RACCT - PROC_LOCK(td->td_proc); - error = racct_add(td->td_proc, RACCT_CORE, coresize); - PROC_UNLOCK(td->td_proc); - if (error != 0) { - error = EFAULT; - goto done; + if (racct_enable) { + PROC_LOCK(td->td_proc); + error = racct_add(td->td_proc, RACCT_CORE, coresize); + PROC_UNLOCK(td->td_proc); + if (error != 0) { + error = EFAULT; + goto done; + } } #endif if (coresize >= limit) { diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 24a5505..68ce9a2 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -874,13 +874,15 @@ do_dup(struct thread *td, int flags, int old, int new, * the limit on the size of the file descriptor table. */ #ifdef RACCT - PROC_LOCK(p); - error = racct_set(p, RACCT_NOFILE, new + 1); - PROC_UNLOCK(p); - if (error != 0) { - FILEDESC_XUNLOCK(fdp); - fdrop(fp, td); - return (EMFILE); + if (racct_enable) { + PROC_LOCK(p); + error = racct_set(p, RACCT_NOFILE, new + 1); + PROC_UNLOCK(p); + if (error != 0) { + FILEDESC_XUNLOCK(fdp); + fdrop(fp, td); + return (EMFILE); + } } #endif fdgrowtable_exp(fdp, new + 1); @@ -1641,11 +1643,13 @@ fdalloc(struct thread *td, int minfd, int *result) if (fd >= fdp->fd_nfiles) { allocfd = min(fd * 2, maxfd); #ifdef RACCT - PROC_LOCK(p); - error = racct_set(p, RACCT_NOFILE, allocfd); - PROC_UNLOCK(p); - if (error != 0) - return (EMFILE); + if (racct_enable) { + PROC_LOCK(p); + error = racct_set(p, RACCT_NOFILE, allocfd); + PROC_UNLOCK(p); + if (error != 0) + return (EMFILE); + } #endif /* * fd is already equal to first free descriptor >= minfd, so @@ -2008,9 +2012,11 @@ fdescfree(struct thread *td) return; #ifdef RACCT - PROC_LOCK(td->td_proc); - racct_set(td->td_proc, RACCT_NOFILE, 0); - PROC_UNLOCK(td->td_proc); + if (racct_enable) { + PROC_LOCK(td->td_proc); + racct_set(td->td_proc, RACCT_NOFILE, 0); + PROC_UNLOCK(td->td_proc); + } #endif /* Check for special need to clear POSIX style locks */ diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 9c72442..d4ed909 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -921,9 +921,11 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options) * Destroy resource accounting information associated with the process. */ #ifdef RACCT - PROC_LOCK(p); - racct_sub(p, RACCT_NPROC, 1); - PROC_UNLOCK(p); + if (racct_enable) { + PROC_LOCK(p); + racct_sub(p, RACCT_NPROC, 1); + PROC_UNLOCK(p); + } #endif racct_proc_exit(p); diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index e9c71ca..af5feb3 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -1787,7 +1787,7 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags) mtx_unlock(&pr->pr_mtx); #ifdef RACCT - if (created) + if (racct_enable && created) prison_racct_attach(pr); #endif @@ -1871,7 +1871,7 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags) } #ifdef RACCT - if (!created) { + if (racct_enable && !created) { if (!(flags & JAIL_ATTACH)) sx_sunlock(&allprison_lock); prison_racct_modify(pr); @@ -2661,7 +2661,8 @@ prison_deref(struct prison *pr, int flags) cpuset_rel(pr->pr_cpuset); osd_jail_exit(pr); #ifdef RACCT - prison_racct_detach(pr); + if (racct_enable) + prison_racct_detach(pr); #endif free(pr, M_PRISON); @@ -4482,12 +4483,15 @@ SYSCTL_JAIL_PARAM(_allow_mount, tmpfs, CTLTYPE_INT | CTLFLAG_RW, SYSCTL_JAIL_PARAM(_allow_mount, zfs, CTLTYPE_INT | CTLFLAG_RW, "B", "Jail may mount the zfs file system"); +#ifdef RACCT void prison_racct_foreach(void (*callback)(struct racct *racct, void *arg2, void *arg3), void *arg2, void *arg3) { struct prison_racct *prr; + ASSERT_RACCT_ENABLED(); + sx_slock(&allprison_lock); LIST_FOREACH(prr, &allprison_racct, prr_next) (callback)(prr->prr_racct, arg2, arg3); @@ -4499,6 +4503,7 @@ prison_racct_find_locked(const char *name) { struct prison_racct *prr; + ASSERT_RACCT_ENABLED(); sx_assert(&allprison_lock, SA_XLOCKED); if (name[0] == '\0' || strlen(name) >= MAXHOSTNAMELEN) @@ -4529,6 +4534,8 @@ prison_racct_find(const char *name) { struct prison_racct *prr; + ASSERT_RACCT_ENABLED(); + sx_xlock(&allprison_lock); prr = prison_racct_find_locked(name); sx_xunlock(&allprison_lock); @@ -4539,6 +4546,8 @@ void prison_racct_hold(struct prison_racct *prr) { + ASSERT_RACCT_ENABLED(); + refcount_acquire(&prr->prr_refcount); } @@ -4546,6 +4555,7 @@ static void prison_racct_free_locked(struct prison_racct *prr) { + ASSERT_RACCT_ENABLED(); sx_assert(&allprison_lock, SA_XLOCKED); if (refcount_release(&prr->prr_refcount)) { @@ -4560,6 +4570,7 @@ prison_racct_free(struct prison_racct *prr) { int old; + ASSERT_RACCT_ENABLED(); sx_assert(&allprison_lock, SA_UNLOCKED); old = prr->prr_refcount; @@ -4571,12 +4582,12 @@ prison_racct_free(struct prison_racct *prr) sx_xunlock(&allprison_lock); } -#ifdef RACCT static void prison_racct_attach(struct prison *pr) { struct prison_racct *prr; + ASSERT_RACCT_ENABLED(); sx_assert(&allprison_lock, SA_XLOCKED); prr = prison_racct_find_locked(pr->pr_name); @@ -4596,6 +4607,8 @@ prison_racct_modify(struct prison *pr) struct ucred *cred; struct prison_racct *oldprr; + ASSERT_RACCT_ENABLED(); + sx_slock(&allproc_lock); sx_xlock(&allprison_lock); @@ -4635,6 +4648,7 @@ static void prison_racct_detach(struct prison *pr) { + ASSERT_RACCT_ENABLED(); sx_assert(&allprison_lock, SA_UNLOCKED); if (pr->pr_prison_racct == NULL) diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c index d18914b..184287c 100644 --- a/sys/kern/kern_racct.c +++ b/sys/kern/kern_racct.c @@ -71,8 +71,15 @@ FEATURE(racct, "Resource Accounting"); * Do not block processes that have their %cpu usage <= pcpu_threshold. */ static int pcpu_threshold = 1; +#ifdef RACCT_DEFAULT_TO_DISABLED +int racct_enable = 0; +#else +int racct_enable = 1; +#endif SYSCTL_NODE(_kern, OID_AUTO, racct, CTLFLAG_RW, 0, "Resource Accounting"); +SYSCTL_UINT(_kern_racct, OID_AUTO, enable, CTLFLAG_RDTUN, &racct_enable, + 0, "Enable RACCT/RCTL"); SYSCTL_UINT(_kern_racct, OID_AUTO, pcpu_threshold, CTLFLAG_RW, &pcpu_threshold, 0, "Processes with higher %cpu usage than this value can be throttled."); @@ -314,6 +321,8 @@ racct_getpcpu(struct proc *p, u_int pcpu) fixpt_t p_pctcpu; struct thread *td; + ASSERT_RACCT_ENABLED(); + /* * If the process is swapped out, we count its %cpu usage as zero. * This behaviour is consistent with the userland ps(1) tool. @@ -378,6 +387,7 @@ racct_add_racct(struct racct *dest, const struct racct *src) { int i; + ASSERT_RACCT_ENABLED(); mtx_assert(&racct_lock, MA_OWNED); /* @@ -399,6 +409,7 @@ racct_sub_racct(struct racct *dest, const struct racct *src) { int i; + ASSERT_RACCT_ENABLED(); mtx_assert(&racct_lock, MA_OWNED); /* @@ -432,6 +443,9 @@ void racct_create(struct racct **racctp) { + if (!racct_enable) + return; + SDT_PROBE(racct, kernel, racct, create, racctp, 0, 0, 0, 0); KASSERT(*racctp == NULL, ("racct already allocated")); @@ -445,6 +459,8 @@ racct_destroy_locked(struct racct **racctp) int i; struct racct *racct; + ASSERT_RACCT_ENABLED(); + SDT_PROBE(racct, kernel, racct, destroy, racctp, 0, 0, 0, 0); mtx_assert(&racct_lock, MA_OWNED); @@ -471,6 +487,9 @@ void racct_destroy(struct racct **racct) { + if (!racct_enable) + return; + mtx_lock(&racct_lock); racct_destroy_locked(racct); mtx_unlock(&racct_lock); @@ -486,6 +505,7 @@ racct_alloc_resource(struct racct *racct, int resource, uint64_t amount) { + ASSERT_RACCT_ENABLED(); mtx_assert(&racct_lock, MA_OWNED); KASSERT(racct != NULL, ("NULL racct")); @@ -517,6 +537,8 @@ racct_add_locked(struct proc *p, int resource, uint64_t amount) int error; #endif + ASSERT_RACCT_ENABLED(); + SDT_PROBE(racct, kernel, rusage, add, p, resource, amount, 0, 0); /* @@ -547,6 +569,9 @@ racct_add(struct proc *p, int resource, uint64_t amount) { int error; + if (!racct_enable) + return (0); + mtx_lock(&racct_lock); error = racct_add_locked(p, resource, amount); mtx_unlock(&racct_lock); @@ -558,6 +583,8 @@ racct_add_cred_locked(struct ucred *cred, int resource, uint64_t amount) { struct prison *pr; + ASSERT_RACCT_ENABLED(); + SDT_PROBE(racct, kernel, rusage, add__cred, cred, resource, amount, 0, 0); @@ -578,6 +605,9 @@ void racct_add_cred(struct ucred *cred, int resource, uint64_t amount) { + if (!racct_enable) + return; + mtx_lock(&racct_lock); racct_add_cred_locked(cred, resource, amount); mtx_unlock(&racct_lock); @@ -591,6 +621,9 @@ void racct_add_force(struct proc *p, int resource, uint64_t amount) { + if (!racct_enable) + return; + SDT_PROBE(racct, kernel, rusage, add__force, p, resource, amount, 0, 0); /* @@ -613,6 +646,8 @@ racct_set_locked(struct proc *p, int resource, uint64_t amount) int error; #endif + ASSERT_RACCT_ENABLED(); + SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0); /* @@ -672,6 +707,9 @@ racct_set(struct proc *p, int resource, uint64_t amount) { int error; + if (!racct_enable) + return (0); + mtx_lock(&racct_lock); error = racct_set_locked(p, resource, amount); mtx_unlock(&racct_lock); @@ -684,6 +722,8 @@ racct_set_force_locked(struct proc *p, int resource, uint64_t amount) int64_t old_amount, decayed_amount; int64_t diff_proc, diff_cred; + ASSERT_RACCT_ENABLED(); + SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0); /* @@ -718,6 +758,10 @@ racct_set_force_locked(struct proc *p, int resource, uint64_t amount) void racct_set_force(struct proc *p, int resource, uint64_t amount) { + + if (!racct_enable) + return; + mtx_lock(&racct_lock); racct_set_force_locked(p, resource, amount); mtx_unlock(&racct_lock); @@ -733,6 +777,9 @@ uint64_t racct_get_limit(struct proc *p, int resource) { + if (!racct_enable) + return (UINT64_MAX); + #ifdef RCTL return (rctl_get_limit(p, resource)); #else @@ -750,6 +797,9 @@ uint64_t racct_get_available(struct proc *p, int resource) { + if (!racct_enable) + return (UINT64_MAX); + #ifdef RCTL return (rctl_get_available(p, resource)); #else @@ -766,6 +816,8 @@ static int64_t racct_pcpu_available(struct proc *p) { + ASSERT_RACCT_ENABLED(); + #ifdef RCTL return (rctl_pcpu_available(p)); #else @@ -780,6 +832,9 @@ void racct_sub(struct proc *p, int resource, uint64_t amount) { + if (!racct_enable) + return; + SDT_PROBE(racct, kernel, rusage, sub, p, resource, amount, 0, 0); /* @@ -805,6 +860,8 @@ racct_sub_cred_locked(struct ucred *cred, int resource, uint64_t amount) { struct prison *pr; + ASSERT_RACCT_ENABLED(); + SDT_PROBE(racct, kernel, rusage, sub__cred, cred, resource, amount, 0, 0); @@ -828,6 +885,9 @@ void racct_sub_cred(struct ucred *cred, int resource, uint64_t amount) { + if (!racct_enable) + return; + mtx_lock(&racct_lock); racct_sub_cred_locked(cred, resource, amount); mtx_unlock(&racct_lock); @@ -841,6 +901,9 @@ racct_proc_fork(struct proc *parent, struct proc *child) { int i, error = 0; + if (!racct_enable) + return (0); + /* * Create racct for the child process. */ @@ -897,6 +960,9 @@ racct_proc_fork_done(struct proc *child) { #ifdef RCTL + if (!racct_enable) + return; + PROC_LOCK(child); mtx_lock(&racct_lock); rctl_enforce(child, RACCT_NPROC, 0); @@ -914,6 +980,9 @@ racct_proc_exit(struct proc *p) struct timeval wallclock; uint64_t pct_estimate, pct; + if (!racct_enable) + return; + PROC_LOCK(p); /* * We don't need to calculate rux, proc_reap() has already done this. @@ -968,6 +1037,9 @@ racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred, struct loginclass *oldlc, *newlc; struct prison *oldpr, *newpr, *pr; + if (!racct_enable) + return; + PROC_LOCK_ASSERT(p, MA_NOTOWNED); newuip = newcred->cr_ruidinfo; @@ -1005,6 +1077,8 @@ void racct_move(struct racct *dest, struct racct *src) { + ASSERT_RACCT_ENABLED(); + mtx_lock(&racct_lock); racct_add_racct(dest, src); @@ -1021,6 +1095,7 @@ racct_proc_throttle(struct proc *p) int cpuid; #endif + ASSERT_RACCT_ENABLED(); PROC_LOCK_ASSERT(p, MA_OWNED); /* @@ -1066,6 +1141,9 @@ racct_proc_throttle(struct proc *p) static void racct_proc_wakeup(struct proc *p) { + + ASSERT_RACCT_ENABLED(); + PROC_LOCK_ASSERT(p, MA_OWNED); if (p->p_throttled) { @@ -1080,6 +1158,8 @@ racct_decay_resource(struct racct *racct, void * res, void* dummy) int resource; int64_t r_old, r_new; + ASSERT_RACCT_ENABLED(); + resource = *(int *)res; r_old = racct->r_resources[resource]; @@ -1096,6 +1176,9 @@ racct_decay_resource(struct racct *racct, void * res, void* dummy) static void racct_decay(int resource) { + + ASSERT_RACCT_ENABLED(); + ui_racct_foreach(racct_decay_resource, &resource, NULL); loginclass_racct_foreach(racct_decay_resource, &resource, NULL); prison_racct_foreach(racct_decay_resource, &resource, NULL); @@ -1110,6 +1193,8 @@ racctd(void) uint64_t runtime; uint64_t pct, pct_estimate; + ASSERT_RACCT_ENABLED(); + for (;;) { racct_decay(RACCT_PCTCPU); @@ -1189,11 +1274,22 @@ static struct kproc_desc racctd_kp = { racctd, NULL }; -SYSINIT(racctd, SI_SUB_RACCTD, SI_ORDER_FIRST, kproc_start, &racctd_kp); + +static void +racctd_init(void) +{ + if (!racct_enable) + return; + + kproc_start(&racctd_kp); +} +SYSINIT(racctd, SI_SUB_RACCTD, SI_ORDER_FIRST, racctd_init, NULL); static void racct_init(void) { + if (!racct_enable) + return; racct_zone = uma_zcreate("racct", sizeof(struct racct), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); diff --git a/sys/kern/kern_rctl.c b/sys/kern/kern_rctl.c index 934327a..c43b83d 100644 --- a/sys/kern/kern_rctl.c +++ b/sys/kern/kern_rctl.c @@ -225,6 +225,7 @@ rctl_available_resource(const struct proc *p, const struct rctl_rule *rule) int64_t available = INT64_MAX; struct ucred *cred = p->p_ucred; + ASSERT_RACCT_ENABLED(); rw_assert(&rctl_lock, RA_LOCKED); resource = rule->rr_resource; @@ -264,6 +265,8 @@ rctl_would_exceed(const struct proc *p, const struct rctl_rule *rule, { int64_t available; + ASSERT_RACCT_ENABLED(); + rw_assert(&rctl_lock, RA_LOCKED); available = rctl_available_resource(p, rule); @@ -283,6 +286,8 @@ rctl_pcpu_available(const struct proc *p) { struct rctl_rule_link *link; int64_t available, minavailable, limit; + ASSERT_RACCT_ENABLED(); + minavailable = INT64_MAX; limit = 0; @@ -334,6 +339,8 @@ rctl_enforce(struct proc *p, int resource, uint64_t amount) static int curtime = 0; static struct timeval lasttime; + ASSERT_RACCT_ENABLED(); + rw_rlock(&rctl_lock); /* @@ -457,6 +464,8 @@ rctl_get_limit(struct proc *p, int resource) struct rctl_rule_link *link; uint64_t amount = UINT64_MAX; + ASSERT_RACCT_ENABLED(); + rw_rlock(&rctl_lock); /* @@ -487,6 +496,8 @@ rctl_get_available(struct proc *p, int resource) minavailable = INT64_MAX; + ASSERT_RACCT_ENABLED(); + rw_rlock(&rctl_lock); /* @@ -521,6 +532,8 @@ static int rctl_rule_matches(const struct rctl_rule *rule, const struct rctl_rule *filter) { + ASSERT_RACCT_ENABLED(); + if (filter->rr_subject_type != RCTL_SUBJECT_TYPE_UNDEFINED) { if (rule->rr_subject_type != filter->rr_subject_type) return (0); @@ -635,6 +648,7 @@ rctl_racct_add_rule(struct racct *racct, struct rctl_rule *rule) { struct rctl_rule_link *link; + ASSERT_RACCT_ENABLED(); KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified")); rctl_rule_acquire(rule); @@ -652,6 +666,7 @@ rctl_racct_add_rule_locked(struct racct *racct, struct rctl_rule *rule) { struct rctl_rule_link *link; + ASSERT_RACCT_ENABLED(); KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified")); rw_assert(&rctl_lock, RA_WLOCKED); @@ -678,6 +693,7 @@ rctl_racct_remove_rules(struct racct *racct, int removed = 0; struct rctl_rule_link *link, *linktmp; + ASSERT_RACCT_ENABLED(); rw_assert(&rctl_lock, RA_WLOCKED); LIST_FOREACH_SAFE(link, &racct->r_rule_links, rrl_next, linktmp) { @@ -696,6 +712,8 @@ static void rctl_rule_acquire_subject(struct rctl_rule *rule) { + ASSERT_RACCT_ENABLED(); + switch (rule->rr_subject_type) { case RCTL_SUBJECT_TYPE_UNDEFINED: case RCTL_SUBJECT_TYPE_PROCESS: @@ -722,6 +740,8 @@ static void rctl_rule_release_subject(struct rctl_rule *rule) { + ASSERT_RACCT_ENABLED(); + switch (rule->rr_subject_type) { case RCTL_SUBJECT_TYPE_UNDEFINED: case RCTL_SUBJECT_TYPE_PROCESS: @@ -749,6 +769,8 @@ rctl_rule_alloc(int flags) { struct rctl_rule *rule; + ASSERT_RACCT_ENABLED(); + rule = uma_zalloc(rctl_rule_zone, flags); if (rule == NULL) return (NULL); @@ -771,6 +793,8 @@ rctl_rule_duplicate(const struct rctl_rule *rule, int flags) { struct rctl_rule *copy; + ASSERT_RACCT_ENABLED(); + copy = uma_zalloc(rctl_rule_zone, flags); if (copy == NULL) return (NULL); @@ -793,6 +817,7 @@ void rctl_rule_acquire(struct rctl_rule *rule) { + ASSERT_RACCT_ENABLED(); KASSERT(rule->rr_refcount > 0, ("rule->rr_refcount <= 0")); refcount_acquire(&rule->rr_refcount); @@ -805,6 +830,7 @@ rctl_rule_free(void *context, int pending) rule = (struct rctl_rule *)context; + ASSERT_RACCT_ENABLED(); KASSERT(rule->rr_refcount == 0, ("rule->rr_refcount != 0")); /* @@ -819,6 +845,7 @@ void rctl_rule_release(struct rctl_rule *rule) { + ASSERT_RACCT_ENABLED(); KASSERT(rule->rr_refcount > 0, ("rule->rr_refcount <= 0")); if (refcount_release(&rule->rr_refcount)) { @@ -838,6 +865,8 @@ static int rctl_rule_fully_specified(const struct rctl_rule *rule) { + ASSERT_RACCT_ENABLED(); + switch (rule->rr_subject_type) { case RCTL_SUBJECT_TYPE_UNDEFINED: return (0); @@ -882,6 +911,8 @@ rctl_string_to_rule(char *rulestr, struct rctl_rule **rulep) struct rctl_rule *rule; id_t id; + ASSERT_RACCT_ENABLED(); + rule = rctl_rule_alloc(M_WAITOK); subjectstr = strsep(&rulestr, ":"); @@ -1008,6 +1039,7 @@ rctl_rule_add(struct rctl_rule *rule) struct rctl_rule *rule2; int match; + ASSERT_RACCT_ENABLED(); KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified")); /* @@ -1118,6 +1150,8 @@ rctl_rule_remove_callback(struct racct *racct, void *arg2, void *arg3) struct rctl_rule *filter = (struct rctl_rule *)arg2; int found = 0; + ASSERT_RACCT_ENABLED(); + rw_wlock(&rctl_lock); found += rctl_racct_remove_rules(racct, filter); rw_wunlock(&rctl_lock); @@ -1134,6 +1168,8 @@ rctl_rule_remove(struct rctl_rule *filter) int found = 0; struct proc *p; + ASSERT_RACCT_ENABLED(); + if (filter->rr_subject_type == RCTL_SUBJECT_TYPE_PROCESS && filter->rr_subject.rs_proc != NULL) { p = filter->rr_subject.rs_proc; @@ -1172,6 +1208,8 @@ rctl_rule_to_sbuf(struct sbuf *sb, const struct rctl_rule *rule) { int64_t amount; + ASSERT_RACCT_ENABLED(); + sbuf_printf(sb, "%s:", rctl_subject_type_name(rule->rr_subject_type)); switch (rule->rr_subject_type) { @@ -1231,6 +1269,8 @@ rctl_read_inbuf(char **inputstr, const char *inbufp, size_t inbuflen) int error; char *str; + ASSERT_RACCT_ENABLED(); + if (inbuflen <= 0) return (EINVAL); if (inbuflen > RCTL_MAX_INBUFLEN) @@ -1256,6 +1296,8 @@ rctl_write_outbuf(struct sbuf *outputsbuf, char *outbufp, size_t outbuflen) { int error; + ASSERT_RACCT_ENABLED(); + if (outputsbuf == NULL) return (0); @@ -1277,6 +1319,8 @@ rctl_racct_to_sbuf(struct racct *racct, int sloppy) int64_t amount; struct sbuf *sb; + ASSERT_RACCT_ENABLED(); + sb = sbuf_new_auto(); for (i = 0; i <= RACCT_MAX; i++) { if (sloppy == 0 && RACCT_IS_SLOPPY(i)) @@ -1302,6 +1346,9 @@ sys_rctl_get_racct(struct thread *td, struct rctl_get_racct_args *uap) struct loginclass *lc; struct prison_racct *prr; + if (!racct_enable) + return (ENOSYS); + error = priv_check(td, PRIV_RCTL_GET_RACCT); if (error != 0) return (error); @@ -1372,6 +1419,8 @@ rctl_get_rules_callback(struct racct *racct, void *arg2, void *arg3) struct rctl_rule_link *link; struct sbuf *sb = (struct sbuf *)arg3; + ASSERT_RACCT_ENABLED(); + rw_rlock(&rctl_lock); LIST_FOREACH(link, &racct->r_rule_links, rrl_next) { if (!rctl_rule_matches(link->rrl_rule, filter)) @@ -1393,6 +1442,9 @@ sys_rctl_get_rules(struct thread *td, struct rctl_get_rules_args *uap) struct rctl_rule_link *link; struct proc *p; + if (!racct_enable) + return (ENOSYS); + error = priv_check(td, PRIV_RCTL_GET_RULES); if (error != 0) return (error); @@ -1467,6 +1519,9 @@ sys_rctl_get_limits(struct thread *td, struct rctl_get_limits_args *uap) struct rctl_rule *filter; struct rctl_rule_link *link; + if (!racct_enable) + return (ENOSYS); + error = priv_check(td, PRIV_RCTL_GET_LIMITS); if (error != 0) return (error); @@ -1538,6 +1593,9 @@ sys_rctl_add_rule(struct thread *td, struct rctl_add_rule_args *uap) struct rctl_rule *rule; char *inputstr; + if (!racct_enable) + return (ENOSYS); + error = priv_check(td, PRIV_RCTL_ADD_RULE); if (error != 0) return (error); @@ -1580,6 +1638,9 @@ sys_rctl_remove_rule(struct thread *td, struct rctl_remove_rule_args *uap) struct rctl_rule *filter; char *inputstr; + if (!racct_enable) + return (ENOSYS); + error = priv_check(td, PRIV_RCTL_REMOVE_RULE); if (error != 0) return (error); @@ -1616,6 +1677,8 @@ rctl_proc_ucred_changed(struct proc *p, struct ucred *newcred) struct prison_racct *newprr; LIST_HEAD(, rctl_rule_link) newrules; + ASSERT_RACCT_ENABLED(); + newuip = newcred->cr_ruidinfo; newlc = newcred->cr_loginclass; newprr = newcred->cr_prison->pr_prison_racct; @@ -1756,6 +1819,7 @@ rctl_proc_fork(struct proc *parent, struct proc *child) LIST_INIT(&child->p_racct->r_rule_links); + ASSERT_RACCT_ENABLED(); KASSERT(parent->p_racct != NULL, ("process without racct; p = %p", parent)); rw_wlock(&rctl_lock); @@ -1809,6 +1873,8 @@ rctl_racct_release(struct racct *racct) { struct rctl_rule_link *link; + ASSERT_RACCT_ENABLED(); + rw_wlock(&rctl_lock); while (!LIST_EMPTY(&racct->r_rule_links)) { link = LIST_FIRST(&racct->r_rule_links); @@ -1823,6 +1889,9 @@ static void rctl_init(void) { + if (!racct_enable) + return; + rctl_rule_link_zone = uma_zcreate("rctl_rule_link", sizeof(struct rctl_rule_link), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c index 0bc6630..dd119a2 100644 --- a/sys/kern/kern_thr.c +++ b/sys/kern/kern_thr.c @@ -281,9 +281,11 @@ create_thread(struct thread *td, mcontext_t *ctx, fail: #ifdef RACCT - PROC_LOCK(p); - racct_sub(p, RACCT_NTHR, 1); - PROC_UNLOCK(p); + if (racct_enable) { + PROC_LOCK(p); + racct_sub(p, RACCT_NTHR, 1); + PROC_UNLOCK(p); + } #endif return (error); } diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c index 53b1f35..1aa79df 100644 --- a/sys/kern/sched_4bsd.c +++ b/sys/kern/sched_4bsd.c @@ -1586,7 +1586,7 @@ sched_pctcpu(struct thread *td) return (ts->ts_pctcpu); } -#ifdef RACCT +#ifdef RACCT /* * Calculates the contribution to the thread cpu usage for the latest * (unfinished) second. diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index 6bef83c..0b5d380b 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$"); #include <sys/ktr.h> #include <sys/pioctl.h> #include <sys/ptrace.h> +#include <sys/racct.h> #include <sys/resourcevar.h> #include <sys/sched.h> #include <sys/signalvar.h> @@ -177,11 +178,13 @@ userret(struct thread *td, struct trapframe *frame) __func__, td, p->p_pid, td->td_name, curvnet, (td->td_vnet_lpush != NULL) ? td->td_vnet_lpush : "N/A")); #endif -#ifdef RACCT - PROC_LOCK(p); - while (p->p_throttled == 1) - msleep(p->p_racct, &p->p_mtx, 0, "racct", 0); - PROC_UNLOCK(p); +#ifdef RACCT + if (racct_enable) { + PROC_LOCK(p); + while (p->p_throttled == 1) + msleep(p->p_racct, &p->p_mtx, 0, "racct", 0); + PROC_UNLOCK(p); + } #endif } diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c index d58cb7e..3248278 100644 --- a/sys/kern/sysv_msg.c +++ b/sys/kern/sysv_msg.c @@ -623,12 +623,14 @@ sys_msgget(td, uap) goto done2; } #ifdef RACCT - PROC_LOCK(td->td_proc); - error = racct_add(td->td_proc, RACCT_NMSGQ, 1); - PROC_UNLOCK(td->td_proc); - if (error != 0) { - error = ENOSPC; - goto done2; + if (racct_enable) { + PROC_LOCK(td->td_proc); + error = racct_add(td->td_proc, RACCT_NMSGQ, 1); + PROC_UNLOCK(td->td_proc); + if (error != 0) { + error = ENOSPC; + goto done2; + } } #endif DPRINTF(("msqid %d is available\n", msqid)); @@ -730,20 +732,22 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype) #endif #ifdef RACCT - PROC_LOCK(td->td_proc); - if (racct_add(td->td_proc, RACCT_MSGQQUEUED, 1)) { - PROC_UNLOCK(td->td_proc); - error = EAGAIN; - goto done2; - } - saved_msgsz = msgsz; - if (racct_add(td->td_proc, RACCT_MSGQSIZE, msgsz)) { - racct_sub(td->td_proc, RACCT_MSGQQUEUED, 1); + if (racct_enable) { + PROC_LOCK(td->td_proc); + if (racct_add(td->td_proc, RACCT_MSGQQUEUED, 1)) { + PROC_UNLOCK(td->td_proc); + error = EAGAIN; + goto done2; + } + saved_msgsz = msgsz; + if (racct_add(td->td_proc, RACCT_MSGQSIZE, msgsz)) { + racct_sub(td->td_proc, RACCT_MSGQQUEUED, 1); + PROC_UNLOCK(td->td_proc); + error = EAGAIN; + goto done2; + } PROC_UNLOCK(td->td_proc); - error = EAGAIN; - goto done2; } - PROC_UNLOCK(td->td_proc); #endif segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz; @@ -1000,7 +1004,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype) td->td_retval[0] = 0; done3: #ifdef RACCT - if (error != 0) { + if (racct_enable && error != 0) { PROC_LOCK(td->td_proc); racct_sub(td->td_proc, RACCT_MSGQQUEUED, 1); racct_sub(td->td_proc, RACCT_MSGQSIZE, saved_msgsz); diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c index f9ff217..441cbfc 100644 --- a/sys/kern/sysv_sem.c +++ b/sys/kern/sysv_sem.c @@ -925,12 +925,14 @@ sys_semget(struct thread *td, struct semget_args *uap) goto done2; } #ifdef RACCT - PROC_LOCK(td->td_proc); - error = racct_add(td->td_proc, RACCT_NSEM, nsems); - PROC_UNLOCK(td->td_proc); - if (error != 0) { - error = ENOSPC; - goto done2; + if (racct_enable) { + PROC_LOCK(td->td_proc); + error = racct_add(td->td_proc, RACCT_NSEM, nsems); + PROC_UNLOCK(td->td_proc); + if (error != 0) { + error = ENOSPC; + goto done2; + } } #endif DPRINTF(("semid %d is available\n", semid)); @@ -1019,12 +1021,15 @@ sys_semop(struct thread *td, struct semop_args *uap) return (E2BIG); } else { #ifdef RACCT - PROC_LOCK(td->td_proc); - if (nsops > racct_get_available(td->td_proc, RACCT_NSEMOP)) { + if (racct_enable) { + PROC_LOCK(td->td_proc); + if (nsops > + racct_get_available(td->td_proc, RACCT_NSEMOP)) { + PROC_UNLOCK(td->td_proc); + return (E2BIG); + } PROC_UNLOCK(td->td_proc); - return (E2BIG); } - PROC_UNLOCK(td->td_proc); #endif sops = malloc(nsops * sizeof(*sops), M_TEMP, M_WAITOK); diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index 66a2a43..613a462 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -651,17 +651,19 @@ shmget_allocate_segment(struct thread *td, struct shmget_args *uap, int mode) ("segnum %d shmalloced %d", segnum, shmalloced)); shmseg = &shmsegs[segnum]; #ifdef RACCT - PROC_LOCK(td->td_proc); - if (racct_add(td->td_proc, RACCT_NSHM, 1)) { - PROC_UNLOCK(td->td_proc); - return (ENOSPC); - } - if (racct_add(td->td_proc, RACCT_SHMSIZE, size)) { - racct_sub(td->td_proc, RACCT_NSHM, 1); + if (racct_enable) { + PROC_LOCK(td->td_proc); + if (racct_add(td->td_proc, RACCT_NSHM, 1)) { + PROC_UNLOCK(td->td_proc); + return (ENOSPC); + } + if (racct_add(td->td_proc, RACCT_SHMSIZE, size)) { + racct_sub(td->td_proc, RACCT_NSHM, 1); + PROC_UNLOCK(td->td_proc); + return (ENOMEM); + } PROC_UNLOCK(td->td_proc); - return (ENOMEM); } - PROC_UNLOCK(td->td_proc); #endif /* @@ -672,10 +674,12 @@ shmget_allocate_segment(struct thread *td, struct shmget_args *uap, int mode) 0, size, VM_PROT_DEFAULT, 0, cred); if (shm_object == NULL) { #ifdef RACCT - PROC_LOCK(td->td_proc); - racct_sub(td->td_proc, RACCT_NSHM, 1); - racct_sub(td->td_proc, RACCT_SHMSIZE, size); - PROC_UNLOCK(td->td_proc); + if (racct_enable) { + PROC_LOCK(td->td_proc); + racct_sub(td->td_proc, RACCT_NSHM, 1); + racct_sub(td->td_proc, RACCT_SHMSIZE, size); + PROC_UNLOCK(td->td_proc); + } #endif return (ENOMEM); } diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC index 5a77910..0036dd9 100644 --- a/sys/pc98/conf/GENERIC +++ b/sys/pc98/conf/GENERIC @@ -70,6 +70,9 @@ options CAPABILITIES # Capsicum capabilities options PROCDESC # Support for process descriptors options MAC # TrustedBSD MAC Framework options INCLUDE_CONFIG_FILE # Include this file in kernel +options RACCT # Resource accounting framework +options RACCT_DEFAULT_TO_DISABLED # Set kern.racct.enable=0 by default +options RCTL # Resource limits # Debugging support. Always need this: options KDB # Enable kernel debugger support. diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC index 78c1f46..507bacb 100644 --- a/sys/powerpc/conf/GENERIC +++ b/sys/powerpc/conf/GENERIC @@ -75,6 +75,9 @@ options MAC # TrustedBSD MAC Framework options KDTRACE_HOOKS # Kernel DTrace hooks options DDB_CTF # Kernel ELF linker loads CTF data options INCLUDE_CONFIG_FILE # Include this file in kernel +options RACCT # Resource accounting framework +options RACCT_DEFAULT_TO_DISABLED # Set kern.racct.enable=0 by default +options RCTL # Resource limits # Debugging support. Always need this: options KDB # Enable kernel debugger support. diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC index 7b6905c..5ba1adc 100644 --- a/sys/sparc64/conf/GENERIC +++ b/sys/sparc64/conf/GENERIC @@ -66,6 +66,9 @@ options CAPABILITIES # Capsicum capabilities options PROCDESC # Support for process descriptors options MAC # TrustedBSD MAC Framework options INCLUDE_CONFIG_FILE # Include this file in kernel +options RACCT # Resource accounting framework +options RACCT_DEFAULT_TO_DISABLED # Set kern.racct.enable=0 by default +options RCTL # Resource limits # Debugging support. Always need this: options KDB # Enable kernel debugger support. diff --git a/sys/sys/racct.h b/sys/sys/racct.h index 3b34891..7a7c07a 100644 --- a/sys/sys/racct.h +++ b/sys/sys/racct.h @@ -82,6 +82,10 @@ struct ucred; #define RACCT_DECAYING 0x20 extern int racct_types[]; +extern int racct_enable; + +#define ASSERT_RACCT_ENABLED() KASSERT(racct_enable, \ + ("%s called with !racct_enable", __func__)) /* * Amount stored in c_resources[] is 10**6 times bigger than what's diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index 04e9fb9..c09dbc2 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -198,11 +198,13 @@ swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred) panic("swap_reserve: & PAGE_MASK"); #ifdef RACCT - PROC_LOCK(curproc); - error = racct_add(curproc, RACCT_SWAP, incr); - PROC_UNLOCK(curproc); - if (error != 0) - return (0); + if (racct_enable) { + PROC_LOCK(curproc); + error = racct_add(curproc, RACCT_SWAP, incr); + PROC_UNLOCK(curproc); + if (error != 0) + return (0); + } #endif res = 0; diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 5cdff1d..275036a 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -298,11 +298,11 @@ vmspace_alloc(vm_offset_t min, vm_offset_t max, pmap_pinit_t pinit) return (vm); } +#ifdef RACCT static void vmspace_container_reset(struct proc *p) { -#ifdef RACCT PROC_LOCK(p); racct_set(p, RACCT_DATA, 0); racct_set(p, RACCT_STACK, 0); @@ -310,8 +310,8 @@ vmspace_container_reset(struct proc *p) racct_set(p, RACCT_MEMLOCK, 0); racct_set(p, RACCT_VMEM, 0); PROC_UNLOCK(p); -#endif } +#endif static inline void vmspace_dofree(struct vmspace *vm) @@ -413,7 +413,10 @@ vmspace_exit(struct thread *td) pmap_activate(td); vmspace_dofree(vm); } - vmspace_container_reset(p); +#ifdef RACCT + if (racct_enable) + vmspace_container_reset(p); +#endif } /* Acquire reference to vmspace owned by another process. */ @@ -3665,14 +3668,16 @@ Retry: return (KERN_NO_SPACE); } #ifdef RACCT - PROC_LOCK(p); - if (is_procstack && - racct_set(p, RACCT_STACK, ctob(vm->vm_ssize) + grow_amount)) { + if (racct_enable) { + PROC_LOCK(p); + if (is_procstack && racct_set(p, RACCT_STACK, + ctob(vm->vm_ssize) + grow_amount)) { + PROC_UNLOCK(p); + vm_map_unlock_read(map); + return (KERN_NO_SPACE); + } PROC_UNLOCK(p); - vm_map_unlock_read(map); - return (KERN_NO_SPACE); } - PROC_UNLOCK(p); #endif /* Round up the grow amount modulo sgrowsiz */ @@ -3698,15 +3703,17 @@ Retry: goto out; } #ifdef RACCT - PROC_LOCK(p); - if (racct_set(p, RACCT_MEMLOCK, - ptoa(pmap_wired_count(map->pmap)) + grow_amount)) { + if (racct_enable) { + PROC_LOCK(p); + if (racct_set(p, RACCT_MEMLOCK, + ptoa(pmap_wired_count(map->pmap)) + grow_amount)) { + PROC_UNLOCK(p); + vm_map_unlock_read(map); + rv = KERN_NO_SPACE; + goto out; + } PROC_UNLOCK(p); - vm_map_unlock_read(map); - rv = KERN_NO_SPACE; - goto out; } - PROC_UNLOCK(p); #endif } /* If we would blow our VMEM resource limit, no go */ @@ -3716,14 +3723,16 @@ Retry: goto out; } #ifdef RACCT - PROC_LOCK(p); - if (racct_set(p, RACCT_VMEM, map->size + grow_amount)) { + if (racct_enable) { + PROC_LOCK(p); + if (racct_set(p, RACCT_VMEM, map->size + grow_amount)) { + PROC_UNLOCK(p); + vm_map_unlock_read(map); + rv = KERN_NO_SPACE; + goto out; + } PROC_UNLOCK(p); - vm_map_unlock_read(map); - rv = KERN_NO_SPACE; - goto out; } - PROC_UNLOCK(p); #endif if (vm_map_lock_upgrade(map)) @@ -3825,7 +3834,7 @@ Retry: out: #ifdef RACCT - if (rv != KERN_SUCCESS) { + if (racct_enable && rv != KERN_SUCCESS) { PROC_LOCK(p); error = racct_set(p, RACCT_VMEM, map->size); KASSERT(error == 0, ("decreasing RACCT_VMEM failed")); diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 997b566..b4bf117 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -1095,16 +1095,18 @@ vm_mlock(struct proc *proc, struct ucred *cred, const void *addr0, size_t len) if (npages + cnt.v_wire_count > vm_page_max_wired) return (EAGAIN); #ifdef RACCT - PROC_LOCK(proc); - error = racct_set(proc, RACCT_MEMLOCK, nsize); - PROC_UNLOCK(proc); - if (error != 0) - return (ENOMEM); + if (racct_enable) { + PROC_LOCK(proc); + error = racct_set(proc, RACCT_MEMLOCK, nsize); + PROC_UNLOCK(proc); + if (error != 0) + return (ENOMEM); + } #endif error = vm_map_wire(map, start, end, VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES); #ifdef RACCT - if (error != KERN_SUCCESS) { + if (racct_enable && error != KERN_SUCCESS) { PROC_LOCK(proc); racct_set(proc, RACCT_MEMLOCK, ptoa(pmap_wired_count(map->pmap))); @@ -1152,11 +1154,13 @@ sys_mlockall(td, uap) PROC_UNLOCK(td->td_proc); } #ifdef RACCT - PROC_LOCK(td->td_proc); - error = racct_set(td->td_proc, RACCT_MEMLOCK, map->size); - PROC_UNLOCK(td->td_proc); - if (error != 0) - return (ENOMEM); + if (racct_enable) { + PROC_LOCK(td->td_proc); + error = racct_set(td->td_proc, RACCT_MEMLOCK, map->size); + PROC_UNLOCK(td->td_proc); + if (error != 0) + return (ENOMEM); + } #endif if (uap->how & MCL_FUTURE) { @@ -1178,7 +1182,7 @@ sys_mlockall(td, uap) error = (error == KERN_SUCCESS ? 0 : EAGAIN); } #ifdef RACCT - if (error != KERN_SUCCESS) { + if (racct_enable && error != KERN_SUCCESS) { PROC_LOCK(td->td_proc); racct_set(td->td_proc, RACCT_MEMLOCK, ptoa(pmap_wired_count(map->pmap))); @@ -1220,7 +1224,7 @@ sys_munlockall(td, uap) error = vm_map_unwire(map, vm_map_min(map), vm_map_max(map), VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK); #ifdef RACCT - if (error == KERN_SUCCESS) { + if (racct_enable && error == KERN_SUCCESS) { PROC_LOCK(td->td_proc); racct_set(td->td_proc, RACCT_MEMLOCK, 0); PROC_UNLOCK(td->td_proc); @@ -1264,7 +1268,7 @@ sys_munlock(td, uap) error = vm_map_unwire(&td->td_proc->p_vmspace->vm_map, start, end, VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES); #ifdef RACCT - if (error == KERN_SUCCESS) { + if (racct_enable && error == KERN_SUCCESS) { PROC_LOCK(td->td_proc); map = &td->td_proc->p_vmspace->vm_map; racct_set(td->td_proc, RACCT_MEMLOCK, diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index db10fa4..998cd37 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -1794,11 +1794,13 @@ vm_daemon(void) while (TRUE) { mtx_lock(&vm_daemon_mtx); + msleep(&vm_daemon_needed, &vm_daemon_mtx, PPAUSE, "psleep", #ifdef RACCT - msleep(&vm_daemon_needed, &vm_daemon_mtx, PPAUSE, "psleep", hz); + racct_enable ? hz : 0 #else - msleep(&vm_daemon_needed, &vm_daemon_mtx, PPAUSE, "psleep", 0); + 0 #endif + ); swapout_flags = vm_pageout_req_swapout; vm_pageout_req_swapout = 0; mtx_unlock(&vm_daemon_mtx); @@ -1873,33 +1875,40 @@ again: &vm->vm_map, limit); } #ifdef RACCT - rsize = IDX_TO_OFF(size); - PROC_LOCK(p); - racct_set(p, RACCT_RSS, rsize); - ravailable = racct_get_available(p, RACCT_RSS); - PROC_UNLOCK(p); - if (rsize > ravailable) { - /* - * Don't be overly aggressive; this might be - * an innocent process, and the limit could've - * been exceeded by some memory hog. Don't - * try to deactivate more than 1/4th of process' - * resident set size. - */ - if (attempts <= 8) { - if (ravailable < rsize - (rsize / 4)) - ravailable = rsize - (rsize / 4); - } - vm_pageout_map_deactivate_pages( - &vm->vm_map, OFF_TO_IDX(ravailable)); - /* Update RSS usage after paging out. */ - size = vmspace_resident_count(vm); + if (racct_enable) { rsize = IDX_TO_OFF(size); PROC_LOCK(p); racct_set(p, RACCT_RSS, rsize); + ravailable = racct_get_available(p, RACCT_RSS); PROC_UNLOCK(p); - if (rsize > ravailable) - tryagain = 1; + if (rsize > ravailable) { + /* + * Don't be overly aggressive; this + * might be an innocent process, + * and the limit could've been exceeded + * by some memory hog. Don't try + * to deactivate more than 1/4th + * of process' resident set size. + */ + if (attempts <= 8) { + if (ravailable < rsize - + (rsize / 4)) { + ravailable = rsize - + (rsize / 4); + } + } + vm_pageout_map_deactivate_pages( + &vm->vm_map, + OFF_TO_IDX(ravailable)); + /* Update RSS usage after paging out. */ + size = vmspace_resident_count(vm); + rsize = IDX_TO_OFF(size); + PROC_LOCK(p); + racct_set(p, RACCT_RSS, rsize); + PROC_UNLOCK(p); + if (rsize > ravailable) + tryagain = 1; + } } #endif vmspace_free(vm); diff --git a/sys/vm/vm_unix.c b/sys/vm/vm_unix.c index edb6ecc..616d7a9 100644 --- a/sys/vm/vm_unix.c +++ b/sys/vm/vm_unix.c @@ -130,35 +130,39 @@ sys_obreak(td, uap) goto done; } #ifdef RACCT - PROC_LOCK(td->td_proc); - error = racct_set(td->td_proc, RACCT_DATA, new - base); - if (error != 0) { - PROC_UNLOCK(td->td_proc); - error = ENOMEM; - goto done; - } - error = racct_set(td->td_proc, RACCT_VMEM, - map->size + (new - old)); - if (error != 0) { - racct_set_force(td->td_proc, RACCT_DATA, old - base); - PROC_UNLOCK(td->td_proc); - error = ENOMEM; - goto done; - } - if (!old_mlock && map->flags & MAP_WIREFUTURE) { - error = racct_set(td->td_proc, RACCT_MEMLOCK, - ptoa(pmap_wired_count(map->pmap)) + (new - old)); + if (racct_enable) { + PROC_LOCK(td->td_proc); + error = racct_set(td->td_proc, RACCT_DATA, new - base); + if (error != 0) { + PROC_UNLOCK(td->td_proc); + error = ENOMEM; + goto done; + } + error = racct_set(td->td_proc, RACCT_VMEM, + map->size + (new - old)); if (error != 0) { racct_set_force(td->td_proc, RACCT_DATA, old - base); - racct_set_force(td->td_proc, RACCT_VMEM, - map->size); PROC_UNLOCK(td->td_proc); error = ENOMEM; goto done; } + if (!old_mlock && map->flags & MAP_WIREFUTURE) { + error = racct_set(td->td_proc, RACCT_MEMLOCK, + ptoa(pmap_wired_count(map->pmap)) + + (new - old)); + if (error != 0) { + racct_set_force(td->td_proc, RACCT_DATA, + old - base); + racct_set_force(td->td_proc, RACCT_VMEM, + map->size); + PROC_UNLOCK(td->td_proc); + error = ENOMEM; + goto done; + } + } + PROC_UNLOCK(td->td_proc); } - PROC_UNLOCK(td->td_proc); #endif prot = VM_PROT_RW; #ifdef COMPAT_FREEBSD32 @@ -170,14 +174,19 @@ sys_obreak(td, uap) rv = vm_map_insert(map, NULL, 0, old, new, prot, VM_PROT_ALL, 0); if (rv != KERN_SUCCESS) { #ifdef RACCT - PROC_LOCK(td->td_proc); - racct_set_force(td->td_proc, RACCT_DATA, old - base); - racct_set_force(td->td_proc, RACCT_VMEM, map->size); - if (!old_mlock && map->flags & MAP_WIREFUTURE) { - racct_set_force(td->td_proc, RACCT_MEMLOCK, - ptoa(pmap_wired_count(map->pmap))); + if (racct_enable) { + PROC_LOCK(td->td_proc); + racct_set_force(td->td_proc, + RACCT_DATA, old - base); + racct_set_force(td->td_proc, + RACCT_VMEM, map->size); + if (!old_mlock && map->flags & MAP_WIREFUTURE) { + racct_set_force(td->td_proc, + RACCT_MEMLOCK, + ptoa(pmap_wired_count(map->pmap))); + } + PROC_UNLOCK(td->td_proc); } - PROC_UNLOCK(td->td_proc); #endif error = ENOMEM; goto done; @@ -205,14 +214,16 @@ sys_obreak(td, uap) } vm->vm_dsize -= btoc(old - new); #ifdef RACCT - PROC_LOCK(td->td_proc); - racct_set_force(td->td_proc, RACCT_DATA, new - base); - racct_set_force(td->td_proc, RACCT_VMEM, map->size); - if (!old_mlock && map->flags & MAP_WIREFUTURE) { - racct_set_force(td->td_proc, RACCT_MEMLOCK, - ptoa(pmap_wired_count(map->pmap))); + if (racct_enable) { + PROC_LOCK(td->td_proc); + racct_set_force(td->td_proc, RACCT_DATA, new - base); + racct_set_force(td->td_proc, RACCT_VMEM, map->size); + if (!old_mlock && map->flags & MAP_WIREFUTURE) { + racct_set_force(td->td_proc, RACCT_MEMLOCK, + ptoa(pmap_wired_count(map->pmap))); + } + PROC_UNLOCK(td->td_proc); } - PROC_UNLOCK(td->td_proc); #endif } done: diff --git a/usr.bin/rctl/rctl.8 b/usr.bin/rctl/rctl.8 index 2bf9aa5..b63a67e 100644 --- a/usr.bin/rctl/rctl.8 +++ b/usr.bin/rctl/rctl.8 @@ -233,6 +233,18 @@ for a list of supported signals Not all actions are supported for all resources. Attempting to add a rule with an action not supported by a given resource will result in error. +.Sh LOADER TUNABLES +Tunables can be set at the +.Xr loader 8 +prompt, or +.Xr loader.conf 5 . +.Bl -tag -width indent +.It Va kern.racct.enable: No 1 +Enable +.Nm . +This defaults to 1, unless +.Cd "options RACCT_DEFAULT_TO_DISABLED" +is set in the kernel configuration file. .Sh EXIT STATUS .Ex -std .Sh EXAMPLES |