Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 8 Nov 2015 18:08:31 +0000 (UTC)
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r290551 - in head/sys: kern sys
Message-ID:  <201511081808.tA8I8VjR050168@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trasz
Date: Sun Nov  8 18:08:31 2015
New Revision: 290551
URL: https://svnweb.freebsd.org/changeset/base/290551

Log:
  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

Modified:
  head/sys/kern/kern_rctl.c
  head/sys/sys/racct.h

Modified: head/sys/kern/kern_rctl.c
==============================================================================
--- head/sys/kern/kern_rctl.c	Sun Nov  8 18:02:39 2015	(r290550)
+++ head/sys/kern/kern_rctl.c	Sun Nov  8 18:08:31 2015	(r290551)
@@ -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, st
 		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, s
 		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);

Modified: head/sys/sys/racct.h
==============================================================================
--- head/sys/sys/racct.h	Sun Nov  8 18:02:39 2015	(r290550)
+++ head/sys/sys/racct.h	Sun Nov  8 18:08:31 2015	(r290551)
@@ -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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201511081808.tA8I8VjR050168>