]> xenbits.xensource.com Git - people/liuw/freebsd.git/commitdiff
Speed up rctl(8) rule retrieval; the difference shows mostly in "rctl -n",
authortrasz <trasz@FreeBSD.org>
Sun, 8 Nov 2015 18:08:31 +0000 (18:08 +0000)
committertrasz <trasz@FreeBSD.org>
Sun, 8 Nov 2015 18:08:31 +0000 (18:08 +0000)
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

sys/kern/kern_rctl.c
sys/sys/racct.h

index c43b83df433a65fe0404b5451ad045e18b6097d0..34ad055c01d518b4185b2a87d79700e6bf6c34fb 100644 (file)
@@ -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);
index 313d5d05de96a96eb7d76f06795ea7bb24a89d97..307585680ca065080886a7e68c0ba918cbb38386 100644 (file)
 #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);