summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2016-10-27 03:00:36 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2016-10-27 03:00:36 +0000
commitd8387b6837f7832fe3fa9fd6158994b6d0ef16f9 (patch)
treeb0a9ff793749e2a273aaecc7e3a7f0f4e6f557b6 /sys/kern
parentc3ec7559ddf5301cc2e4c3703b0d1b345c476545 (diff)
add a new pool for 2k + 2 byte (mcl2k2) clusters.
a certain vendor likes to make chips that specify the rx buffer sizes in kilobyte increments. unfortunately it places the ethernet header on the start of the rx buffer, which means if you give it a mcl2k cluster, the ethernet header will not be ETHER_ALIGNed cos mcl2k clusters are always allocated on 2k boundarys (cos they pack into pages well). that in turn means the ip header wont be aligned correctly. the current workaround on these chips has been to let non-strict alignment archs just use the normal 2k cluster, but use whatever cluster can fit 2k + 2 on strict archs. that turns out to be the 4k cluster, meaning we waste nearly 2k of space on every packet. properly aligning the ethernet header and ip headers gives a performance boost, even on non-strict archs.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/uipc_mbuf.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index a6e46b5f2f8..e0ba9457212 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_mbuf.c,v 1.235 2016/10/24 23:58:33 dlg Exp $ */
+/* $OpenBSD: uipc_mbuf.c,v 1.236 2016/10/27 03:00:35 dlg Exp $ */
/* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */
/*
@@ -110,6 +110,7 @@ struct pool mtagpool;
/* mbuf cluster pools */
u_int mclsizes[MCLPOOLS] = {
MCLBYTES, /* must be at slot 0 */
+ MCLBYTES + 2, /* ETHER_ALIGNED 2k mbufs */
4 * 1024,
8 * 1024,
9 * 1024,
@@ -145,6 +146,7 @@ void
mbinit(void)
{
int i;
+ unsigned int lowbits;
#if DIAGNOSTIC
if (mclsizes[0] != MCLBYTES)
@@ -161,9 +163,15 @@ mbinit(void)
IPL_NET, 0, "mtagpl", NULL);
for (i = 0; i < nitems(mclsizes); i++) {
- snprintf(mclnames[i], sizeof(mclnames[0]), "mcl%dk",
- mclsizes[i] >> 10);
- pool_init(&mclpools[i], mclsizes[i], 0, IPL_NET, 0,
+ lowbits = mclsizes[i] & ((1 << 10) - 1);
+ if (lowbits) {
+ snprintf(mclnames[i], sizeof(mclnames[0]),
+ "mcl%dk%u", mclsizes[i] >> 10, lowbits);
+ } else {
+ snprintf(mclnames[i], sizeof(mclnames[0]), "mcl%dk",
+ mclsizes[i] >> 10);
+ }
+ pool_init(&mclpools[i], mclsizes[i], 64, IPL_NET, 0,
mclnames[i], NULL);
pool_set_constraints(&mclpools[i], &kp_dma_contig);
pool_setlowat(&mclpools[i], mcllowat);