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.
This commit is contained in:
David Greenman 2002-08-16 18:41:48 +00:00
parent 2cd998a25d
commit 79cb7eb41c
2 changed files with 52 additions and 10 deletions

View File

@ -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 @@ soreserve(so, sndcc, rcvcc)
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,

View File

@ -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 @@ soreserve(so, sndcc, rcvcc)
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,