diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2014-07-08 05:35:20 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2014-07-08 05:35:20 +0000 |
commit | 4930c61b730e44cdce66c7f71fa9f703fcae2b38 (patch) | |
tree | 69bcdb82287306b3e015c5b2778bccc9790f2f81 /sys/dev/pci | |
parent | f201a4bbc9d2fe8c3664f8b02ebf1ac13ae5b94e (diff) |
cut things that relied on mclgeti for rx ring accounting/restriction over
to using if_rxr.
cut the reporting systat did over to the rxr ioctl.
tested as much as i can on alpha, amd64, and sparc64.
mpi@ has run it on macppc.
ok mpi@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/if_bge.c | 88 | ||||
-rw-r--r-- | sys/dev/pci/if_bgereg.h | 6 | ||||
-rw-r--r-- | sys/dev/pci/if_bnx.c | 60 | ||||
-rw-r--r-- | sys/dev/pci/if_bnxreg.h | 4 | ||||
-rw-r--r-- | sys/dev/pci/if_em.c | 45 | ||||
-rw-r--r-- | sys/dev/pci/if_em.h | 4 | ||||
-rw-r--r-- | sys/dev/pci/if_ix.c | 31 | ||||
-rw-r--r-- | sys/dev/pci/if_ix.h | 4 | ||||
-rw-r--r-- | sys/dev/pci/if_msk.c | 40 | ||||
-rw-r--r-- | sys/dev/pci/if_mskvar.h | 8 | ||||
-rw-r--r-- | sys/dev/pci/if_myx.c | 62 | ||||
-rw-r--r-- | sys/dev/pci/if_oce.c | 36 | ||||
-rw-r--r-- | sys/dev/pci/if_sis.c | 20 | ||||
-rw-r--r-- | sys/dev/pci/if_sisreg.h | 4 | ||||
-rw-r--r-- | sys/dev/pci/if_vic.c | 27 | ||||
-rw-r--r-- | sys/dev/pci/if_vio.c | 20 | ||||
-rw-r--r-- | sys/dev/pci/if_vmx.c | 24 | ||||
-rw-r--r-- | sys/dev/pci/if_vr.c | 30 | ||||
-rw-r--r-- | sys/dev/pci/if_vrreg.h | 4 |
19 files changed, 298 insertions, 219 deletions
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; |