diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2009-01-27 09:17:52 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2009-01-27 09:17:52 +0000 |
commit | 3a88b0b36d678797ab770bbfcdadaed66cddf81f (patch) | |
tree | 468df1061e828b2f91bcd07036116ee6e0f61293 /sys | |
parent | d04fc03bc9900852eb4b3e5bbc797baecab62f9b (diff) |
make drivers tell the mclgeti allocator what their maximum ring size is
to prevent the hwm growing beyond that. this allows the livelock mitigation
to do something where the hwm used to grow beyond twice the rx rings size.
ok kettenis@ claudio@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ic/gem.c | 4 | ||||
-rw-r--r-- | sys/dev/pci/if_bge.c | 7 | ||||
-rw-r--r-- | sys/dev/pci/if_em.c | 4 | ||||
-rw-r--r-- | sys/kern/uipc_mbuf.c | 79 | ||||
-rw-r--r-- | sys/net/if.h | 4 | ||||
-rw-r--r-- | sys/sys/mbuf.h | 4 |
6 files changed, 59 insertions, 43 deletions
diff --git a/sys/dev/ic/gem.c b/sys/dev/ic/gem.c index c81f1f3319f..fe730c16d5a 100644 --- a/sys/dev/ic/gem.c +++ b/sys/dev/ic/gem.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gem.c,v 1.86 2008/12/14 21:31:50 kettenis Exp $ */ +/* $OpenBSD: gem.c,v 1.87 2009/01/27 09:17:51 dlg Exp $ */ /* $NetBSD: gem.c,v 1.1 2001/09/16 00:11:43 eeh Exp $ */ /* @@ -229,7 +229,7 @@ gem_config(struct gem_softc *sc) IFQ_SET_READY(&ifp->if_snd); /* Hardware reads RX descriptors in multiples of four. */ - m_clsetlwm(ifp, MCLBYTES, 4); + m_clsetwms(ifp, MCLBYTES, 4, GEM_NRXDESC - 4); ifp->if_capabilities = IFCAP_VLAN_MTU; diff --git a/sys/dev/pci/if_bge.c b/sys/dev/pci/if_bge.c index 2f8940e07ab..d045941fff1 100644 --- a/sys/dev/pci/if_bge.c +++ b/sys/dev/pci/if_bge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bge.c,v 1.260 2008/12/23 00:14:18 dlg Exp $ */ +/* $OpenBSD: if_bge.c,v 1.261 2009/01/27 09:17:51 dlg Exp $ */ /* * Copyright (c) 2001 Wind River Systems @@ -2136,7 +2136,10 @@ bge_attach(struct device *parent, struct device *self, void *aux) ifp->if_watchdog = bge_watchdog; IFQ_SET_MAXLEN(&ifp->if_snd, BGE_TX_RING_CNT - 1); IFQ_SET_READY(&ifp->if_snd); - m_clsetlwm(ifp, MCLBYTES, 17); /* must be > replenish threshold */ + + /* lwm must be greater than the replenish threshold */ + m_clsetwms(ifp, MCLBYTES, 17, BGE_STD_RX_RING_CNT); + DPRINTFN(5, ("bcopy\n")); bcopy(sc->bge_dev.dv_xname, ifp->if_xname, IFNAMSIZ); diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c index d83e3471a9e..a74b85592e0 100644 --- a/sys/dev/pci/if_em.c +++ b/sys/dev/pci/if_em.c @@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ -/* $OpenBSD: if_em.c,v 1.206 2008/12/23 07:40:31 dlg Exp $ */ +/* $OpenBSD: if_em.c,v 1.207 2009/01/27 09:17:51 dlg Exp $ */ /* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */ #include <dev/pci/if_em.h> @@ -1733,6 +1733,8 @@ em_setup_interface(struct em_softc *sc) IFQ_SET_MAXLEN(&ifp->if_snd, sc->num_tx_desc - 1); IFQ_SET_READY(&ifp->if_snd); + m_clsetwms(ifp, MCLBYTES, 4, sc->num_rx_desc); + ifp->if_capabilities = IFCAP_VLAN_MTU; #if NVLAN > 0 diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 6ce7b34f0ac..cf1778038fa 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_mbuf.c,v 1.115 2009/01/26 15:16:39 claudio Exp $ */ +/* $OpenBSD: uipc_mbuf.c,v 1.116 2009/01/27 09:17:51 dlg Exp $ */ /* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */ /* @@ -108,6 +108,8 @@ u_int mclsizes[] = { static char mclnames[MCLPOOLS][8]; struct pool mclpools[MCLPOOLS]; +int m_clpool(u_int); + int max_linkhdr; /* largest link-level header */ int max_protohdr; /* largest protocol header */ int max_hdr; /* largest link+protocol header */ @@ -271,36 +273,49 @@ m_getclr(int nowait, int type) return (m); } +int +m_clpool(u_int pktlen) +{ + int pi; + + for (pi = 0; pi < MCLPOOLS; pi++) { + if (pktlen <= mclsizes[pi]) + return (pi); + } + + return (-1); +} + void m_clinitifp(struct ifnet *ifp) { struct mclpool *mclp = ifp->if_data.ifi_mclpool; - extern u_int mclsizes[]; int i; /* Initialize high water marks for use of cluster pools */ for (i = 0; i < MCLPOOLS; i++) { - if (mclp[i].mcl_lwm == 0) - mclp[i].mcl_lwm = 2; - mclp[i].mcl_hwm = MAX(4, mclp[i].mcl_lwm); - mclp[i].mcl_size = mclsizes[i]; + mclp = &ifp->if_data.ifi_mclpool[i]; + + if (mclp->mcl_lwm == 0) + mclp->mcl_lwm = 2; + if (mclp->mcl_hwm == 0) + mclp->mcl_hwm = 32768; + + mclp->mcl_cwm = MAX(4, mclp->mcl_lwm); } } void -m_clsetlwm(struct ifnet *ifp, u_int pktlen, u_int lwm) +m_clsetwms(struct ifnet *ifp, u_int pktlen, u_int lwm, u_int hwm) { - extern u_int mclsizes[]; - int i; + int pi; - for (i = 0; i < MCLPOOLS; i++) { - if (pktlen <= mclsizes[i]) - break; - } - if (i >= MCLPOOLS) + pi = m_clpool(pktlen); + if (pi == -1) return; - ifp->if_data.ifi_mclpool[i].mcl_lwm = lwm; + ifp->if_data.ifi_mclpool[pi].mcl_lwm = lwm; + ifp->if_data.ifi_mclpool[pi].mcl_hwm = hwm; } extern int m_clticks; @@ -328,19 +343,20 @@ m_cldrop(struct ifnet *ifp, int pi) liveticks = ticks; TAILQ_FOREACH(aifp, &ifnet, if_list) { mclp = aifp->if_data.ifi_mclpool; - for (i = 0; i < nitems(aifp->if_data.ifi_mclpool); i++) - mclp[i].mcl_hwm = - max(mclp[i].mcl_hwm / 2, mclp[i].mcl_lwm); + for (i = 0; i < MCLPOOLS; i++) { + mclp[i].mcl_cwm = + max(mclp[i].mcl_cwm / 2, mclp[i].mcl_lwm); + } } } else if (m_livelock && ticks - liveticks > 5) m_livelock = 0; /* Let the high water marks grow again */ - mclp = ifp->if_data.ifi_mclpool; - if (mclp[pi].mcl_alive <= 2 && mclp[pi].mcl_hwm < 32768 && - ISSET(ifp->if_flags, IFF_RUNNING) && m_livelock == 0) { - /* About to run out, so increase the watermark */ - mclp[pi].mcl_hwm++; - } else if (mclp[pi].mcl_alive >= mclp[pi].mcl_hwm) + mclp = &ifp->if_data.ifi_mclpool[pi]; + if (m_livelock == 0 && ISSET(ifp->if_flags, IFF_RUNNING) && + mclp->mcl_alive <= 2 && mclp->mcl_cwm < mclp->mcl_hwm) { + /* About to run out, so increase the current watermark */ + mclp->mcl_cwm++; + } else if (mclp->mcl_alive >= mclp->mcl_cwm) return (1); /* No more packets given */ return (0); @@ -371,18 +387,12 @@ m_cluncount(struct mbuf *m, int all) void m_clget(struct mbuf *m, int how, struct ifnet *ifp, u_int pktlen) { - struct pool *mclp; int pi; int s; - for (pi = 0; pi < nitems(mclpools); pi++) { - mclp = &mclpools[pi]; - if (pktlen <= mclp->pr_size) - break; - } - + pi = m_clpool(pktlen); #ifdef DIAGNOSTIC - if (mclp == NULL) + if (pi == -1) panic("m_clget: request for %d sized cluster", pktlen); #endif @@ -390,12 +400,13 @@ m_clget(struct mbuf *m, int how, struct ifnet *ifp, u_int pktlen) return; s = splnet(); - m->m_ext.ext_buf = pool_get(mclp, how == M_WAIT ? PR_WAITOK : 0); + m->m_ext.ext_buf = pool_get(&mclpools[pi], + how == M_WAIT ? PR_WAITOK : 0); splx(s); if (m->m_ext.ext_buf != NULL) { m->m_data = m->m_ext.ext_buf; m->m_flags |= M_EXT|M_CLUSTER; - m->m_ext.ext_size = mclp->pr_size; + m->m_ext.ext_size = mclpools[pi].pr_size; m->m_ext.ext_free = NULL; m->m_ext.ext_arg = NULL; diff --git a/sys/net/if.h b/sys/net/if.h index ab6df1ab27f..18e3fd153c8 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if.h,v 1.102 2008/12/12 22:07:33 claudio Exp $ */ +/* $OpenBSD: if.h,v 1.103 2009/01/27 09:17:51 dlg Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -109,7 +109,7 @@ struct if_clonereq { struct mclpool { u_short mcl_alive; u_short mcl_hwm; - u_short mcl_size; + u_short mcl_cwm; u_short mcl_lwm; }; diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index 26957adabc3..2a6420be5b9 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mbuf.h,v 1.120 2008/12/23 01:06:33 deraadt Exp $ */ +/* $OpenBSD: mbuf.h,v 1.121 2009/01/27 09:17:51 dlg Exp $ */ /* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */ /* @@ -428,7 +428,7 @@ struct mbuf *m_getptr(struct mbuf *, int, int *); int m_leadingspace(struct mbuf *); int m_trailingspace(struct mbuf *); void m_clget(struct mbuf *, int, struct ifnet *, u_int); -void m_clsetlwm(struct ifnet *, u_int, u_int); +void m_clsetwms(struct ifnet *, u_int, u_int, u_int); int m_cldrop(struct ifnet *, int); void m_clcount(struct ifnet *, int); void m_cluncount(struct mbuf *, int); |