aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Tomasz Napierala <trasz@FreeBSD.org>2015-11-08 18:08:31 +0000
committerEdward Tomasz Napierala <trasz@FreeBSD.org>2015-11-08 18:08:31 +0000
commit2b4035eeb68663604f064304a079ce0a36d1e7b6 (patch)
tree95f41827273c285d633e6765ed8247c461f67957
parent6a833a7a2cac3545256910f8f6c497c5c12d795f (diff)
downloadsrc-2b4035eeb68663604f064304a079ce0a36d1e7b6.tar.gz
src-2b4035eeb68663604f064304a079ce0a36d1e7b6.zip
Speed up rctl(8) rule retrieval; the difference shows mostly in "rctl -n",
as otherwise most of the time is spent resolving UIDs to names. Reviewed by: mjg@ MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D4059
Notes
Notes: svn path=/head/; revision=290551
-rw-r--r--sys/kern/kern_rctl.c46
-rw-r--r--sys/sys/racct.h7
2 files changed, 34 insertions, 19 deletions
diff --git a/sys/kern/kern_rctl.c b/sys/kern/kern_rctl.c
index c43b83df433a..34ad055c01d5 100644
--- a/sys/kern/kern_rctl.c
+++ b/sys/kern/kern_rctl.c
@@ -71,13 +71,18 @@ FEATURE(rctl, "Resource Limits");
#define HRF_DONT_INHERIT 1
#define HRF_DONT_ACCUMULATE 2
-/* Default buffer size for rctl_get_rules(2). */
-#define RCTL_DEFAULT_BUFSIZE 4096
-#define RCTL_MAX_INBUFLEN 4096
+#define RCTL_MAX_INBUFLEN 4 * 1024
+#define RCTL_MAX_OUTBUFLEN 16 * 1024 * 1024
#define RCTL_LOG_BUFSIZE 128
#define RCTL_PCPU_SHIFT (10 * 1000000)
+unsigned int rctl_maxbufsize = RCTL_MAX_OUTBUFLEN;
+
+SYSCTL_NODE(_kern_racct, OID_AUTO, rctl, CTLFLAG_RW, 0, "Resource Limits");
+SYSCTL_UINT(_kern_racct_rctl, OID_AUTO, maxbufsize, CTLFLAG_RWTUN,
+ &rctl_maxbufsize, 0, "Maximum output buffer size");
+
/*
* 'rctl_rule_link' connects a rule with every racct it's related to.
* For example, rule 'user:X:openfiles:deny=N/process' is linked
@@ -1435,7 +1440,7 @@ int
sys_rctl_get_rules(struct thread *td, struct rctl_get_rules_args *uap)
{
int error;
- size_t bufsize = RCTL_DEFAULT_BUFSIZE;
+ size_t bufsize;
char *inputstr, *buf;
struct sbuf *sb;
struct rctl_rule *filter;
@@ -1461,12 +1466,16 @@ sys_rctl_get_rules(struct thread *td, struct rctl_get_rules_args *uap)
return (error);
}
-again:
+ bufsize = uap->outbuflen;
+ if (bufsize > rctl_maxbufsize) {
+ sx_sunlock(&allproc_lock);
+ return (E2BIG);
+ }
+
buf = malloc(bufsize, M_RCTL, M_WAITOK);
sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN);
KASSERT(sb != NULL, ("sbuf_new failed"));
- sx_assert(&allproc_lock, SA_LOCKED);
FOREACH_PROC_IN_SYSTEM(p) {
rw_rlock(&rctl_lock);
LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
@@ -1489,10 +1498,8 @@ again:
ui_racct_foreach(rctl_get_rules_callback, filter, sb);
prison_racct_foreach(rctl_get_rules_callback, filter, sb);
if (sbuf_error(sb) == ENOMEM) {
- sbuf_delete(sb);
- free(buf, M_RCTL);
- bufsize *= 4;
- goto again;
+ error = ERANGE;
+ goto out;
}
/*
@@ -1502,7 +1509,7 @@ again:
sbuf_setpos(sb, sbuf_len(sb) - 1);
error = rctl_write_outbuf(sb, uap->outbufp, uap->outbuflen);
-
+out:
rctl_rule_release(filter);
sx_sunlock(&allproc_lock);
free(buf, M_RCTL);
@@ -1513,7 +1520,7 @@ int
sys_rctl_get_limits(struct thread *td, struct rctl_get_limits_args *uap)
{
int error;
- size_t bufsize = RCTL_DEFAULT_BUFSIZE;
+ size_t bufsize;
char *inputstr, *buf;
struct sbuf *sb;
struct rctl_rule *filter;
@@ -1554,7 +1561,13 @@ sys_rctl_get_limits(struct thread *td, struct rctl_get_limits_args *uap)
return (EINVAL);
}
-again:
+ bufsize = uap->outbuflen;
+ if (bufsize > rctl_maxbufsize) {
+ rctl_rule_release(filter);
+ sx_sunlock(&allproc_lock);
+ return (E2BIG);
+ }
+
buf = malloc(bufsize, M_RCTL, M_WAITOK);
sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN);
KASSERT(sb != NULL, ("sbuf_new failed"));
@@ -1567,10 +1580,8 @@ again:
}
rw_runlock(&rctl_lock);
if (sbuf_error(sb) == ENOMEM) {
- sbuf_delete(sb);
- free(buf, M_RCTL);
- bufsize *= 4;
- goto again;
+ error = ERANGE;
+ goto out;
}
/*
@@ -1580,6 +1591,7 @@ again:
sbuf_setpos(sb, sbuf_len(sb) - 1);
error = rctl_write_outbuf(sb, uap->outbufp, uap->outbuflen);
+out:
rctl_rule_release(filter);
sx_sunlock(&allproc_lock);
free(buf, M_RCTL);
diff --git a/sys/sys/racct.h b/sys/sys/racct.h
index 313d5d05de96..307585680ca0 100644
--- a/sys/sys/racct.h
+++ b/sys/sys/racct.h
@@ -37,9 +37,10 @@
#define _RACCT_H_
#include <sys/cdefs.h>
-#include <sys/stdint.h>
-#include <sys/queue.h>
#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/stdint.h>
+#include <sys/sysctl.h>
struct proc;
struct rctl_rule_link;
@@ -146,6 +147,8 @@ struct racct {
LIST_HEAD(, rctl_rule_link) r_rule_links;
};
+SYSCTL_DECL(_kern_racct);
+
#ifdef RACCT
int racct_add(struct proc *p, int resource, uint64_t amount);