summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/socppc/dev/if_tsec.c20
-rw-r--r--sys/dev/ic/gem.c23
-rw-r--r--sys/dev/ic/gemvar.h5
-rw-r--r--sys/dev/ic/hme.c22
-rw-r--r--sys/dev/ic/hmevar.h5
-rw-r--r--sys/dev/ic/re.c20
-rw-r--r--sys/dev/ic/rtl81x9reg.h4
-rw-r--r--sys/dev/ic/xl.c18
-rw-r--r--sys/dev/ic/xlreg.h4
-rw-r--r--sys/dev/pci/if_bge.c88
-rw-r--r--sys/dev/pci/if_bgereg.h6
-rw-r--r--sys/dev/pci/if_bnx.c60
-rw-r--r--sys/dev/pci/if_bnxreg.h4
-rw-r--r--sys/dev/pci/if_em.c45
-rw-r--r--sys/dev/pci/if_em.h4
-rw-r--r--sys/dev/pci/if_ix.c31
-rw-r--r--sys/dev/pci/if_ix.h4
-rw-r--r--sys/dev/pci/if_msk.c40
-rw-r--r--sys/dev/pci/if_mskvar.h8
-rw-r--r--sys/dev/pci/if_myx.c62
-rw-r--r--sys/dev/pci/if_oce.c36
-rw-r--r--sys/dev/pci/if_sis.c20
-rw-r--r--sys/dev/pci/if_sisreg.h4
-rw-r--r--sys/dev/pci/if_vic.c27
-rw-r--r--sys/dev/pci/if_vio.c20
-rw-r--r--sys/dev/pci/if_vmx.c24
-rw-r--r--sys/dev/pci/if_vr.c30
-rw-r--r--sys/dev/pci/if_vrreg.h4
-rw-r--r--sys/kern/uipc_mbuf.c6
-rw-r--r--usr.bin/systat/mbufs.c175
30 files changed, 474 insertions, 345 deletions
diff --git a/sys/arch/socppc/dev/if_tsec.c b/sys/arch/socppc/dev/if_tsec.c
index 4c18c31c489..2f3cb628d34 100644
--- a/sys/arch/socppc/dev/if_tsec.c
+++ b/sys/arch/socppc/dev/if_tsec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tsec.c,v 1.29 2012/11/29 21:10:31 brad Exp $ */
+/* $OpenBSD: if_tsec.c,v 1.30 2014/07/08 05:35:18 dlg Exp $ */
/*
* Copyright (c) 2008 Mark Kettenis
@@ -267,7 +267,7 @@ struct tsec_softc {
struct tsec_buf *sc_rxbuf;
struct tsec_desc *sc_rxdesc;
int sc_rx_prod;
- int sc_rx_cnt;
+ struct if_rxring sc_rx_ring;
int sc_rx_cons;
struct timeout sc_tick;
@@ -417,8 +417,6 @@ tsec_attach(struct device *parent, struct device *self, void *aux)
IFQ_SET_READY(&ifp->if_snd);
bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
- m_clsetwms(ifp, MCLBYTES, 0, TSEC_NRXDESC);
-
ifp->if_capabilities = IFCAP_VLAN_MTU;
sc->sc_mii.mii_ifp = ifp;
@@ -849,7 +847,7 @@ tsec_rx_proc(struct tsec_softc *sc)
TSEC_DMA_LEN(sc->sc_rxring),
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- while (sc->sc_rx_cnt > 0) {
+ while (if_rxr_inuse(&sc->sc_rx_ring) > 0) {
idx = sc->sc_rx_cons;
KASSERT(idx < TSEC_NRXDESC);
@@ -883,7 +881,7 @@ tsec_rx_proc(struct tsec_softc *sc)
ether_input_mbuf(ifp, m);
- sc->sc_rx_cnt--;
+ if_rxr_put(&sc->sc_rx_ring, 1);
if (rxd->td_status & TSEC_RX_W)
sc->sc_rx_cons = 0;
else
@@ -954,8 +952,8 @@ tsec_up(struct tsec_softc *sc)
0, TSEC_DMA_LEN(sc->sc_rxring), BUS_DMASYNC_PREWRITE);
sc->sc_rx_prod = sc->sc_rx_cons = 0;
- sc->sc_rx_cnt = 0;
+ if_rxr_init(&sc->sc_rx_ring, 2, TSEC_NRXDESC);
tsec_fill_rx_ring(sc);
tsec_write(sc, TSEC_MRBLR, MCLBYTES);
@@ -1279,7 +1277,7 @@ tsec_alloc_mbuf(struct tsec_softc *sc, bus_dmamap_t map)
{
struct mbuf *m = NULL;
- m = MCLGETI(NULL, M_DONTWAIT, &sc->sc_ac.ac_if, MCLBYTES);
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
if (!m)
return (NULL);
m->m_len = m->m_pkthdr.len = MCLBYTES;
@@ -1301,8 +1299,10 @@ tsec_fill_rx_ring(struct tsec_softc *sc)
{
struct tsec_desc *rxd;
struct tsec_buf *rxb;
+ u_int slots;
- while (sc->sc_rx_cnt < TSEC_NRXDESC) {
+ for (slots = if_rxr_get(&sc->sc_rx_ring, TSEC_NRXDESC);
+ slots > 0; slots--) {
rxb = &sc->sc_rxbuf[sc->sc_rx_prod];
rxb->tb_m = tsec_alloc_mbuf(sc, rxb->tb_map);
if (rxb->tb_m == NULL)
@@ -1314,10 +1314,10 @@ tsec_fill_rx_ring(struct tsec_softc *sc)
__asm volatile("eieio" ::: "memory");
rxd->td_status |= TSEC_RX_E | TSEC_RX_I;
- sc->sc_rx_cnt++;
if (rxd->td_status & TSEC_RX_W)
sc->sc_rx_prod = 0;
else
sc->sc_rx_prod++;
}
+ if_rxr_put(&sc->sc_rx_ring, slots);
}
diff --git a/sys/dev/ic/gem.c b/sys/dev/ic/gem.c
index 8d3e84cdb55..d3d654bb9b8 100644
--- a/sys/dev/ic/gem.c
+++ b/sys/dev/ic/gem.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gem.c,v 1.103 2014/04/22 15:52:05 naddy Exp $ */
+/* $OpenBSD: gem.c,v 1.104 2014/07/08 05:35:18 dlg Exp $ */
/* $NetBSD: gem.c,v 1.1 2001/09/16 00:11:43 eeh Exp $ */
/*
@@ -231,9 +231,6 @@ gem_config(struct gem_softc *sc)
IFQ_SET_MAXLEN(&ifp->if_snd, GEM_NTXDESC - 1);
IFQ_SET_READY(&ifp->if_snd);
- /* Hardware reads RX descriptors in multiples of four. */
- m_clsetwms(ifp, MCLBYTES, 4, GEM_NRXDESC - 4);
-
ifp->if_capabilities = IFCAP_VLAN_MTU;
/* Initialize ifmedia structures and MII info */
@@ -520,7 +517,7 @@ gem_rxdrain(struct gem_softc *sc)
rxs->rxs_mbuf = NULL;
}
}
- sc->sc_rx_prod = sc->sc_rx_cons = sc->sc_rx_cnt = 0;
+ sc->sc_rx_prod = sc->sc_rx_cons = 0;
}
/*
@@ -697,6 +694,8 @@ gem_meminit(struct gem_softc *sc)
sc->sc_rxdescs[i].gd_flags = 0;
sc->sc_rxdescs[i].gd_addr = 0;
}
+ /* Hardware reads RX descriptors in multiples of four. */
+ if_rxr_init(&sc->sc_rx_ring, 4, GEM_NRXDESC - 4);
gem_fill_rx_ring(sc);
return (0);
@@ -957,7 +956,8 @@ gem_rint(struct gem_softc *sc)
u_int64_t rxstat;
int i, len;
- for (i = sc->sc_rx_cons; sc->sc_rx_cnt > 0; i = GEM_NEXTRX(i)) {
+ for (i = sc->sc_rx_cons; if_rxr_inuse(&sc->sc_rx_ring) > 0;
+ i = GEM_NEXTRX(i)) {
rxs = &sc->sc_rxsoft[i];
GEM_CDRXSYNC(sc, i,
@@ -977,7 +977,7 @@ gem_rint(struct gem_softc *sc)
m = rxs->rxs_mbuf;
rxs->rxs_mbuf = NULL;
- sc->sc_rx_cnt--;
+ if_rxr_put(&sc->sc_rx_ring, 1);
if (rxstat & GEM_RD_BAD_CRC) {
ifp->if_ierrors++;
@@ -1031,10 +1031,14 @@ gem_rint(struct gem_softc *sc)
void
gem_fill_rx_ring(struct gem_softc *sc)
{
- while (sc->sc_rx_cnt < (GEM_NRXDESC - 4)) {
+ u_int slots;
+
+ for (slots = if_rxr_get(&sc->sc_rx_ring, GEM_NRXDESC - 4);
+ slots > 0; slots--) {
if (gem_add_rxbuf(sc, sc->sc_rx_prod))
break;
}
+ if_rxr_put(&sc->sc_rx_ring, slots);
}
/*
@@ -1047,7 +1051,7 @@ gem_add_rxbuf(struct gem_softc *sc, int idx)
struct mbuf *m;
int error;
- m = MCLGETI(NULL, M_DONTWAIT, &sc->sc_arpcom.ac_if, MCLBYTES);
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
if (!m)
return (ENOBUFS);
m->m_len = m->m_pkthdr.len = MCLBYTES;
@@ -1073,7 +1077,6 @@ gem_add_rxbuf(struct gem_softc *sc, int idx)
GEM_INIT_RXDESC(sc, idx);
sc->sc_rx_prod = GEM_NEXTRX(sc->sc_rx_prod);
- sc->sc_rx_cnt++;
return (0);
}
diff --git a/sys/dev/ic/gemvar.h b/sys/dev/ic/gemvar.h
index 12fc0ae897d..26044cddc3f 100644
--- a/sys/dev/ic/gemvar.h
+++ b/sys/dev/ic/gemvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: gemvar.h,v 1.28 2014/03/14 11:04:24 dlg Exp $ */
+/* $OpenBSD: gemvar.h,v 1.29 2014/07/08 05:35:18 dlg Exp $ */
/* $NetBSD: gemvar.h,v 1.1 2001/09/16 00:11:43 eeh Exp $ */
/*
@@ -176,7 +176,8 @@ struct gem_softc {
u_int32_t sc_tx_cnt, sc_tx_prod, sc_tx_cons;
struct gem_rxsoft sc_rxsoft[GEM_NRXDESC];
- u_int32_t sc_rx_cnt, sc_rx_prod, sc_rx_cons;
+ struct if_rxring sc_rx_ring;
+ u_int32_t sc_rx_prod, sc_rx_cons;
/*
* Control data structures.
diff --git a/sys/dev/ic/hme.c b/sys/dev/ic/hme.c
index 8d272989c71..e235987a082 100644
--- a/sys/dev/ic/hme.c
+++ b/sys/dev/ic/hme.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hme.c,v 1.65 2014/06/17 02:48:30 dlg Exp $ */
+/* $OpenBSD: hme.c,v 1.66 2014/07/08 05:35:18 dlg Exp $ */
/* $NetBSD: hme.c,v 1.21 2001/07/07 15:59:37 thorpej Exp $ */
/*-
@@ -227,8 +227,6 @@ hme_config(struct hme_softc *sc)
IFQ_SET_READY(&ifp->if_snd);
ifp->if_capabilities = IFCAP_VLAN_MTU;
- m_clsetwms(ifp, MCLBYTES, 0, HME_RX_RING_SIZE);
-
/* Initialize ifmedia structures and MII info */
mii->mii_ifp = ifp;
mii->mii_readreg = hme_mii_readreg;
@@ -360,7 +358,7 @@ hme_tick(void *arg)
* If buffer allocation fails, the receive ring may become
* empty. There is no receive interrupt to recover from that.
*/
- if (sc->sc_rx_cnt == 0)
+ if (if_rxr_inuse(&sc->sc_rx_ring) == 0)
hme_fill_rx_ring(sc);
mii_tick(&sc->sc_mii);
@@ -437,7 +435,7 @@ hme_stop(struct hme_softc *sc, int softonly)
sc->sc_rxd[n].sd_mbuf = NULL;
}
}
- sc->sc_rx_prod = sc->sc_rx_cons = sc->sc_rx_cnt = 0;
+ sc->sc_rx_prod = sc->sc_rx_cons = 0;
}
void
@@ -491,6 +489,7 @@ hme_meminit(struct hme_softc *sc)
sc->sc_rxd[i].sd_mbuf = NULL;
}
+ if_rxr_init(&sc->sc_rx_ring, 2, HME_RX_RING_SIZE);
hme_fill_rx_ring(sc);
}
@@ -834,7 +833,7 @@ hme_rint(struct hme_softc *sc)
/*
* Process all buffers with valid data.
*/
- while (sc->sc_rx_cnt > 0) {
+ while (if_rxr_inuse(&sc->sc_rx_ring) > 0) {
flags = HME_XD_GETFLAGS(sc->sc_pci, sc->sc_rb.rb_rxd, ri);
if (flags & HME_XD_OWN)
break;
@@ -851,7 +850,8 @@ hme_rint(struct hme_softc *sc)
sd = sc->sc_rxd;
} else
sd++;
- sc->sc_rx_cnt--;
+
+ if_rxr_put(&sc->sc_rx_ring, 1);
if (flags & HME_XD_OFL) {
ifp->if_ierrors++;
@@ -1281,8 +1281,10 @@ void
hme_fill_rx_ring(struct hme_softc *sc)
{
struct hme_sxd *sd;
+ u_int slots;
- while (sc->sc_rx_cnt < HME_RX_RING_SIZE) {
+ for (slots = if_rxr_get(&sc->sc_rx_ring, HME_RX_RING_SIZE);
+ slots > 0; slots--) {
if (hme_newbuf(sc, &sc->sc_rxd[sc->sc_rx_prod]))
break;
@@ -1294,8 +1296,8 @@ hme_fill_rx_ring(struct hme_softc *sc)
if (++sc->sc_rx_prod == HME_RX_RING_SIZE)
sc->sc_rx_prod = 0;
- sc->sc_rx_cnt++;
}
+ if_rxr_put(&sc->sc_rx_ring, slots);
}
int
@@ -1309,7 +1311,7 @@ hme_newbuf(struct hme_softc *sc, struct hme_sxd *d)
* until we're sure everything is a success.
*/
- m = MCLGETI(NULL, M_DONTWAIT, &sc->sc_arpcom.ac_if, MCLBYTES);
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
if (!m)
return (ENOBUFS);
m->m_pkthdr.rcvif = &sc->sc_arpcom.ac_if;
diff --git a/sys/dev/ic/hmevar.h b/sys/dev/ic/hmevar.h
index 1f9c3308bb5..f9a3571c392 100644
--- a/sys/dev/ic/hmevar.h
+++ b/sys/dev/ic/hmevar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hmevar.h,v 1.15 2009/10/15 17:54:54 deraadt Exp $ */
+/* $OpenBSD: hmevar.h,v 1.16 2014/07/08 05:35:18 dlg Exp $ */
/* $NetBSD: hmevar.h,v 1.6 2000/09/28 10:56:57 tsutsui Exp $ */
/*-
@@ -87,7 +87,8 @@ struct hme_softc {
struct hme_sxd sc_txd[HME_TX_RING_MAX], sc_rxd[HME_RX_RING_MAX];
bus_dmamap_t sc_rxmap_spare;
int sc_tx_cnt, sc_tx_prod, sc_tx_cons;
- int sc_rx_cnt, sc_rx_prod, sc_rx_cons;
+ struct if_rxring sc_rx_ring;
+ int sc_rx_prod, sc_rx_cons;
u_int32_t sc_tcvr;
};
diff --git a/sys/dev/ic/re.c b/sys/dev/ic/re.c
index 2d583865247..abf81f47950 100644
--- a/sys/dev/ic/re.c
+++ b/sys/dev/ic/re.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: re.c,v 1.153 2014/04/23 03:37:29 jsg Exp $ */
+/* $OpenBSD: re.c,v 1.154 2014/07/08 05:35:18 dlg Exp $ */
/* $FreeBSD: if_re.c,v 1.31 2004/09/04 07:54:05 ru Exp $ */
/*
* Copyright (c) 1997, 1998-2003
@@ -964,8 +964,6 @@ re_attach(struct rl_softc *sc, const char *intrstr)
IFQ_SET_MAXLEN(&ifp->if_snd, RL_TX_QLEN);
IFQ_SET_READY(&ifp->if_snd);
- m_clsetwms(ifp, MCLBYTES, 2, RL_RX_DESC_CNT);
-
ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_CSUM_TCPv4 |
IFCAP_CSUM_UDPv4;
@@ -1083,7 +1081,7 @@ re_newbuf(struct rl_softc *sc)
u_int32_t cmdstat;
int error, idx;
- m = MCLGETI(NULL, M_DONTWAIT, &sc->sc_arpcom.ac_if, MCLBYTES);
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
if (!m)
return (ENOBUFS);
@@ -1133,7 +1131,6 @@ re_newbuf(struct rl_softc *sc)
RL_RXDESCSYNC(sc, idx, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
sc->rl_ldata.rl_rx_prodidx = RL_NEXT_RX_DESC(sc, idx);
- sc->rl_ldata.rl_rx_cnt++;
return (0);
}
@@ -1168,9 +1165,9 @@ re_rx_list_init(struct rl_softc *sc)
sc->rl_ldata.rl_rx_prodidx = 0;
sc->rl_ldata.rl_rx_considx = 0;
- sc->rl_ldata.rl_rx_cnt = 0;
sc->rl_head = sc->rl_tail = NULL;
+ if_rxr_init(&sc->rl_ldata.rl_rx_ring, 2, RL_RX_DESC_CNT);
re_rx_list_fill(sc);
return (0);
@@ -1179,10 +1176,14 @@ re_rx_list_init(struct rl_softc *sc)
void
re_rx_list_fill(struct rl_softc *sc)
{
- while (sc->rl_ldata.rl_rx_cnt < RL_RX_DESC_CNT) {
+ u_int slots;
+
+ for (slots = if_rxr_get(&sc->rl_ldata.rl_rx_ring, RL_RX_DESC_CNT);
+ slots > 0; slots--) {
if (re_newbuf(sc) == ENOBUFS)
break;
}
+ if_rxr_put(&sc->rl_ldata.rl_rx_ring, slots);
}
/*
@@ -1202,7 +1203,8 @@ re_rxeof(struct rl_softc *sc)
ifp = &sc->sc_arpcom.ac_if;
- for (i = sc->rl_ldata.rl_rx_considx; sc->rl_ldata.rl_rx_cnt > 0;
+ for (i = sc->rl_ldata.rl_rx_considx;
+ if_rxr_inuse(&sc->rl_ldata.rl_rx_ring) > 0;
i = RL_NEXT_RX_DESC(sc, i)) {
cur_rx = &sc->rl_ldata.rl_rx_list[i];
RL_RXDESCSYNC(sc, i,
@@ -1216,7 +1218,7 @@ re_rxeof(struct rl_softc *sc)
rxs = &sc->rl_ldata.rl_rxsoft[i];
m = rxs->rxs_mbuf;
rxs->rxs_mbuf = NULL;
- sc->rl_ldata.rl_rx_cnt--;
+ if_rxr_put(&sc->rl_ldata.rl_rx_ring, 1);
rx = 1;
/* Invalidate the RX mbuf and unload its map */
diff --git a/sys/dev/ic/rtl81x9reg.h b/sys/dev/ic/rtl81x9reg.h
index c0561ef06f0..e61e4e3d77b 100644
--- a/sys/dev/ic/rtl81x9reg.h
+++ b/sys/dev/ic/rtl81x9reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtl81x9reg.h,v 1.84 2014/04/23 03:37:29 jsg Exp $ */
+/* $OpenBSD: rtl81x9reg.h,v 1.85 2014/07/08 05:35:18 dlg Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -806,7 +806,7 @@ struct rl_list_data {
struct rl_desc *rl_rx_list;
int rl_rx_considx;
int rl_rx_prodidx;
- int rl_rx_cnt;
+ struct if_rxring rl_rx_ring;
bus_dma_segment_t rl_rx_listseg;
int rl_rx_listnseg;
};
diff --git a/sys/dev/ic/xl.c b/sys/dev/ic/xl.c
index 5926eb0769c..f28caf4f32c 100644
--- a/sys/dev/ic/xl.c
+++ b/sys/dev/ic/xl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xl.c,v 1.113 2014/05/30 19:51:22 chl Exp $ */
+/* $OpenBSD: xl.c,v 1.114 2014/07/08 05:35:18 dlg Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -1093,7 +1093,7 @@ xl_list_rx_init(struct xl_softc *sc)
}
cd->xl_rx_prod = cd->xl_rx_cons = &cd->xl_rx_chain[0];
- cd->xl_rx_cnt = 0;
+ if_rxr_init(&cd->xl_rx_ring, 2, XL_RX_LIST_CNT - 1);
xl_fill_rx_ring(sc);
return (0);
}
@@ -1102,15 +1102,17 @@ void
xl_fill_rx_ring(struct xl_softc *sc)
{
struct xl_chain_data *cd;
+ u_int slots;
cd = &sc->xl_cdata;
- while (cd->xl_rx_cnt < XL_RX_LIST_CNT) {
+ for (slots = if_rxr_get(&cd->xl_rx_ring, XL_RX_LIST_CNT);
+ slots > 0; slots--) {
if (xl_newbuf(sc, cd->xl_rx_prod) == ENOBUFS)
break;
cd->xl_rx_prod = cd->xl_rx_prod->xl_next;
- cd->xl_rx_cnt++;
}
+ if_rxr_put(&cd->xl_rx_ring, slots);
}
/*
@@ -1122,7 +1124,7 @@ xl_newbuf(struct xl_softc *sc, struct xl_chain_onefrag *c)
struct mbuf *m_new = NULL;
bus_dmamap_t map;
- m_new = MCLGETI(NULL, M_DONTWAIT, &sc->sc_arpcom.ac_if, MCLBYTES);
+ m_new = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
if (!m_new)
return (ENOBUFS);
@@ -1182,7 +1184,7 @@ xl_rxeof(struct xl_softc *sc)
again:
- while (sc->xl_cdata.xl_rx_cnt > 0) {
+ while (if_rxr_inuse(&sc->xl_cdata.xl_rx_ring) > 0) {
cur_rx = sc->xl_cdata.xl_rx_cons;
bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
((caddr_t)cur_rx->xl_ptr - sc->sc_listkva),
@@ -1193,7 +1195,7 @@ again:
m = cur_rx->xl_mbuf;
cur_rx->xl_mbuf = NULL;
sc->xl_cdata.xl_rx_cons = cur_rx->xl_next;
- sc->xl_cdata.xl_rx_cnt--;
+ if_rxr_put(&sc->xl_cdata.xl_rx_ring, 1);
total_len = rxstat & XL_RXSTAT_LENMASK;
/*
@@ -2511,8 +2513,6 @@ xl_attach(struct xl_softc *sc)
IFQ_SET_READY(&ifp->if_snd);
bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
- m_clsetwms(ifp, MCLBYTES, 2, XL_RX_LIST_CNT - 1);
-
ifp->if_capabilities = IFCAP_VLAN_MTU;
#ifndef XL905B_TXCSUM_BROKEN
diff --git a/sys/dev/ic/xlreg.h b/sys/dev/ic/xlreg.h
index 287cf88460f..9c0b5842247 100644
--- a/sys/dev/ic/xlreg.h
+++ b/sys/dev/ic/xlreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: xlreg.h,v 1.28 2011/10/13 13:07:13 kettenis Exp $ */
+/* $OpenBSD: xlreg.h,v 1.29 2014/07/08 05:35:18 dlg Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -488,7 +488,7 @@ struct xl_chain_data {
struct xl_chain_onefrag *xl_rx_cons;
struct xl_chain_onefrag *xl_rx_prod;
- int xl_rx_cnt;
+ struct if_rxring xl_rx_ring;
/* 3c90x "boomerang" queuing stuff */
struct xl_chain *xl_tx_head;
diff --git a/sys/dev/pci/if_bge.c b/sys/dev/pci/if_bge.c
index 3666964ab8b..d5806775977 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.355 2014/07/03 13:26:05 dlg Exp $ */
+/* $OpenBSD: if_bge.c,v 1.356 2014/07/08 05:35:18 dlg Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
@@ -151,6 +151,7 @@ int bge_compact_dma_runt(struct mbuf *);
int bge_intr(void *);
void bge_start(struct ifnet *);
int bge_ioctl(struct ifnet *, u_long, caddr_t);
+int bge_rxrinfo(struct bge_softc *, struct if_rxrinfo *);
void bge_init(void *);
void bge_stop_block(struct bge_softc *, bus_size_t, u_int32_t);
void bge_stop(struct bge_softc *);
@@ -1118,7 +1119,7 @@ bge_newbuf(struct bge_softc *sc, int i)
struct mbuf *m;
int error;
- m = MCLGETI(NULL, M_DONTWAIT, &sc->arpcom.ac_if, MCLBYTES);
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
if (!m)
return (ENOBUFS);
m->m_len = m->m_pkthdr.len = MCLBYTES;
@@ -1153,8 +1154,6 @@ bge_newbuf(struct bge_softc *sc, int i)
sizeof (struct bge_rx_bd),
BUS_DMASYNC_PREWRITE);
- sc->bge_std_cnt++;
-
return (0);
}
@@ -1169,7 +1168,7 @@ bge_newbuf_jumbo(struct bge_softc *sc, int i)
struct mbuf *m;
int error;
- m = MCLGETI(NULL, M_DONTWAIT, &sc->arpcom.ac_if, BGE_JLEN);
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, BGE_JLEN);
if (!m)
return (ENOBUFS);
m->m_len = m->m_pkthdr.len = BGE_JUMBO_FRAMELEN;
@@ -1226,8 +1225,6 @@ bge_newbuf_jumbo(struct bge_softc *sc, int i)
sizeof (struct bge_ext_rx_bd),
BUS_DMASYNC_PREWRITE);
- sc->bge_jumbo_cnt++;
-
return (0);
}
@@ -1258,7 +1255,9 @@ bge_init_rx_ring_std(struct bge_softc *sc)
}
sc->bge_std = BGE_STD_RX_RING_CNT - 1;
- sc->bge_std_cnt = 0;
+
+ /* lwm must be greater than the replenish threshold */
+ if_rxr_init(&sc->bge_std_ring, 17, BGE_JUMBO_RX_RING_CNT);
bge_fill_rx_ring_std(sc);
SET(sc->bge_flags, BGE_RXRING_VALID);
@@ -1281,10 +1280,10 @@ bge_rxtick(void *arg)
s = splnet();
if (ISSET(sc->bge_flags, BGE_RXRING_VALID) &&
- sc->bge_std_cnt <= 8)
+ if_rxr_inuse(&sc->bge_std_ring) <= 8)
bge_fill_rx_ring_std(sc);
if (ISSET(sc->bge_flags, BGE_JUMBO_RXRING_VALID) &&
- sc->bge_jumbo_cnt <= 8)
+ if_rxr_inuse(&sc->bge_jumbo_ring) <= 8)
bge_fill_rx_ring_jumbo(sc);
splx(s);
}
@@ -1294,17 +1293,21 @@ bge_fill_rx_ring_std(struct bge_softc *sc)
{
int i;
int post = 0;
+ u_int slots;
i = sc->bge_std;
- while (sc->bge_std_cnt < BGE_STD_RX_RING_CNT) {
+ for (slots = if_rxr_get(&sc->bge_std_ring, BGE_STD_RX_RING_CNT);
+ slots > 0; slots--) {
BGE_INC(i, BGE_STD_RX_RING_CNT);
if (bge_newbuf(sc, i) != 0)
break;
- sc->bge_std = i;
post = 1;
}
+ if_rxr_put(&sc->bge_std_ring, slots);
+
+ sc->bge_std = i;
if (post)
bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
@@ -1313,7 +1316,7 @@ bge_fill_rx_ring_std(struct bge_softc *sc)
* bge always needs more than 8 packets on the ring. if we cant do
* that now, then try again later.
*/
- if (sc->bge_std_cnt <= 8)
+ if (if_rxr_inuse(&sc->bge_std_ring) <= 8)
timeout_add(&sc->bge_rxtimeout, 1);
}
@@ -1368,7 +1371,9 @@ bge_init_rx_ring_jumbo(struct bge_softc *sc)
}
sc->bge_jumbo = BGE_JUMBO_RX_RING_CNT - 1;
- sc->bge_jumbo_cnt = 0;
+
+ /* lwm must be greater than the replenish threshold */
+ if_rxr_init(&sc->bge_jumbo_ring, 17, BGE_JUMBO_RX_RING_CNT);
bge_fill_rx_ring_jumbo(sc);
SET(sc->bge_flags, BGE_JUMBO_RXRING_VALID);
@@ -1393,17 +1398,21 @@ bge_fill_rx_ring_jumbo(struct bge_softc *sc)
{
int i;
int post = 0;
+ u_int slots;
i = sc->bge_jumbo;
- while (sc->bge_jumbo_cnt < BGE_JUMBO_RX_RING_CNT) {
+ for (slots = if_rxr_get(&sc->bge_jumbo_ring, BGE_JUMBO_RX_RING_CNT);
+ slots > 0; slots--) {
BGE_INC(i, BGE_JUMBO_RX_RING_CNT);
if (bge_newbuf_jumbo(sc, i) != 0)
break;
- sc->bge_jumbo = i;
post = 1;
}
+ if_rxr_put(&sc->bge_jumbo_ring, slots);
+
+ sc->bge_jumbo = i;
if (post)
bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
@@ -1412,7 +1421,7 @@ bge_fill_rx_ring_jumbo(struct bge_softc *sc)
* bge always needs more than 8 packets on the ring. if we cant do
* that now, then try again later.
*/
- if (sc->bge_jumbo_cnt <= 8)
+ if (if_rxr_inuse(&sc->bge_jumbo_ring) <= 8)
timeout_add(&sc->bge_rxtimeout, 1);
}
@@ -2995,10 +3004,6 @@ bge_attach(struct device *parent, struct device *self, void *aux)
IFQ_SET_MAXLEN(&ifp->if_snd, BGE_TX_RING_CNT - 1);
IFQ_SET_READY(&ifp->if_snd);
- /* lwm must be greater than the replenish threshold */
- m_clsetwms(ifp, MCLBYTES, 17, BGE_STD_RX_RING_CNT);
- m_clsetwms(ifp, BGE_JLEN, 17, BGE_JUMBO_RX_RING_CNT);
-
DPRINTFN(5, ("bcopy\n"));
bcopy(sc->bge_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
@@ -3455,7 +3460,6 @@ bge_rxeof(struct bge_softc *sc)
sc->bge_cdata.bge_rx_jumbo_chain[rxidx] = NULL;
jumbocnt++;
- sc->bge_jumbo_cnt--;
dmamap = sc->bge_cdata.bge_rx_jumbo_map[rxidx];
bus_dmamap_sync(sc->bge_dmatag, dmamap, 0,
@@ -3471,7 +3475,6 @@ bge_rxeof(struct bge_softc *sc)
sc->bge_cdata.bge_rx_std_chain[rxidx] = NULL;
stdcnt++;
- sc->bge_std_cnt--;
dmamap = sc->bge_cdata.bge_rx_std_map[rxidx];
bus_dmamap_sync(sc->bge_dmatag, dmamap, 0,
@@ -3522,10 +3525,14 @@ bge_rxeof(struct bge_softc *sc)
sc->bge_rx_saved_considx = rx_cons;
bge_writembx(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx);
- if (stdcnt)
+ if (stdcnt) {
+ if_rxr_put(&sc->bge_std_ring, stdcnt);
bge_fill_rx_ring_std(sc);
- if (jumbocnt)
+ }
+ if (jumbocnt) {
+ if_rxr_put(&sc->bge_jumbo_ring, jumbocnt);
bge_fill_rx_ring_jumbo(sc);
+ }
}
void
@@ -4478,6 +4485,10 @@ bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
}
break;
+ case SIOCGIFRXR:
+ error = bge_rxrinfo(sc, (struct if_rxrinfo *)ifr->ifr_data);
+ break;
+
default:
error = ether_ioctl(ifp, &sc->arpcom, command, data);
}
@@ -4492,6 +4503,33 @@ bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
return (error);
}
+int
+bge_rxrinfo(struct bge_softc *sc, struct if_rxrinfo *ifri)
+{
+ struct if_rxring_info ifr[2];
+ u_int n = 0;
+
+ memset(ifr, 0, sizeof(ifr));
+
+ if (ISSET(sc->bge_flags, BGE_RXRING_VALID)) {
+ ifr[n].ifr_size = MCLBYTES;
+ strlcpy(ifr[n].ifr_name, "std", sizeof(ifr[n].ifr_name));
+ ifr[n].ifr_info = sc->bge_std_ring;
+
+ n++;
+ }
+
+ if (ISSET(sc->bge_flags, BGE_JUMBO_RXRING_VALID)) {
+ ifr[n].ifr_size = BGE_JLEN;
+ strlcpy(ifr[n].ifr_name, "jumbo", sizeof(ifr[n].ifr_name));
+ ifr[n].ifr_info = sc->bge_jumbo_ring;
+
+ n++;
+ }
+
+ return (if_rxr_info_ioctl(ifri, n, ifr));
+}
+
void
bge_watchdog(struct ifnet *ifp)
{
diff --git a/sys/dev/pci/if_bgereg.h b/sys/dev/pci/if_bgereg.h
index f876477f42e..0929f28e1bf 100644
--- a/sys/dev/pci/if_bgereg.h
+++ b/sys/dev/pci/if_bgereg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bgereg.h,v 1.123 2014/02/05 05:59:42 brad Exp $ */
+/* $OpenBSD: if_bgereg.h,v 1.124 2014/07/08 05:35:18 dlg Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
@@ -2898,10 +2898,10 @@ struct bge_softc {
u_int16_t bge_ev_saved_considx;
u_int16_t bge_return_ring_cnt;
u_int32_t bge_tx_prodidx;
+ struct if_rxring bge_std_ring;
u_int16_t bge_std; /* current std ring head */
- int bge_std_cnt;
+ struct if_rxring bge_jumbo_ring;
u_int16_t bge_jumbo; /* current jumo ring head */
- int bge_jumbo_cnt;
u_int32_t bge_stat_ticks;
u_int32_t bge_rx_coal_ticks;
u_int32_t bge_tx_coal_ticks;
diff --git a/sys/dev/pci/if_bnx.c b/sys/dev/pci/if_bnx.c
index dffee8cbd0e..323a1696804 100644
--- a/sys/dev/pci/if_bnx.c
+++ b/sys/dev/pci/if_bnx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bnx.c,v 1.103 2013/10/30 04:08:07 dlg Exp $ */
+/* $OpenBSD: if_bnx.c,v 1.104 2014/07/08 05:35:18 dlg Exp $ */
/*-
* Copyright (c) 2006 Broadcom Corporation
@@ -880,7 +880,6 @@ bnx_attachhook(void *xsc)
ifp->if_watchdog = bnx_watchdog;
IFQ_SET_MAXLEN(&ifp->if_snd, USABLE_TX_BD - 1);
IFQ_SET_READY(&ifp->if_snd);
- m_clsetwms(ifp, MCLBYTES, 2, USABLE_RX_BD);
bcopy(sc->eaddr, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
bcopy(sc->bnx_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
@@ -3664,9 +3663,9 @@ bnx_get_buf(struct bnx_softc *sc, u_int16_t *prod,
*prod_bseq);
/* This is a new mbuf allocation. */
- m = MCLGETI(NULL, M_DONTWAIT, &sc->arpcom.ac_if, MCLBYTES);
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
if (!m)
- return (ENOBUFS);
+ return (0);
m->m_len = m->m_pkthdr.len = MCLBYTES;
/* the chip aligns the ip header for us, no need to m_adj */
@@ -3674,27 +3673,15 @@ bnx_get_buf(struct bnx_softc *sc, u_int16_t *prod,
map = sc->rx_mbuf_map[*chain_prod];
if (bus_dmamap_load_mbuf(sc->bnx_dmatag, map, m, BUS_DMA_NOWAIT)) {
m_freem(m);
- return (ENOBUFS);
+ return (0);
}
first_chain_prod = *chain_prod;
- /* Make sure there is room in the receive chain. */
- if (map->dm_nsegs > sc->free_rx_bd) {
- bus_dmamap_unload(sc->bnx_dmatag, map);
- m_freem(m);
- return (EFBIG);
- }
-
#ifdef BNX_DEBUG
/* Track the distribution of buffer segments. */
sc->rx_mbuf_segs[map->dm_nsegs]++;
#endif
- /* Update some debug statistics counters */
- DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
- sc->rx_low_watermark = sc->free_rx_bd);
- DBRUNIF((sc->free_rx_bd == sc->max_rx_bd), sc->rx_empty_count++);
-
/* Setup the rx_bd for the first segment. */
rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
@@ -3732,12 +3719,11 @@ bnx_get_buf(struct bnx_softc *sc, u_int16_t *prod,
sc->rx_mbuf_ptr[*chain_prod] = m;
sc->rx_mbuf_map[first_chain_prod] = sc->rx_mbuf_map[*chain_prod];
sc->rx_mbuf_map[*chain_prod] = map;
- sc->free_rx_bd -= map->dm_nsegs;
DBRUN(BNX_VERBOSE_RECV, bnx_dump_rx_mbuf_chain(sc, debug_chain_prod,
map->dm_nsegs));
- return (0);
+ return (map->dm_nsegs);
}
void
@@ -4012,9 +3998,10 @@ bnx_fill_rx_chain(struct bnx_softc *sc)
{
u_int16_t prod, chain_prod;
u_int32_t prod_bseq;
+ u_int slots, used;
int ndesc = 0;
#ifdef BNX_DEBUG
- int rx_mbuf_alloc_before, free_rx_bd_before;
+ int rx_mbuf_alloc_before;
#endif
DBPRINT(sc, BNX_EXCESSIVE_RECV, "Entering %s()\n", __FUNCTION__);
@@ -4024,26 +4011,24 @@ bnx_fill_rx_chain(struct bnx_softc *sc)
#ifdef BNX_DEBUG
rx_mbuf_alloc_before = sc->rx_mbuf_alloc;
- free_rx_bd_before = sc->free_rx_bd;
#endif
/* Keep filling the RX chain until it's full. */
- while (sc->free_rx_bd > 0) {
+ slots = if_rxr_get(&sc->rx_ring, sc->max_rx_bd);
+ while (slots > BNX_MAX_SEGMENTS) {
chain_prod = RX_CHAIN_IDX(prod);
- if (bnx_get_buf(sc, &prod, &chain_prod, &prod_bseq)) {
+
+ used = bnx_get_buf(sc, &prod, &chain_prod, &prod_bseq);
+ if (used == 0) {
/* Bail out if we can't add an mbuf to the chain. */
break;
}
+ slots -= used;
+
prod = NEXT_RX_BD(prod);
ndesc++;
}
-
-#if 0
- DBRUNIF((sc->rx_mbuf_alloc - rx_mbuf_alloc_before),
- BNX_PRINTF(sc, "%s(): Installed %d mbufs in %d rx_bd entries.\n",
- __FUNCTION__, (sc->rx_mbuf_alloc - rx_mbuf_alloc_before),
- (free_rx_bd_before - sc->free_rx_bd)));
-#endif
+ if_rxr_put(&sc->rx_ring, slots);
/* Save the RX chain producer index. */
sc->rx_prod = prod;
@@ -4077,7 +4062,6 @@ bnx_init_rx_chain(struct bnx_softc *sc)
sc->rx_prod = 0;
sc->rx_cons = 0;
sc->rx_prod_bseq = 0;
- sc->free_rx_bd = USABLE_RX_BD;
sc->max_rx_bd = USABLE_RX_BD;
DBRUNIF(1, sc->rx_low_watermark = USABLE_RX_BD);
DBRUNIF(1, sc->rx_empty_count = 0);
@@ -4101,6 +4085,8 @@ bnx_init_rx_chain(struct bnx_softc *sc)
rxbd->rx_bd_haddr_lo = addr;
}
+ if_rxr_init(&sc->rx_ring, 2, sc->max_rx_bd);
+
/* Fill up the RX chain. */
bnx_fill_rx_chain(sc);
@@ -4163,8 +4149,6 @@ bnx_free_rx_chain(struct bnx_softc *sc)
for (i = 0; i < RX_PAGES; i++)
bzero(sc->rx_bd_chain[i], BNX_RX_CHAIN_PAGE_SZ);
- sc->free_rx_bd = sc->max_rx_bd;
-
/* Check if we lost any mbufs in the process. */
DBRUNIF((sc->rx_mbuf_alloc),
printf("%s: Memory leak! Lost %d mbufs from rx chain!\n",
@@ -4323,11 +4307,6 @@ bnx_rx_intr(struct bnx_softc *sc)
bus_space_barrier(sc->bnx_btag, sc->bnx_bhandle, 0, 0,
BUS_SPACE_BARRIER_READ);
- /* Update some debug statistics counters */
- DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
- sc->rx_low_watermark = sc->free_rx_bd);
- DBRUNIF((sc->free_rx_bd == USABLE_RX_BD), sc->rx_empty_count++);
-
/*
* Scan through the receive chain as long
* as there is work to do.
@@ -4349,7 +4328,7 @@ bnx_rx_intr(struct bnx_softc *sc)
/* Get the used rx_bd. */
rxbd = &sc->rx_bd_chain[RX_PAGE(sw_chain_cons)][RX_IDX(sw_chain_cons)];
- sc->free_rx_bd++;
+ if_rxr_put(&sc->rx_ring, 1);
DBRUN(BNX_VERBOSE_RECV, printf("%s(): ", __FUNCTION__);
bnx_dump_rxbd(sc, sw_chain_cons, rxbd));
@@ -6264,9 +6243,6 @@ bnx_dump_driver_state(struct bnx_softc *sc)
" 0x%08X - (sc->rx_mbuf_alloc) rx mbufs allocated\n",
sc->rx_mbuf_alloc);
- BNX_PRINTF(sc, " 0x%08X - (sc->free_rx_bd) free rx_bd's\n",
- sc->free_rx_bd);
-
BNX_PRINTF(sc,
"0x%08X/%08X - (sc->rx_low_watermark) rx low watermark\n",
sc->rx_low_watermark, sc->max_rx_bd);
diff --git a/sys/dev/pci/if_bnxreg.h b/sys/dev/pci/if_bnxreg.h
index 728250ebe61..83b358ead98 100644
--- a/sys/dev/pci/if_bnxreg.h
+++ b/sys/dev/pci/if_bnxreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bnxreg.h,v 1.42 2013/10/30 04:08:07 dlg Exp $ */
+/* $OpenBSD: if_bnxreg.h,v 1.43 2014/07/08 05:35:18 dlg Exp $ */
/*-
* Copyright (c) 2006 Broadcom Corporation
@@ -4936,7 +4936,7 @@ struct bnx_softc {
struct mbuf *rx_mbuf_ptr[TOTAL_RX_BD];
/* Track the number of rx_bd and tx_bd's in use. */
- u_int16_t free_rx_bd;
+ struct if_rxring rx_ring;
u_int16_t max_rx_bd;
u_int16_t used_tx_bd;
u_int16_t max_tx_bd;
diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c
index 8a1600cfab4..4c934eb26e8 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.284 2014/07/08 02:57:27 dlg Exp $ */
+/* $OpenBSD: if_em.c,v 1.285 2014/07/08 05:35:18 dlg Exp $ */
/* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */
#include <dev/pci/if_em.h>
@@ -698,6 +698,11 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
error = ifmedia_ioctl(ifp, ifr, &sc->media, command);
break;
+ case SIOCGIFRXR:
+ error = if_rxr_ioctl((struct if_rxrinfo *)ifr->ifr_data,
+ NULL, MCLBYTES, &sc->rx_ring);
+ break;
+
default:
error = ether_ioctl(ifp, &sc->interface_data, command, data);
}
@@ -1870,9 +1875,6 @@ 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, 2 * ((ifp->if_hardmtu / MCLBYTES) + 1),
- sc->num_rx_desc);
-
ifp->if_capabilities = IFCAP_VLAN_MTU;
#if NVLAN > 0
@@ -2506,7 +2508,7 @@ em_get_buf(struct em_softc *sc, int i)
return (ENOBUFS);
}
- m = MCLGETI(NULL, M_DONTWAIT, &sc->interface_data.ac_if, MCLBYTES);
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
if (!m) {
sc->mbuf_cluster_failed++;
return (ENOBUFS);
@@ -2534,8 +2536,6 @@ em_get_buf(struct em_softc *sc, int i)
bus_dmamap_sync(sc->rxdma.dma_tag, sc->rxdma.dma_map,
sizeof(*desc) * i, sizeof(*desc), BUS_DMASYNC_PREWRITE);
- sc->rx_ndescs++;
-
return (0);
}
@@ -2593,8 +2593,10 @@ fail:
int
em_setup_receive_structures(struct em_softc *sc)
{
- bzero((void *) sc->rx_desc_base,
- (sizeof(struct em_rx_desc)) * sc->num_rx_desc);
+ struct ifnet *ifp = &sc->interface_data.ac_if;
+
+ memset(sc->rx_desc_base, 0,
+ sizeof(struct em_rx_desc) * sc->num_rx_desc);
if (em_allocate_receive_structures(sc))
return (ENOMEM);
@@ -2602,10 +2604,11 @@ em_setup_receive_structures(struct em_softc *sc)
/* Setup our descriptor pointers */
sc->next_rx_desc_to_check = 0;
sc->last_rx_desc_filled = sc->num_rx_desc - 1;
- sc->rx_ndescs = 0;
- em_rxfill(sc);
- if (sc->rx_ndescs < 1) {
+ if_rxr_init(&sc->rx_ring, 2 * ((ifp->if_hardmtu / MCLBYTES) + 1),
+ sc->num_rx_desc);
+
+ if (em_rxfill(sc) == 0) {
printf("%s: unable to fill any rx descriptors\n",
sc->sc_dv.dv_xname);
}
@@ -2807,22 +2810,26 @@ em_realign(struct em_softc *sc, struct mbuf *m, u_int16_t *prev_len_adj)
int
em_rxfill(struct em_softc *sc)
{
+ u_int slots;
int post = 0;
int i;
i = sc->last_rx_desc_filled;
- while (sc->rx_ndescs < sc->num_rx_desc) {
+ for (slots = if_rxr_get(&sc->rx_ring, sc->num_rx_desc);
+ slots > 0; slots--) {
if (++i == sc->num_rx_desc)
i = 0;
if (em_get_buf(sc, i) != 0)
break;
- sc->last_rx_desc_filled = i;
post = 1;
}
+ sc->last_rx_desc_filled = i;
+ if_rxr_put(&sc->rx_ring, slots);
+
return (post);
}
@@ -2848,7 +2855,7 @@ em_rxeof(struct em_softc *sc)
struct em_buffer *pkt;
u_int8_t status;
- if (sc->rx_ndescs == 0)
+ if (if_rxr_inuse(&sc->rx_ring) == 0)
return;
i = sc->next_rx_desc_to_check;
@@ -2876,12 +2883,12 @@ em_rxeof(struct em_softc *sc)
if (m == NULL) {
panic("em_rxeof: NULL mbuf in slot %d "
- "(nrx %d, filled %d)", i, sc->rx_ndescs,
+ "(nrx %d, filled %d)", i,
+ if_rxr_inuse(&sc->rx_ring),
sc->last_rx_desc_filled);
}
- m_cluncount(m, 1);
- sc->rx_ndescs--;
+ if_rxr_put(&sc->rx_ring, 1);
accept_frame = 1;
prev_len_adj = 0;
@@ -2990,7 +2997,7 @@ em_rxeof(struct em_softc *sc)
/* Advance our pointers to the next descriptor. */
if (++i == sc->num_rx_desc)
i = 0;
- } while (sc->rx_ndescs > 0);
+ } while (if_rxr_inuse(&sc->rx_ring) > 0);
bus_dmamap_sync(sc->rxdma.dma_tag, sc->rxdma.dma_map,
0, sizeof(*desc) * sc->num_rx_desc,
diff --git a/sys/dev/pci/if_em.h b/sys/dev/pci/if_em.h
index 3f871a71cb9..78650804104 100644
--- a/sys/dev/pci/if_em.h
+++ b/sys/dev/pci/if_em.h
@@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
/* $FreeBSD: if_em.h,v 1.26 2004/09/01 23:22:41 pdeuskar Exp $ */
-/* $OpenBSD: if_em.h,v 1.50 2013/08/07 01:06:34 bluhm Exp $ */
+/* $OpenBSD: if_em.h,v 1.51 2014/07/08 05:35:18 dlg Exp $ */
#ifndef _EM_H_DEFINED_
#define _EM_H_DEFINED_
@@ -373,9 +373,9 @@ struct em_softc {
*/
struct em_dma_alloc rxdma; /* bus_dma glue for rx desc */
struct em_rx_desc *rx_desc_base;
+ struct if_rxring rx_ring;
u_int32_t next_rx_desc_to_check;
u_int32_t last_rx_desc_filled;
- int rx_ndescs;
u_int32_t rx_buffer_len;
u_int16_t num_rx_desc;
struct em_buffer *rx_buffer_area;
diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c
index 78f2f9c40fb..1d0618b8338 100644
--- a/sys/dev/pci/if_ix.c
+++ b/sys/dev/pci/if_ix.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ix.c,v 1.93 2013/12/09 19:48:04 mikeb Exp $ */
+/* $OpenBSD: if_ix.c,v 1.94 2014/07/08 05:35:18 dlg Exp $ */
/******************************************************************************
@@ -1535,8 +1535,6 @@ ixgbe_setup_interface(struct ix_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
@@ -2441,7 +2439,7 @@ ixgbe_get_buf(struct rx_ring *rxr, int i)
}
/* needed in any case so prealocate since this one will fail for sure */
- mp = MCLGETI(NULL, M_DONTWAIT, &sc->arpcom.ac_if, sc->rx_mbuf_sz);
+ mp = MCLGETI(NULL, M_DONTWAIT, NULL, sc->rx_mbuf_sz);
if (!mp)
return (ENOBUFS);
@@ -2468,8 +2466,6 @@ ixgbe_get_buf(struct rx_ring *rxr, int i)
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
dsize * i, dsize, BUS_DMASYNC_PREWRITE);
- rxr->rx_ndescs++;
-
return (0);
}
@@ -2527,6 +2523,7 @@ int
ixgbe_setup_receive_ring(struct rx_ring *rxr)
{
struct ix_softc *sc = rxr->sc;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
int rsize, error;
rsize = roundup2(sc->num_rx_desc *
@@ -2540,10 +2537,12 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr)
/* Setup our descriptor indices */
rxr->next_to_check = 0;
rxr->last_desc_filled = sc->num_rx_desc - 1;
- rxr->rx_ndescs = 0;
+
+ if_rxr_init(&rxr->rx_ring, 2 * ((ifp->if_hardmtu / MCLBYTES) + 1),
+ sc->num_rx_desc);
ixgbe_rxfill(rxr);
- if (rxr->rx_ndescs < 1) {
+ if (if_rxr_inuse(&rxr->rx_ring) == 0) {
printf("%s: unable to fill any rx descriptors\n",
sc->dev.dv_xname);
return (ENOBUFS);
@@ -2557,19 +2556,23 @@ ixgbe_rxfill(struct rx_ring *rxr)
{
struct ix_softc *sc = rxr->sc;
int post = 0;
+ u_int slots;
int i;
i = rxr->last_desc_filled;
- while (rxr->rx_ndescs < sc->num_rx_desc) {
+ for (slots = if_rxr_get(&rxr->rx_ring, sc->num_rx_desc);
+ slots > 0; slots--) {
if (++i == sc->num_rx_desc)
i = 0;
if (ixgbe_get_buf(rxr, i) != 0)
break;
- rxr->last_desc_filled = i;
post = 1;
}
+ if_rxr_put(&rxr->rx_ring, slots);
+
+ rxr->last_desc_filled = i;
return (post);
}
@@ -2801,7 +2804,7 @@ ixgbe_rxeof(struct ix_queue *que)
return FALSE;
i = rxr->next_to_check;
- while (rxr->rx_ndescs > 0) {
+ while (if_rxr_inuse(&rxr->rx_ring) > 0) {
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
dsize * i, dsize, BUS_DMASYNC_POSTREAD);
@@ -2847,7 +2850,7 @@ ixgbe_rxeof(struct ix_queue *que)
if (mp == NULL) {
panic("%s: ixgbe_rxeof: NULL mbuf in slot %d "
"(nrx %d, filled %d)", sc->dev.dv_xname,
- i, rxr->rx_ndescs,
+ i, if_rxr_inuse(&rxr->rx_ring),
rxr->last_desc_filled);
}
@@ -2898,8 +2901,6 @@ ixgbe_rxeof(struct ix_queue *que)
sendmp = NULL;
mp->m_next = nxbuf->buf;
} else { /* Sending this frame? */
- m_cluncount(sendmp, 1);
-
sendmp->m_pkthdr.rcvif = ifp;
ifp->if_ipackets++;
rxr->rx_packets++;
@@ -2918,7 +2919,7 @@ ixgbe_rxeof(struct ix_queue *que)
ether_input_mbuf(ifp, sendmp);
}
next_desc:
- rxr->rx_ndescs--;
+ if_rxr_put(&rxr->rx_ring, 1);
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
dsize * i, dsize,
BUS_DMASYNC_PREREAD);
diff --git a/sys/dev/pci/if_ix.h b/sys/dev/pci/if_ix.h
index f7d4f326895..8a69c8504c9 100644
--- a/sys/dev/pci/if_ix.h
+++ b/sys/dev/pci/if_ix.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ix.h,v 1.24 2013/08/05 19:58:05 mikeb Exp $ */
+/* $OpenBSD: if_ix.h,v 1.25 2014/07/08 05:35:18 dlg Exp $ */
/******************************************************************************
@@ -204,7 +204,7 @@ struct rx_ring {
uint next_to_refresh;
uint next_to_check;
uint last_desc_filled;
- int rx_ndescs;
+ struct if_rxring rx_ring;
struct ixgbe_rx_buf *rx_buffers;
uint32_t bytes; /* Used for AIM calc */
diff --git a/sys/dev/pci/if_msk.c b/sys/dev/pci/if_msk.c
index 21ee4e03d2b..7ca28629540 100644
--- a/sys/dev/pci/if_msk.c
+++ b/sys/dev/pci/if_msk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_msk.c,v 1.102 2013/12/28 03:35:42 deraadt Exp $ */
+/* $OpenBSD: if_msk.c,v 1.103 2014/07/08 05:35:18 dlg Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
@@ -433,7 +433,8 @@ msk_init_rx_ring(struct sk_if_softc *sc_if)
sc_if->sk_cdata.sk_rx_prod = 0;
sc_if->sk_cdata.sk_rx_cons = 0;
- sc_if->sk_cdata.sk_rx_cnt = 0;
+
+ if_rxr_init(&sc_if->sk_cdata.sk_rx_ring, 2, MSK_RX_RING_CNT);
msk_fill_rx_ring(sc_if);
return (0);
@@ -494,9 +495,9 @@ msk_newbuf(struct sk_if_softc *sc_if)
int error;
int i, head;
- m = MCLGETI(NULL, M_DONTWAIT, &sc_if->arpcom.ac_if, sc_if->sk_pktlen);
- if (!m)
- return (ENOBUFS);
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, sc_if->sk_pktlen);
+ if (m == NULL)
+ return (0);
m->m_len = m->m_pkthdr.len = sc_if->sk_pktlen;
m_adj(m, ETHER_ALIGN);
@@ -506,13 +507,7 @@ msk_newbuf(struct sk_if_softc *sc_if)
BUS_DMA_READ|BUS_DMA_NOWAIT);
if (error) {
m_freem(m);
- return (ENOBUFS);
- }
-
- if (dmamap->dm_nsegs > (MSK_RX_RING_CNT - sc_if->sk_cdata.sk_rx_cnt)) {
- bus_dmamap_unload(sc_if->sk_softc->sc_dmatag, dmamap);
- m_freem(m);
- return (ENOBUFS);
+ return (0);
}
bus_dmamap_sync(sc_if->sk_softc->sc_dmatag, dmamap, 0,
@@ -530,7 +525,6 @@ msk_newbuf(struct sk_if_softc *sc_if)
MSK_CDRXSYNC(sc_if, head, BUS_DMASYNC_PREWRITE);
SK_INC(sc_if->sk_cdata.sk_rx_prod, MSK_RX_RING_CNT);
- sc_if->sk_cdata.sk_rx_cnt++;
for (i = 1; i < dmamap->dm_nsegs; i++) {
c = &sc_if->sk_cdata.sk_rx_chain[sc_if->sk_cdata.sk_rx_prod];
@@ -550,7 +544,6 @@ msk_newbuf(struct sk_if_softc *sc_if)
BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
SK_INC(sc_if->sk_cdata.sk_rx_prod, MSK_RX_RING_CNT);
- sc_if->sk_cdata.sk_rx_cnt++;
}
c = &sc_if->sk_cdata.sk_rx_chain[head];
@@ -559,7 +552,7 @@ msk_newbuf(struct sk_if_softc *sc_if)
MSK_CDRXSYNC(sc_if, head, BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
- return (0);
+ return (dmamap->dm_nsegs);
}
/*
@@ -952,7 +945,7 @@ msk_attach(struct device *parent, struct device *self, void *aux)
for (i = 0; i < MSK_RX_RING_CNT; i++) {
if ((error = bus_dmamap_create(sc->sc_dmatag,
- sc_if->sk_pktlen, 4, sc_if->sk_pktlen,
+ sc_if->sk_pktlen, SK_NRXSEG, sc_if->sk_pktlen,
0, 0, &sc_if->sk_cdata.sk_rx_map[i])) != 0) {
printf("\n%s: unable to create rx DMA map %d, "
"error = %d\n", sc->sk_dev.dv_xname, i, error);
@@ -1011,7 +1004,6 @@ msk_attach(struct device *parent, struct device *self, void *aux)
*/
if_attach(ifp);
ether_ifattach(ifp);
- m_clsetwms(ifp, sc_if->sk_pktlen, 2, MSK_RX_RING_CNT);
DPRINTFN(2, ("msk_attach: end\n"));
return;
@@ -1620,8 +1612,8 @@ msk_rxeof(struct sk_if_softc *sc_if, u_int16_t len, u_int32_t rxstat)
dmamap = sc_if->sk_cdata.sk_rx_map[cur];
for (i = 0; i < dmamap->dm_nsegs; i++) {
SK_INC(sc_if->sk_cdata.sk_rx_cons, MSK_RX_RING_CNT);
- sc_if->sk_cdata.sk_rx_cnt--;
}
+ if_rxr_put(&sc_if->sk_cdata.sk_rx_ring, dmamap->dm_nsegs);
bus_dmamap_sync(sc_if->sk_softc->sc_dmatag, dmamap, 0,
dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
@@ -1713,10 +1705,17 @@ msk_txeof(struct sk_if_softc *sc_if)
void
msk_fill_rx_ring(struct sk_if_softc *sc_if)
{
- while (sc_if->sk_cdata.sk_rx_cnt < MSK_RX_RING_CNT) {
- if (msk_newbuf(sc_if) == ENOBUFS)
+ u_int slots, used;
+
+ slots = if_rxr_get(&sc_if->sk_cdata.sk_rx_ring, MSK_RX_RING_CNT);
+ while (slots > SK_NRXSEG) {
+ used = msk_newbuf(sc_if);
+ if (used == 0)
break;
+
+ slots -= used;
}
+ if_rxr_put(&sc_if->sk_cdata.sk_rx_ring, slots);
}
void
@@ -2127,7 +2126,6 @@ msk_stop(struct sk_if_softc *sc_if, int softonly)
sc_if->sk_cdata.sk_rx_prod = 0;
sc_if->sk_cdata.sk_rx_cons = 0;
- sc_if->sk_cdata.sk_rx_cnt = 0;
for (i = 0; i < MSK_TX_RING_CNT; i++) {
if (sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf != NULL) {
diff --git a/sys/dev/pci/if_mskvar.h b/sys/dev/pci/if_mskvar.h
index b0e2943f80d..5291dedb50a 100644
--- a/sys/dev/pci/if_mskvar.h
+++ b/sys/dev/pci/if_mskvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_mskvar.h,v 1.10 2013/02/01 06:51:32 brad Exp $ */
+/* $OpenBSD: if_mskvar.h,v 1.11 2014/07/08 05:35:18 dlg Exp $ */
/* $NetBSD: if_skvar.h,v 1.6 2005/05/30 04:35:22 christos Exp $ */
/*-
@@ -26,7 +26,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-/* $OpenBSD: if_mskvar.h,v 1.10 2013/02/01 06:51:32 brad Exp $ */
+/* $OpenBSD: if_mskvar.h,v 1.11 2014/07/08 05:35:18 dlg Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
@@ -96,12 +96,15 @@ struct sk_chain {
*/
#define SK_NTXSEG 30
+#define SK_NRXSEG 4
+
struct sk_txmap_entry {
bus_dmamap_t dmamap;
SIMPLEQ_ENTRY(sk_txmap_entry) link;
};
struct msk_chain_data {
+ struct if_rxring sk_rx_ring;
struct sk_chain sk_tx_chain[MSK_TX_RING_CNT];
struct sk_chain sk_rx_chain[MSK_RX_RING_CNT];
struct sk_txmap_entry *sk_tx_map[MSK_TX_RING_CNT];
@@ -111,7 +114,6 @@ struct msk_chain_data {
int sk_tx_cnt;
int sk_rx_prod;
int sk_rx_cons;
- int sk_rx_cnt;
};
struct msk_ring_data {
diff --git a/sys/dev/pci/if_myx.c b/sys/dev/pci/if_myx.c
index 0bfe70a5704..848e4854f81 100644
--- a/sys/dev/pci/if_myx.c
+++ b/sys/dev/pci/if_myx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_myx.c,v 1.58 2014/06/17 04:58:45 dlg Exp $ */
+/* $OpenBSD: if_myx.c,v 1.59 2014/07/08 05:35:18 dlg Exp $ */
/*
* Copyright (c) 2007 Reyk Floeter <reyk@openbsd.org>
@@ -143,6 +143,7 @@ struct myx_softc {
struct myx_buf_list sc_rx_buf_free[2];
struct myx_buf_list sc_rx_buf_list[2];
u_int sc_rx_ring_idx[2];
+ struct if_rxring sc_rx_ring[2];
#define MYX_RXSMALL 0
#define MYX_RXBIG 1
struct timeout sc_refill;
@@ -195,6 +196,7 @@ void myx_media_status(struct ifnet *, struct ifmediareq *);
void myx_link_state(struct myx_softc *, u_int32_t);
void myx_watchdog(struct ifnet *);
int myx_ioctl(struct ifnet *, u_long, caddr_t);
+int myx_rxrinfo(struct myx_softc *, struct if_rxrinfo *);
void myx_up(struct myx_softc *);
void myx_iff(struct myx_softc *);
void myx_down(struct myx_softc *);
@@ -944,6 +946,10 @@ myx_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
break;
+ case SIOCGIFRXR:
+ error = myx_rxrinfo(sc, (struct if_rxrinfo *)ifr->ifr_data);
+ break;
+
default:
error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
}
@@ -959,6 +965,26 @@ myx_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
return (error);
}
+int
+myx_rxrinfo(struct myx_softc *sc, struct if_rxrinfo *ifri)
+{
+ struct if_rxring_info ifr[2];
+
+ memset(ifr, 0, sizeof(ifr));
+
+ ifr[0].ifr_size = MCLBYTES;
+ mtx_enter(&sc->sc_rx_ring_lock[0].mrl_mtx);
+ ifr[0].ifr_info = sc->sc_rx_ring[0];
+ mtx_leave(&sc->sc_rx_ring_lock[0].mrl_mtx);
+
+ ifr[1].ifr_size = 12 * 1024;
+ mtx_enter(&sc->sc_rx_ring_lock[1].mrl_mtx);
+ ifr[1].ifr_info = sc->sc_rx_ring[1];
+ mtx_leave(&sc->sc_rx_ring_lock[1].mrl_mtx);
+
+ return (if_rxr_info_ioctl(ifri, nitems(ifr), ifr));
+}
+
void
myx_up(struct myx_softc *sc)
{
@@ -1008,9 +1034,6 @@ myx_up(struct myx_softc *sc)
}
sc->sc_rx_ring_count = r / sizeof(struct myx_rx_desc);
- m_clsetwms(ifp, MCLBYTES, 2, sc->sc_rx_ring_count - 2);
- m_clsetwms(ifp, 12 * 1024, 2, sc->sc_rx_ring_count - 2);
-
memset(&mc, 0, sizeof(mc));
if (myx_cmd(sc, MYXCMD_GET_TXRINGSZ, &mc, &r) != 0) {
printf("%s: unable to get tx ring size\n", DEVNAME(sc));
@@ -1177,6 +1200,9 @@ myx_up(struct myx_softc *sc)
myx_buf_put(&sc->sc_rx_buf_free[MYX_RXBIG], mb);
}
+ if_rxr_init(&sc->sc_rx_ring[MYX_RXBIG], 2, sc->sc_rx_ring_count - 2);
+ if_rxr_init(&sc->sc_rx_ring[MYX_RXSMALL], 2, sc->sc_rx_ring_count - 2);
+
myx_rx_zero(sc, MYX_RXSMALL);
if (myx_rx_fill(sc, MYX_RXSMALL) != 0) {
printf("%s: failed to fill small rx ring\n", DEVNAME(sc));
@@ -1777,6 +1803,7 @@ myx_rxeof(struct myx_softc *sc)
struct mbuf *m;
int ring;
int rings = 0;
+ u_int rxfree[2] = { 0 , 0 };
u_int len;
bus_dmamap_sync(sc->sc_dmat, sc->sc_intrq_dma.mxm_map, 0,
@@ -1818,12 +1845,20 @@ myx_rxeof(struct myx_softc *sc)
myx_buf_put(&sc->sc_rx_buf_free[ring], mb);
- SET(rings, 1 << ring);
+ rxfree[ring]++;
}
bus_dmamap_sync(sc->sc_dmat, sc->sc_intrq_dma.mxm_map, 0,
sc->sc_intrq_dma.mxm_map->dm_mapsize, BUS_DMASYNC_PREREAD);
+ for (ring = MYX_RXSMALL; ring <= MYX_RXBIG; ring++) {
+ mtx_enter(&sc->sc_rx_ring_lock[ring].mrl_mtx);
+ if_rxr_put(&sc->sc_rx_ring[ring], rxfree[ring]);
+ mtx_leave(&sc->sc_rx_ring_lock[ring].mrl_mtx);
+
+ SET(rings, 1 << ring);
+ }
+
return (rings);
}
@@ -1849,13 +1884,20 @@ myx_rx_fill(struct myx_softc *sc, int ring)
struct myx_rx_desc rxd;
struct myx_buf *mb, *firstmb;
u_int32_t offset = sc->sc_rx_ring_offset[ring];
- u_int idx, firstidx;
+ u_int idx, firstidx, slots;
int rv = 1;
if (!myx_ring_enter(&sc->sc_rx_ring_lock[ring]))
return (-1);
do {
+ mtx_enter(&sc->sc_rx_ring_lock[ring].mrl_mtx);
+ slots = if_rxr_get(&sc->sc_rx_ring[ring], sc->sc_rx_ring_count);
+ mtx_leave(&sc->sc_rx_ring_lock[ring].mrl_mtx);
+
+ if (slots-- == 0)
+ continue;
+
firstmb = myx_buf_fill(sc, ring);
if (firstmb == NULL)
continue;
@@ -1867,7 +1909,7 @@ myx_rx_fill(struct myx_softc *sc, int ring)
idx = firstidx + 1;
idx %= sc->sc_rx_ring_count;
- while ((mb = myx_buf_fill(sc, ring)) != NULL) {
+ while (slots > 0 && (mb = myx_buf_fill(sc, ring)) != NULL) {
myx_buf_put(&sc->sc_rx_buf_list[ring], mb);
rxd.rx_addr = htobe64(mb->mb_map->dm_segs[0].ds_addr);
@@ -1876,6 +1918,7 @@ myx_rx_fill(struct myx_softc *sc, int ring)
idx++;
idx %= sc->sc_rx_ring_count;
+ slots--;
}
/* make sure the first descriptor is seen after the others */
@@ -1890,6 +1933,9 @@ myx_rx_fill(struct myx_softc *sc, int ring)
&rxd, sizeof(rxd));
sc->sc_rx_ring_idx[ring] = idx;
+ mtx_enter(&sc->sc_rx_ring_lock[ring].mrl_mtx);
+ if_rxr_put(&sc->sc_rx_ring[ring], slots);
+ mtx_leave(&sc->sc_rx_ring_lock[ring].mrl_mtx);
} while (!myx_ring_leave(&sc->sc_rx_ring_lock[ring]));
return (rv);
@@ -1904,7 +1950,7 @@ myx_buf_fill(struct myx_softc *sc, int ring)
int rv;
KERNEL_LOCK();
- m = MCLGETI(NULL, M_DONTWAIT, &sc->sc_ac.ac_if, sizes[ring]);
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, sizes[ring]);
KERNEL_UNLOCK();
if (m == NULL)
return (NULL);
diff --git a/sys/dev/pci/if_oce.c b/sys/dev/pci/if_oce.c
index 37234120da5..4e08eb2b947 100644
--- a/sys/dev/pci/if_oce.c
+++ b/sys/dev/pci/if_oce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_oce.c,v 1.74 2014/01/20 17:21:22 chris Exp $ */
+/* $OpenBSD: if_oce.c,v 1.75 2014/07/08 05:35:18 dlg Exp $ */
/*
* Copyright (c) 2012 Mike Belopuhov
@@ -279,11 +279,10 @@ struct oce_rq {
struct oce_cq * cq;
+ struct if_rxring rxring;
struct oce_pkt_list pkt_list;
struct oce_pkt_list pkt_free;
- uint32_t pending;
-
uint32_t rss_cpuid;
#ifdef OCE_LRO
@@ -831,9 +830,6 @@ oce_attach_ifp(struct oce_softc *sc)
IFQ_SET_MAXLEN(&ifp->if_snd, sc->sc_tx_ring_size - 1);
IFQ_SET_READY(&ifp->if_snd);
- /* oce splits jumbos into 2k chunks... */
- m_clsetwms(ifp, MCLBYTES, 8, sc->sc_rx_ring_size);
-
ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_CSUM_IPv4 |
IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
@@ -1063,9 +1059,11 @@ oce_init(void *arg)
sc->sc_dev.dv_xname);
goto error;
}
- rq->pending = 0;
rq->ring->index = 0;
+ /* oce splits jumbos into 2k chunks... */
+ if_rxr_init(&rq->rxring, 8, rq->nitems);
+
if (!oce_alloc_rx_bufs(rq)) {
printf("%s: failed to allocate rx buffers\n",
sc->sc_dev.dv_xname);
@@ -1523,7 +1521,7 @@ oce_intr_rq(void *arg)
if (ncqe) {
oce_arm_cq(cq, ncqe, FALSE);
- if (rq->nitems - rq->pending > 1 && !oce_alloc_rx_bufs(rq))
+ if (!oce_alloc_rx_bufs(rq))
timeout_add(&sc->sc_rxrefill, 1);
}
}
@@ -1556,7 +1554,7 @@ oce_rxeof(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe)
bus_dmamap_sync(sc->sc_dmat, pkt->map, 0, pkt->map->dm_mapsize,
BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->sc_dmat, pkt->map);
- rq->pending--;
+ if_rxr_put(&rq->rxring, 1);
frag_len = (len > rq->fragsize) ? rq->fragsize : len;
pkt->mbuf->m_len = frag_len;
@@ -1593,9 +1591,6 @@ oce_rxeof(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe)
goto exit;
}
- /* Account for jumbo chains */
- m_cluncount(m, 1);
-
m->m_pkthdr.rcvif = ifp;
#if NVLAN > 0
@@ -1670,7 +1665,7 @@ oce_rxeoc(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe)
bus_dmamap_sync(sc->sc_dmat, pkt->map, 0, pkt->map->dm_mapsize,
BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->sc_dmat, pkt->map);
- rq->pending--;
+ if_rxr_put(&rq->rxring, 1);
m_freem(pkt->mbuf);
oce_pkt_put(&rq->pkt_free, pkt);
}
@@ -1758,14 +1753,13 @@ int
oce_get_buf(struct oce_rq *rq)
{
struct oce_softc *sc = rq->sc;
- struct ifnet *ifp = &sc->sc_ac.ac_if;
struct oce_pkt *pkt;
struct oce_nic_rqe *rqe;
if ((pkt = oce_pkt_get(&rq->pkt_free)) == NULL)
return (0);
- pkt->mbuf = MCLGETI(NULL, M_DONTWAIT, ifp, MCLBYTES);
+ pkt->mbuf = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
if (pkt->mbuf == NULL) {
oce_pkt_put(&rq->pkt_free, pkt);
return (0);
@@ -1791,7 +1785,6 @@ oce_get_buf(struct oce_rq *rq)
rqe = oce_ring_get(rq->ring);
rqe->u0.s.frag_pa_hi = ADDR_HI(pkt->map->dm_segs[0].ds_addr);
rqe->u0.s.frag_pa_lo = ADDR_LO(pkt->map->dm_segs[0].ds_addr);
- rq->pending++;
oce_dma_sync(&rq->ring->dma, BUS_DMASYNC_POSTREAD |
BUS_DMASYNC_POSTWRITE);
@@ -1806,9 +1799,16 @@ oce_alloc_rx_bufs(struct oce_rq *rq)
{
struct oce_softc *sc = rq->sc;
int i, nbufs = 0;
+ u_int slots;
+
+ for (slots = if_rxr_get(&rq->rxring, rq->nitems); slots > 0; slots--) {
+ if (oce_get_buf(rq) == 0)
+ break;
- while (oce_get_buf(rq))
nbufs++;
+ }
+ if_rxr_put(&rq->rxring, slots);
+
if (!nbufs)
return (0);
for (i = nbufs / OCE_MAX_RQ_POSTS; i > 0; i--) {
@@ -2424,7 +2424,7 @@ oce_free_posted_rxbuf(struct oce_rq *rq)
pkt->mbuf = NULL;
}
oce_pkt_put(&rq->pkt_free, pkt);
- rq->pending--;
+ if_rxr_put(&rq->rxring, 1);
}
}
diff --git a/sys/dev/pci/if_sis.c b/sys/dev/pci/if_sis.c
index 6588ebade1e..a51ca8e26b1 100644
--- a/sys/dev/pci/if_sis.c
+++ b/sys/dev/pci/if_sis.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sis.c,v 1.115 2013/12/28 03:34:54 deraadt Exp $ */
+/* $OpenBSD: if_sis.c,v 1.116 2014/07/08 05:35:18 dlg Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
@@ -1174,8 +1174,6 @@ sis_attach(struct device *parent, struct device *self, void *aux)
ifp->if_capabilities = IFCAP_VLAN_MTU;
- m_clsetwms(ifp, MCLBYTES, 2, SIS_RX_LIST_CNT - 1);
-
sc->sc_mii.mii_ifp = ifp;
sc->sc_mii.mii_readreg = sis_miibus_readreg;
sc->sc_mii.mii_writereg = sis_miibus_writereg;
@@ -1270,7 +1268,8 @@ sis_ring_init(struct sis_softc *sc)
ld->sis_rx_list[i].sis_ctl = 0;
}
- cd->sis_rx_prod = cd->sis_rx_cons = cd->sis_rx_cnt = 0;
+ cd->sis_rx_prod = cd->sis_rx_cons;
+ if_rxr_init(&cd->sis_rx_ring, 2, SIS_RX_LIST_CNT - 1);
sis_fill_rx_ring(sc);
return (0);
@@ -1281,16 +1280,19 @@ sis_fill_rx_ring(struct sis_softc *sc)
{
struct sis_list_data *ld;
struct sis_ring_data *cd;
+ u_int slots;
cd = &sc->sis_cdata;
ld = sc->sis_ldata;
- while (cd->sis_rx_cnt < SIS_RX_LIST_CNT) {
+ for (slots = if_rxr_get(&cd->sis_rx_ring, SIS_RX_LIST_CNT);
+ slots > 0; slots--) {
if (sis_newbuf(sc, &ld->sis_rx_list[cd->sis_rx_prod]))
break;
+
SIS_INC(cd->sis_rx_prod, SIS_RX_LIST_CNT);
- cd->sis_rx_cnt++;
}
+ if_rxr_put(&cd->sis_rx_ring, slots);
}
/*
@@ -1304,7 +1306,7 @@ sis_newbuf(struct sis_softc *sc, struct sis_desc *c)
if (c == NULL)
return (EINVAL);
- m_new = MCLGETI(NULL, M_DONTWAIT, &sc->arpcom.ac_if, MCLBYTES);
+ m_new = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
if (!m_new)
return (ENOBUFS);
@@ -1350,7 +1352,7 @@ sis_rxeof(struct sis_softc *sc)
ifp = &sc->arpcom.ac_if;
- while(sc->sis_cdata.sis_rx_cnt > 0) {
+ while (if_rxr_inuse(&sc->sis_cdata.sis_rx_ring) > 0) {
cur_rx = &sc->sis_ldata->sis_rx_list[sc->sis_cdata.sis_rx_cons];
bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
((caddr_t)cur_rx - sc->sc_listkva),
@@ -1365,7 +1367,7 @@ sis_rxeof(struct sis_softc *sc)
total_len = SIS_RXBYTES(cur_rx);
/* from here on the buffer is consumed */
SIS_INC(sc->sis_cdata.sis_rx_cons, SIS_RX_LIST_CNT);
- sc->sis_cdata.sis_rx_cnt--;
+ if_rxr_put(&sc->sis_cdata.sis_rx_ring, 1);
/*
* If an error occurs, update stats, clear the
diff --git a/sys/dev/pci/if_sisreg.h b/sys/dev/pci/if_sisreg.h
index 0d046450460..6e54e88634f 100644
--- a/sys/dev/pci/if_sisreg.h
+++ b/sys/dev/pci/if_sisreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sisreg.h,v 1.32 2012/10/18 21:44:21 deraadt Exp $ */
+/* $OpenBSD: if_sisreg.h,v 1.33 2014/07/08 05:35:18 dlg Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
@@ -385,9 +385,9 @@ struct sis_list_data {
};
struct sis_ring_data {
+ struct if_rxring sis_rx_ring;
int sis_rx_prod;
int sis_rx_cons;
- int sis_rx_cnt;
int sis_tx_prod;
int sis_tx_cons;
int sis_tx_cnt;
diff --git a/sys/dev/pci/if_vic.c b/sys/dev/pci/if_vic.c
index 247c880f12c..649a25eee29 100644
--- a/sys/dev/pci/if_vic.c
+++ b/sys/dev/pci/if_vic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vic.c,v 1.77 2011/11/29 11:53:25 jsing Exp $ */
+/* $OpenBSD: if_vic.c,v 1.78 2014/07/08 05:35:19 dlg Exp $ */
/*
* Copyright (c) 2006 Reyk Floeter <reyk@openbsd.org>
@@ -290,10 +290,10 @@ struct vic_softc {
struct vic_data *sc_data;
struct {
+ struct if_rxring ring;
struct vic_rxbuf *bufs;
struct vic_rxdesc *slots;
int end;
- int len;
u_int pktlen;
} sc_rxq[VIC_NRXRINGS];
@@ -486,9 +486,6 @@ vic_attach(struct device *parent, struct device *self, void *aux)
IFQ_SET_MAXLEN(&ifp->if_snd, sc->sc_ntxbuf - 1);
IFQ_SET_READY(&ifp->if_snd);
- m_clsetwms(ifp, MCLBYTES, 2, sc->sc_nrxbuf - 1);
- m_clsetwms(ifp, 4096, 2, sc->sc_nrxbuf - 1);
-
ifp->if_capabilities = IFCAP_VLAN_MTU;
#if 0
@@ -608,7 +605,6 @@ vic_alloc_data(struct vic_softc *sc)
for (q = 0; q < VIC_NRXRINGS; q++) {
sc->sc_rxq[q].slots = (struct vic_rxdesc *)&kva[offset];
sc->sc_data->vd_rx_offset[q] = offset;
- sc->sc_data->vd_rx[q].length = sc->sc_nrxbuf;
for (i = 0; i < sc->sc_nrxbuf; i++) {
rxd = &sc->sc_rxq[q].slots[i];
@@ -644,8 +640,10 @@ vic_rx_fill(struct vic_softc *sc, int q)
{
struct vic_rxbuf *rxb;
struct vic_rxdesc *rxd;
+ u_int slots;
- while (sc->sc_rxq[q].len < sc->sc_data->vd_rx[q].length) {
+ for (slots = if_rxr_get(&sc->sc_rxq[q].ring, sc->sc_nrxbuf);
+ slots > 0; slots--) {
rxb = &sc->sc_rxq[q].bufs[sc->sc_rxq[q].end];
rxd = &sc->sc_rxq[q].slots[sc->sc_rxq[q].end];
@@ -663,8 +661,8 @@ vic_rx_fill(struct vic_softc *sc, int q)
rxd->rx_owner = VIC_OWNER_NIC;
VIC_INC(sc->sc_rxq[q].end, sc->sc_data->vd_rx[q].length);
- sc->sc_rxq[q].len++;
}
+ if_rxr_put(&sc->sc_rxq[q].ring, slots);
}
int
@@ -695,9 +693,9 @@ vic_init_data(struct vic_softc *sc)
rxd->rx_length = 0;
rxd->rx_owner = VIC_OWNER_DRIVER;
}
-
- sc->sc_rxq[q].len = 0;
sc->sc_rxq[q].end = 0;
+
+ if_rxr_init(&sc->sc_rxq[q].ring, 2, sc->sc_nrxbuf - 1);
vic_rx_fill(sc, q);
}
@@ -825,7 +823,7 @@ vic_rx_proc(struct vic_softc *sc, int q)
bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_map, 0, sc->sc_dma_size,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- while (sc->sc_rxq[q].len > 0) {
+ while (if_rxr_inuse(&sc->sc_rxq[q].ring) > 0) {
idx = sc->sc_data->vd_rx[q].nextidx;
if (idx >= sc->sc_data->vd_rx[q].length) {
ifp->if_ierrors++;
@@ -875,9 +873,8 @@ vic_rx_proc(struct vic_softc *sc, int q)
ether_input_mbuf(ifp, m);
nextp:
- sc->sc_rxq[q].len--;
- VIC_INC(sc->sc_data->vd_rx[q].nextidx,
- sc->sc_data->vd_rx[q].length);
+ if_rxr_put(&sc->sc_rxq[q].ring, 1);
+ VIC_INC(sc->sc_data->vd_rx[q].nextidx, sc->sc_nrxbuf);
}
vic_rx_fill(sc, q);
@@ -1330,7 +1327,7 @@ vic_alloc_mbuf(struct vic_softc *sc, bus_dmamap_t map, u_int pktlen)
{
struct mbuf *m = NULL;
- m = MCLGETI(NULL, M_DONTWAIT, &sc->sc_ac.ac_if, pktlen);
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, pktlen);
if (!m)
return (NULL);
m->m_data += ETHER_ALIGN;
diff --git a/sys/dev/pci/if_vio.c b/sys/dev/pci/if_vio.c
index 3621489679b..fb22fd2dd6f 100644
--- a/sys/dev/pci/if_vio.c
+++ b/sys/dev/pci/if_vio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vio.c,v 1.16 2014/06/17 19:46:13 sf Exp $ */
+/* $OpenBSD: if_vio.c,v 1.17 2014/07/08 05:35:19 dlg Exp $ */
/*
* Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg.
@@ -223,6 +223,7 @@ struct vio_softc {
bus_dmamap_t *sc_tx_dmamaps;
struct mbuf **sc_rx_mbufs;
struct mbuf **sc_tx_mbufs;
+ struct if_rxring sc_rx_ring;
enum vio_ctrl_state sc_ctrl_inuse;
@@ -595,7 +596,6 @@ vio_attach(struct device *parent, struct device *self, void *aux)
ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
vsc->sc_config_change = vio_config_change;
- m_clsetwms(ifp, MCLBYTES, 4, sc->sc_vq[VQRX].vq_num);
timeout_set(&sc->sc_txtick, vio_txtick, &sc->sc_vq[VQTX]);
timeout_set(&sc->sc_rxtick, vio_rxtick, &sc->sc_vq[VQRX]);
@@ -667,6 +667,7 @@ vio_init(struct ifnet *ifp)
struct vio_softc *sc = ifp->if_softc;
vio_stop(ifp, 0);
+ if_rxr_init(&sc->sc_rx_ring, 4, sc->sc_vq[VQRX].vq_num);
vio_populate_rx_mbufs(sc);
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
@@ -878,7 +879,7 @@ vio_add_rx_mbuf(struct vio_softc *sc, int i)
struct mbuf *m;
int r;
- m = MCLGETI(NULL, M_DONTWAIT, &sc->sc_ac.ac_if, MCLBYTES);
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
if (m == NULL)
return ENOBUFS;
sc->sc_rx_mbufs[i] = m;
@@ -908,11 +909,13 @@ void
vio_populate_rx_mbufs(struct vio_softc *sc)
{
struct virtio_softc *vsc = sc->sc_virtio;
- int i, r, ndone = 0;
+ int r, done = 0;
+ u_int slots;
struct virtqueue *vq = &sc->sc_vq[VQRX];
int mrg_rxbuf = VIO_HAVE_MRG_RXBUF(sc);
- for (i = 0; i < vq->vq_num; i++) {
+ for (slots = if_rxr_get(&sc->sc_rx_ring, vq->vq_num);
+ slots > 0; slots--) {
int slot;
r = virtio_enqueue_prep(vq, &slot);
if (r == EAGAIN)
@@ -948,9 +951,11 @@ vio_populate_rx_mbufs(struct vio_softc *sc)
sc->sc_hdr_size, MCLBYTES - sc->sc_hdr_size, 0);
}
virtio_enqueue_commit(vsc, vq, slot, 0);
- ndone++;
+ done = 1;
}
- if (ndone > 0)
+ if_rxr_put(&sc->sc_rx_ring, slots);
+
+ if (done)
virtio_notify(vsc, vq);
if (vq->vq_used_idx != vq->vq_avail_idx)
timeout_del(&sc->sc_rxtick);
@@ -979,6 +984,7 @@ vio_rxeof(struct vio_softc *sc)
bus_dmamap_unload(vsc->sc_dmat, sc->sc_rx_dmamaps[slot]);
sc->sc_rx_mbufs[slot] = NULL;
virtio_dequeue_commit(vq, slot);
+ if_rxr_put(&sc->sc_rx_ring, 1);
m->m_pkthdr.rcvif = ifp;
m->m_len = m->m_pkthdr.len = len;
m->m_pkthdr.csum_flags = 0;
diff --git a/sys/dev/pci/if_vmx.c b/sys/dev/pci/if_vmx.c
index f0712005afa..386c3fa8627 100644
--- a/sys/dev/pci/if_vmx.c
+++ b/sys/dev/pci/if_vmx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vmx.c,v 1.16 2014/01/22 06:04:17 brad Exp $ */
+/* $OpenBSD: if_vmx.c,v 1.17 2014/07/08 05:35:19 dlg Exp $ */
/*
* Copyright (c) 2013 Tsubai Masanari
@@ -71,6 +71,7 @@ struct vmxnet3_txring {
struct vmxnet3_rxring {
struct mbuf *m[NRXDESC];
bus_dmamap_t dmap[NRXDESC];
+ struct if_rxring rxr;
struct vmxnet3_rxdesc *rxd;
u_int fill;
u_int8_t gen;
@@ -483,17 +484,21 @@ vmxnet3_rxinit(struct vmxnet3_softc *sc, struct vmxnet3_rxqueue *rq)
{
struct vmxnet3_rxring *ring;
struct vmxnet3_comp_ring *comp_ring;
- int i, idx;
+ int i;
+ u_int slots;
for (i = 0; i < 2; i++) {
ring = &rq->cmd_ring[i];
ring->fill = 0;
ring->gen = 1;
bzero(ring->rxd, NRXDESC * sizeof ring->rxd[0]);
- for (idx = 0; idx < NRXDESC; idx++) {
+ if_rxr_init(&ring->rxr, 2, NRXDESC - 1);
+ for (slots = if_rxr_get(&ring->rxr, NRXDESC);
+ slots > 0; slots--) {
if (vmxnet3_getbuf(sc, ring))
break;
}
+ if_rxr_put(&ring->rxr, slots);
}
comp_ring = &rq->comp_ring;
comp_ring->next = 0;
@@ -688,6 +693,7 @@ vmxnet3_rxintr(struct vmxnet3_softc *sc, struct vmxnet3_rxqueue *rq)
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
struct mbuf *m;
int idx, len;
+ u_int slots;
for (;;) {
rxcd = &comp_ring->rxcd[comp_ring->next];
@@ -713,6 +719,7 @@ vmxnet3_rxintr(struct vmxnet3_softc *sc, struct vmxnet3_rxqueue *rq)
VMXNET3_RXC_LEN_M);
m = ring->m[idx];
ring->m[idx] = NULL;
+ if_rxr_put(&ring->rxr, 1);
bus_dmamap_unload(sc->sc_dmat, ring->dmap[idx]);
if (m == NULL)
@@ -772,13 +779,11 @@ skip_buffer:
/* XXX Should we (try to) allocate buffers for ring 2 too? */
ring = &rq->cmd_ring[0];
- for (;;) {
- idx = ring->fill;
- if (ring->m[idx])
- return;
+ for (slots = if_rxr_get(&ring->rxr, NRXDESC); slots > 0; slots--) {
if (vmxnet3_getbuf(sc, ring))
- return;
+ break;
}
+ if_rxr_put(&ring->rxr, slots);
}
void
@@ -855,7 +860,6 @@ vmxnet3_getbuf(struct vmxnet3_softc *sc, struct vmxnet3_rxring *ring)
{
int idx = ring->fill;
struct vmxnet3_rxdesc *rxd = &ring->rxd[idx];
- struct ifnet *ifp = &sc->sc_arpcom.ac_if;
struct mbuf *m;
int btype;
@@ -874,7 +878,7 @@ vmxnet3_getbuf(struct vmxnet3_softc *sc, struct vmxnet3_rxring *ring)
btype = VMXNET3_BTYPE_BODY;
#endif
- m = MCLGETI(NULL, M_DONTWAIT, ifp, JUMBO_LEN);
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, JUMBO_LEN);
if (m == NULL)
return -1;
diff --git a/sys/dev/pci/if_vr.c b/sys/dev/pci/if_vr.c
index 923664c04e6..9a6f9441abc 100644
--- a/sys/dev/pci/if_vr.c
+++ b/sys/dev/pci/if_vr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vr.c,v 1.133 2014/04/19 14:47:51 henning Exp $ */
+/* $OpenBSD: if_vr.c,v 1.134 2014/07/08 05:35:19 dlg Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -678,7 +678,6 @@ vr_attach(struct device *parent, struct device *self, void *aux)
/*
* Call MI attach routines.
*/
- m_clsetwms(ifp, MCLBYTES, 2, VR_RX_LIST_CNT - 1);
if_attach(ifp);
ether_ifattach(ifp);
return;
@@ -794,7 +793,7 @@ vr_list_rx_init(struct vr_softc *sc)
}
cd->vr_rx_prod = cd->vr_rx_cons = &cd->vr_rx_chain[0];
- cd->vr_rx_cnt = 0;
+ if_rxr_init(&sc->sc_rxring, 2, VR_RX_LIST_CNT - 1);
vr_fill_rx_ring(sc);
return (0);
@@ -805,19 +804,22 @@ vr_fill_rx_ring(struct vr_softc *sc)
{
struct vr_chain_data *cd;
struct vr_list_data *ld;
+ u_int slots;
cd = &sc->vr_cdata;
ld = sc->vr_ldata;
- while (cd->vr_rx_cnt < VR_RX_LIST_CNT) {
- if (vr_alloc_mbuf(sc, cd->vr_rx_prod)) {
- if (cd->vr_rx_cnt == 0)
- timeout_add(&sc->sc_rxto, 0);
+ for (slots = if_rxr_get(&sc->sc_rxring, VR_RX_LIST_CNT);
+ slots > 0; slots--) {
+ if (vr_alloc_mbuf(sc, cd->vr_rx_prod))
break;
- }
+
cd->vr_rx_prod = cd->vr_rx_prod->vr_nextdesc;
- cd->vr_rx_cnt++;
}
+
+ if_rxr_put(&sc->sc_rxring, slots);
+ if (if_rxr_inuse(&sc->sc_rxring) == 0)
+ timeout_add(&sc->sc_rxto, 0);
}
/*
@@ -835,7 +837,7 @@ vr_rxeof(struct vr_softc *sc)
ifp = &sc->arpcom.ac_if;
- while(sc->vr_cdata.vr_rx_cnt > 0) {
+ while (if_rxr_inuse(&sc->sc_rxring) > 0) {
bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap.vrm_map,
0, sc->sc_listmap.vrm_map->dm_mapsize,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
@@ -849,7 +851,7 @@ vr_rxeof(struct vr_softc *sc)
m = cur_rx->vr_mbuf;
cur_rx->vr_mbuf = NULL;
sc->vr_cdata.vr_rx_cons = cur_rx->vr_nextdesc;
- sc->vr_cdata.vr_rx_cnt--;
+ if_rxr_put(&sc->sc_rxring, 1);
/*
* If an error occurs, update stats, clear the
@@ -1094,9 +1096,9 @@ vr_rxtick(void *xsc)
int s;
s = splnet();
- if (sc->vr_cdata.vr_rx_cnt == 0) {
+ if (if_rxr_inuse(&sc->sc_rxring) == 0) {
vr_fill_rx_ring(sc);
- if (sc->vr_cdata.vr_rx_cnt == 0)
+ if (if_rxr_inuse(&sc->sc_rxring) == 0)
timeout_add(&sc->sc_rxto, 1);
}
splx(s);
@@ -1726,7 +1728,7 @@ vr_alloc_mbuf(struct vr_softc *sc, struct vr_chain_onefrag *r)
if (r == NULL)
return (EINVAL);
- m = MCLGETI(NULL, M_DONTWAIT, &sc->arpcom.ac_if, MCLBYTES);
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
if (!m)
return (ENOBUFS);
diff --git a/sys/dev/pci/if_vrreg.h b/sys/dev/pci/if_vrreg.h
index d46638868cc..799d7dc510b 100644
--- a/sys/dev/pci/if_vrreg.h
+++ b/sys/dev/pci/if_vrreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vrreg.h,v 1.35 2013/02/09 19:17:52 sthen Exp $ */
+/* $OpenBSD: if_vrreg.h,v 1.36 2014/07/08 05:35:19 dlg Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -468,7 +468,6 @@ struct vr_chain_data {
struct vr_chain_onefrag *vr_rx_cons;
struct vr_chain_onefrag *vr_rx_prod;
- int vr_rx_cnt;
struct vr_chain *vr_tx_cons;
struct vr_chain *vr_tx_prod;
@@ -524,6 +523,7 @@ struct vr_softc {
struct timeout sc_rxto;
struct vr_dmamem sc_listmap; /* descriptor list map */
struct vr_dmamem sc_zeromap; /* zero pad map */
+ struct if_rxring sc_rxring;
int sc_rxbufs;
int vr_link;
int vr_quirks;
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index 2f1adcabc43..016bd27380f 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_mbuf.c,v 1.186 2014/06/18 11:09:58 dlg Exp $ */
+/* $OpenBSD: uipc_mbuf.c,v 1.187 2014/07/08 05:35:19 dlg Exp $ */
/* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */
/*
@@ -343,6 +343,9 @@ m_cltick(void *arg)
{
extern int ticks;
+ if (ticks - m_clticks > 1)
+ mcllivelocks++;
+
m_clticks = ticks;
timeout_add(&m_cltick_tmo, 1);
}
@@ -365,7 +368,6 @@ m_cldrop(struct ifnet *ifp, int pi)
* decrease their cluster allocation high water marks.
*/
m_livelock = 1;
- mcllivelocks++;
m_clticks = liveticks = ticks;
} else if (m_livelock && (ticks - liveticks) > 4)
m_livelock = 0; /* Let the high water marks grow again */
diff --git a/usr.bin/systat/mbufs.c b/usr.bin/systat/mbufs.c
index bbd3980405c..fef6095c614 100644
--- a/usr.bin/systat/mbufs.c
+++ b/usr.bin/systat/mbufs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mbufs.c,v 1.34 2014/07/02 00:12:34 dlg Exp $ */
+/* $OpenBSD: mbufs.c,v 1.35 2014/07/08 05:35:19 dlg Exp $ */
/*
* Copyright (c) 2008 Can Erkin Acar <canacar@openbsd.org>
*
@@ -21,6 +21,8 @@
#include <sys/mbuf.h>
#include <sys/pool.h>
#include <net/if.h>
+#include <sys/sockio.h>
+#include <sys/ioctl.h>
#include <err.h>
#include <errno.h>
@@ -30,32 +32,27 @@
#include "systat.h"
-
-/* pool info for mcl* pools */
-struct mclpool_info {
- char title[16];
- int pool_offset;
- int size;
-} mclpools[MCLPOOLS];
-
-int mclpool_count = 0;
+/* pool info */
int mbpool_index = -1;
+int mclpools_index[MCLPOOLS];
+int mclpool_count = 0;
struct kinfo_pool mbpool;
u_int mcllivelocks, mcllivelocks_cur, mcllivelocks_diff;
/* interfaces */
-static int num_ifs;
+static int num_ifs = 0;
struct if_info {
char name[16];
- struct if_data data;
+ struct if_rxrinfo data;
} *interfaces = NULL;
+static int sock;
+
void print_mb(void);
int read_mb(void);
int select_mb(void);
static void showmbuf(struct if_info *, int, int);
-
/* Define fields */
field_def fields_mbuf[] = {
{"IFACE", 8, 16, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
@@ -104,14 +101,35 @@ field_view views_mb[] = {
int
initmembufs(void)
{
+ struct if_rxring_info *ifr;
field_view *v;
int i, mib[4], npools;
struct kinfo_pool pool;
char pname[32];
size_t size;
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock == -1) {
+ err(1, "socket()");
+ /* NOTREACHED */
+ }
+
+ /* set up the "System" interface */
+
+ interfaces = calloc(1, sizeof(*interfaces));
+ if (interfaces == NULL)
+ err(1, "calloc: interfaces");
+
+ ifr = calloc(MCLPOOLS, sizeof(*ifr));
+ if (ifr == NULL)
+ err(1, "calloc: system pools");
+
+ strlcpy(interfaces[0].name, "System", sizeof(interfaces[0].name));
+ interfaces[0].data.ifri_total = MCLPOOLS;
+ interfaces[0].data.ifri_entries = ifr;
+ num_ifs = 1;
+
/* go through all pools to identify mbuf and cluster pools */
- bzero(mclpools, sizeof(mclpools));
mib[0] = CTL_KERN;
mib[1] = KERN_POOL;
@@ -154,13 +172,12 @@ initmembufs(void)
/* NOTREACHED */
}
- mclpools[mclpool_count].size = pool.pr_size;
- mclpools[mclpool_count].pool_offset = i;
- snprintf(mclpools[mclpool_count].title,
- sizeof(mclpools[0].title), "%dk",
+ snprintf(ifr[mclpool_count].ifr_name,
+ sizeof(ifr[mclpool_count].ifr_name), "%dk",
pool.pr_size / 1024);
+ ifr[mclpool_count].ifr_size = pool.pr_size;
- mclpool_count++;
+ mclpools_index[mclpool_count++] = i;
}
if (mclpool_count != MCLPOOLS)
@@ -170,7 +187,6 @@ initmembufs(void)
for (v = views_mb; v->name != NULL; v++)
add_view(v);
-
/* finally read it once */
read_mb();
@@ -190,8 +206,10 @@ read_mb(void)
struct kinfo_pool pool;
struct ifaddrs *ifap, *ifa;
struct if_info *ifi;
+ struct if_rxring_info *ifr;
int mib[4];
- int i, p, nif, ret = 1;
+ int i, p, nif, ret = 1, rv;
+ u_int rings;
size_t size;
mib[0] = CTL_KERN;
@@ -212,26 +230,24 @@ read_mb(void)
}
nif = 1;
- for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next)
- if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_LINK)
- nif++;
-
- if (interfaces == NULL || num_ifs < nif) {
- size_t len = sizeof(*ifi) * nif;
- if (nif > SIZE_MAX / sizeof(*ifi)) {
- error("overflow allocting %u interfaces", nif);
- goto exit;
- }
+ for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr == NULL ||
+ ifa->ifa_addr->sa_family != AF_LINK)
+ continue;
+
+ nif++;
+ }
- ifi = realloc(interfaces, len);
+ if (num_ifs < nif) {
+ ifi = reallocarray(interfaces, nif, sizeof(*interfaces));
if (ifi == NULL) {
- error("realloc: out of memory allocating %lld bytes",
- (long long) len);
+ error("reallocarray: %d interfaces", nif);
goto exit;
}
interfaces = ifi;
- num_ifs = nif;
+ while (num_ifs < nif)
+ memset(&interfaces[num_ifs++], 0, sizeof(*interfaces));
}
/* Fill in the "real" interfaces */
@@ -243,17 +259,47 @@ read_mb(void)
continue;
strlcpy(ifi->name, ifa->ifa_name, sizeof(ifi->name));
+ for (;;) {
+ struct ifreq ifreq;
+ rings = ifi->data.ifri_total;
+
+ memset(&ifreq, 0, sizeof(ifreq));
+ strlcpy(ifreq.ifr_name, ifa->ifa_name,
+ sizeof(ifreq.ifr_name));
+ ifreq.ifr_data = (caddr_t)&ifi->data;
+
+ rv = ioctl(sock, SIOCGIFRXR, &ifreq);
+ if (rv == -1) {
+ if (errno == ENOTTY) {
+ free(ifi->data.ifri_entries);
+ ifi->data.ifri_total = 0;
+ ifi->data.ifri_entries = NULL;
+ break;
+ }
+
+ error("ioctl(SIOCGIFRXR) %s", strerror(errno));
+ break;
+ }
+
+ if (rings >= ifi->data.ifri_total)
+ break;
+
+ ifr = reallocarray(ifi->data.ifri_entries,
+ ifi->data.ifri_total, sizeof(*ifr));
+ if (ifr == NULL) {
+ ifi->data.ifri_total = rings;
+ error("reallocarray: %u rings",
+ ifi->data.ifri_total);
+ goto exit;
+ }
+
+ ifi->data.ifri_entries = ifr;
+ }
- if (ifa->ifa_data)
- memcpy(&ifi->data, ifa->ifa_data, sizeof(ifi->data));
- else
- bzero(&ifi->data, sizeof(ifi->data));
ifi++;
}
/* Fill in the "System" entry from pools */
- bzero(interfaces, sizeof(interfaces[0]));
- strlcpy(interfaces[0].name, "System", sizeof(interfaces[0].name));
mib[0] = CTL_KERN;
mib[1] = KERN_POOL;
@@ -267,9 +313,9 @@ read_mb(void)
}
for (i = 0; i < mclpool_count; i++) {
- struct mclpool *mp = &interfaces[0].data.ifi_mclpool[i];
+ ifr = &interfaces[0].data.ifri_entries[i];
- mib[3] = mclpools[i].pool_offset;
+ mib[3] = mclpools_index[i];
size = sizeof(pool);
if (sysctl(mib, 4, &pool, &size, NULL, 0) < 0) {
@@ -277,9 +323,8 @@ read_mb(void)
continue;
}
- mp->mcl_livelocks = mcllivelocks;
- mp->mcl_alive = pool.pr_nget - pool.pr_nput;
- mp->mcl_hwm = pool.pr_hiwat;
+ ifr->ifr_info.rxr_alive = pool.pr_nget - pool.pr_nput;
+ ifr->ifr_info.rxr_hwm = pool.pr_hiwat;
}
num_disp = 1;
@@ -288,9 +333,9 @@ read_mb(void)
for (i = 0; i < num_ifs; i++) {
struct if_info *ifi = &interfaces[i];
int pnd = num_disp;
- for (p = 0; p < mclpool_count; p++) {
- struct mclpool *mp = &ifi->data.ifi_mclpool[p];
- if (mp->mcl_alive == 0)
+ for (p = 0; p < ifi->data.ifri_total; p++) {
+ ifr = &ifi->data.ifri_entries[p];
+ if (ifr->ifr_info.rxr_alive == 0);
continue;
num_disp++;
}
@@ -318,9 +363,9 @@ print_mb(void)
if (maxprint > 0 && count >= maxprint)
return;
- for (p = 0; p < mclpool_count; p++) {
- struct mclpool *mp = &ifi->data.ifi_mclpool[p];
- if (mp->mcl_alive == 0)
+ for (p = 0; p < ifi->data.ifri_total; p++) {
+ struct if_rxring_info *ifr = &ifi->data.ifri_entries[p];
+ if (ifr->ifr_info.rxr_alive == 0)
continue;
if (n++ >= dispstart) {
showmbuf(ifi, p, showif);
@@ -336,8 +381,6 @@ print_mb(void)
count++;
}
}
-
-
}
}
@@ -356,20 +399,16 @@ showmbuf(struct if_info *ifi, int p, int showif)
}
if (p >= 0 && p < mclpool_count) {
- struct mclpool *mp = &ifi->data.ifi_mclpool[p];
- int livelocks_diff;
-
- livelocks_diff = mp->mcl_livelocks - mcllivelocks;
- if (livelocks_diff)
- print_fld_uint(FLD_MB_LLOCKS, livelocks_diff);
- print_fld_str(FLD_MB_MSIZE, mclpools[p].title);
- print_fld_uint(FLD_MB_MALIVE, mp->mcl_alive);
- if (mp->mcl_lwm)
- print_fld_size(FLD_MB_MLWM, mp->mcl_lwm);
- if (mp->mcl_hwm)
- print_fld_size(FLD_MB_MHWM, mp->mcl_hwm);
- if (mp->mcl_cwm)
- print_fld_size(FLD_MB_MCWM, mp->mcl_cwm);
+ struct if_rxring_info *ifr = &ifi->data.ifri_entries[p];
+ struct if_rxring *rxr= &ifr->ifr_info;
+ print_fld_uint(FLD_MB_MSIZE, ifr->ifr_size);
+ print_fld_uint(FLD_MB_MALIVE, rxr->rxr_alive);
+ if (rxr->rxr_lwm)
+ print_fld_size(FLD_MB_MLWM, rxr->rxr_lwm);
+ if (rxr->rxr_hwm)
+ print_fld_size(FLD_MB_MHWM, rxr->rxr_hwm);
+ if (rxr->rxr_cwm)
+ print_fld_size(FLD_MB_MCWM, rxr->rxr_cwm);
}
end_line();