summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_sockbuf.c
diff options
context:
space:
mode:
authordg <dg@FreeBSD.org>2002-08-16 18:41:48 +0000
committerdg <dg@FreeBSD.org>2002-08-16 18:41:48 +0000
commit343fb296315858459bcd2a8d790079774342dbb8 (patch)
treeef7c526a360a0989d16408f363f561f2871c9af6 /sys/kern/uipc_sockbuf.c
parent1f81bb02827618b06d201044121aa1fe55867eef (diff)
downloadFreeBSD-src-343fb296315858459bcd2a8d790079774342dbb8.zip
FreeBSD-src-343fb296315858459bcd2a8d790079774342dbb8.tar.gz
Further improved the performance of sbreserve() by moving the calculation
of the adjusted sb_max into a sysctl handler for sb_max and assigning it to a variable that is used instead. This eliminates the 32bit multiply and divide from the fast path that was being done previously.
Diffstat (limited to 'sys/kern/uipc_sockbuf.c')
-rw-r--r--sys/kern/uipc_sockbuf.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 5995b06..f062b2d 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -66,7 +66,9 @@ void (*aio_swake)(struct socket *, struct sockbuf *);
* Primitive routines for operating on sockets and socket buffers
*/
-u_long sb_max = SB_MAX; /* XXX should be static */
+u_long sb_max = SB_MAX;
+u_long sb_max_adj =
+ SB_MAX * MCLBYTES / (MSIZE + MCLBYTES); /* adjusted sb_max */
static u_long sb_efficiency = 8; /* parameter for sbreserve() */
@@ -375,6 +377,26 @@ bad:
return (ENOBUFS);
}
+static int
+sysctl_handle_sb_max(SYSCTL_HANDLER_ARGS)
+{
+ int error = 0;
+ u_long old_sb_max = sb_max;
+
+ error = SYSCTL_OUT(req, arg1, sizeof(int));
+ if (error || !req->newptr)
+ return (error);
+ error = SYSCTL_IN(req, arg1, sizeof(int));
+ if (error)
+ return (error);
+ if (sb_max < MSIZE + MCLBYTES) {
+ sb_max = old_sb_max;
+ return (EINVAL);
+ }
+ sb_max_adj = (u_quad_t)sb_max * MCLBYTES / (MSIZE + MCLBYTES);
+ return (0);
+}
+
/*
* Allot mbufs to a sockbuf.
* Attempt to scale mbmax so that mbcnt doesn't become limiting
@@ -392,7 +414,7 @@ sbreserve(sb, cc, so, td)
* td will only be NULL when we're in an interrupt
* (e.g. in tcp_input())
*/
- if (cc > sb_max / (MSIZE + MCLBYTES) * MCLBYTES)
+ if (cc > sb_max_adj)
return (0);
if (!chgsbsize(so->so_cred->cr_uidinfo, &sb->sb_hiwat, cc,
td ? td->td_proc->p_rlimit[RLIMIT_SBSIZE].rlim_cur : RLIM_INFINITY)) {
@@ -971,9 +993,8 @@ SYSCTL_NODE(_kern, KERN_IPC, ipc, CTLFLAG_RW, 0, "IPC");
/* This takes the place of kern.maxsockbuf, which moved to kern.ipc. */
static int dummy;
SYSCTL_INT(_kern, KERN_DUMMY, dummy, CTLFLAG_RW, &dummy, 0, "");
-
-SYSCTL_INT(_kern_ipc, KIPC_MAXSOCKBUF, maxsockbuf, CTLFLAG_RW,
- &sb_max, 0, "Maximum socket buffer size");
+SYSCTL_OID(_kern_ipc, KIPC_MAXSOCKBUF, maxsockbuf, CTLTYPE_INT|CTLFLAG_RW,
+ &sb_max, 0, sysctl_handle_sb_max, "I", "Maximum socket buffer size");
SYSCTL_INT(_kern_ipc, OID_AUTO, maxsockets, CTLFLAG_RD,
&maxsockets, 0, "Maximum number of sockets avaliable");
SYSCTL_INT(_kern_ipc, KIPC_SOCKBUF_WASTE, sockbuf_waste_factor, CTLFLAG_RW,
OpenPOWER on IntegriCloud