summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/amd64/conf/GENERIC3
-rw-r--r--sys/conf/options1
-rw-r--r--sys/i386/conf/GENERIC3
-rw-r--r--sys/kern/imgact_elf.c14
-rw-r--r--sys/kern/kern_descrip.c36
-rw-r--r--sys/kern/kern_exit.c8
-rw-r--r--sys/kern/kern_jail.c22
-rw-r--r--sys/kern/kern_racct.c98
-rw-r--r--sys/kern/kern_rctl.c69
-rw-r--r--sys/kern/kern_thr.c8
-rw-r--r--sys/kern/sched_4bsd.c2
-rw-r--r--sys/kern/subr_trap.c13
-rw-r--r--sys/kern/sysv_msg.c42
-rw-r--r--sys/kern/sysv_sem.c25
-rw-r--r--sys/kern/sysv_shm.c30
-rw-r--r--sys/pc98/conf/GENERIC3
-rw-r--r--sys/powerpc/conf/GENERIC3
-rw-r--r--sys/sparc64/conf/GENERIC3
-rw-r--r--sys/sys/racct.h4
-rw-r--r--sys/vm/swap_pager.c12
-rw-r--r--sys/vm/vm_map.c55
-rw-r--r--sys/vm/vm_mmap.c32
-rw-r--r--sys/vm/vm_pageout.c59
-rw-r--r--sys/vm/vm_unix.c81
-rw-r--r--usr.bin/rctl/rctl.812
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
OpenPOWER on IntegriCloud