diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2015-11-09 00:29:07 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2015-11-09 00:29:07 +0000 |
commit | 0d86db08091aec725d213488e002e692ae87610f (patch) | |
tree | 842b84c10208a30f61622b75e65e9c8740631c9d /sys/dev/pci | |
parent | d1a8c3966d4b13ef9211587439a4896144eafcf1 (diff) |
rework the start routines to avoid IF_PREPEND.
IF_PREPEND assumes the underlying send queue is priq, while hfsc may be
enabled on it.
the previous code pattern to DEQUEUE, try and encap the mbuf on the
ring, and if that failed cos there was no space it would PREPEND
it.
now it checks for space on the ring before it attempts to DEQUEUE.
failure to encap means the mbuf is now unconditionally dropped.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/if_age.c | 49 | ||||
-rw-r--r-- | sys/dev/pci/if_alc.c | 52 | ||||
-rw-r--r-- | sys/dev/pci/if_ale.c | 50 | ||||
-rw-r--r-- | sys/dev/pci/if_jme.c | 47 |
4 files changed, 74 insertions, 124 deletions
diff --git a/sys/dev/pci/if_age.c b/sys/dev/pci/if_age.c index a6d2a769ce6..9b285cb00df 100644 --- a/sys/dev/pci/if_age.c +++ b/sys/dev/pci/if_age.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_age.c,v 1.29 2015/10/25 13:04:28 mpi Exp $ */ +/* $OpenBSD: if_age.c,v 1.30 2015/11/09 00:29:06 dlg Exp $ */ /*- * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org> @@ -89,7 +89,7 @@ void age_dma_free(struct age_softc *); void age_get_macaddr(struct age_softc *); void age_phy_reset(struct age_softc *); -int age_encap(struct age_softc *, struct mbuf **); +int age_encap(struct age_softc *, struct mbuf *); void age_init_tx_ring(struct age_softc *); int age_init_rx_ring(struct age_softc *); void age_init_rr_ring(struct age_softc *); @@ -957,7 +957,7 @@ void age_start(struct ifnet *ifp) { struct age_softc *sc = ifp->if_softc; - struct mbuf *m_head; + struct mbuf *m; int enq; if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) @@ -969,8 +969,14 @@ age_start(struct ifnet *ifp) enq = 0; for (;;) { - IFQ_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) + if (sc->age_cdata.age_tx_cnt + AGE_MAXTXSEGS >= + AGE_TX_RING_CNT - 2) { + ifp->if_flags |= IFF_OACTIVE; + break; + } + + IFQ_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) break; /* @@ -978,14 +984,9 @@ age_start(struct ifnet *ifp) * don't have room, set the OACTIVE flag and wait * for the NIC to drain the ring. */ - if (age_encap(sc, &m_head)) { - if (m_head == NULL) - ifp->if_oerrors++; - else { - IF_PREPEND(&ifp->if_snd, m_head); - ifp->if_flags |= IFF_OACTIVE; - } - break; + if (age_encap(sc, m) != 0) { + ifp->if_oerrors++; + continue; } enq = 1; @@ -995,7 +996,7 @@ age_start(struct ifnet *ifp) * to him. */ if (ifp->if_bpf != NULL) - bpf_mtap_ether(ifp->if_bpf, m_head, BPF_DIRECTION_OUT); + bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT); #endif } @@ -1115,16 +1116,14 @@ age_mac_config(struct age_softc *sc) } int -age_encap(struct age_softc *sc, struct mbuf **m_head) +age_encap(struct age_softc *sc, struct mbuf *m) { struct age_txdesc *txd, *txd_last; struct tx_desc *desc; - struct mbuf *m; bus_dmamap_t map; uint32_t cflags, poff, vtag; int error, i, prod; - m = *m_head; cflags = vtag = 0; poff = 0; @@ -1133,27 +1132,20 @@ age_encap(struct age_softc *sc, struct mbuf **m_head) txd_last = txd; map = txd->tx_dmamap; - error = bus_dmamap_load_mbuf(sc->sc_dmat, map, *m_head, BUS_DMA_NOWAIT); + error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT); if (error != 0 && error != EFBIG) goto drop; if (error != 0) { - if (m_defrag(*m_head, M_DONTWAIT)) { + if (m_defrag(m, M_DONTWAIT)) { error = ENOBUFS; goto drop; } - error = bus_dmamap_load_mbuf(sc->sc_dmat, map, *m_head, + error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT); if (error != 0) goto drop; } - /* Check descriptor overrun. */ - if (sc->age_cdata.age_tx_cnt + map->dm_nsegs >= AGE_TX_RING_CNT - 2) { - bus_dmamap_unload(sc->sc_dmat, map); - return (ENOBUFS); - } - - m = *m_head; /* Configure Tx IP/TCP/UDP checksum offload. */ if ((m->m_pkthdr.csum_flags & AGE_CSUM_FEATURES) != 0) { cflags |= AGE_TD_CSUM; @@ -1210,8 +1202,7 @@ age_encap(struct age_softc *sc, struct mbuf **m_head) return (0); drop: - m_freem(*m_head); - *m_head = NULL; + m_freem(m); return (error); } diff --git a/sys/dev/pci/if_alc.c b/sys/dev/pci/if_alc.c index 75267481b18..d0344b85821 100644 --- a/sys/dev/pci/if_alc.c +++ b/sys/dev/pci/if_alc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_alc.c,v 1.35 2015/10/25 13:04:28 mpi Exp $ */ +/* $OpenBSD: if_alc.c,v 1.36 2015/11/09 00:29:06 dlg Exp $ */ /*- * Copyright (c) 2009, Pyun YongHyeon <yongari@FreeBSD.org> * All rights reserved. @@ -83,7 +83,7 @@ void alc_aspm(struct alc_softc *, uint64_t); void alc_disable_l0s_l1(struct alc_softc *); int alc_dma_alloc(struct alc_softc *); void alc_dma_free(struct alc_softc *); -int alc_encap(struct alc_softc *, struct mbuf **); +int alc_encap(struct alc_softc *, struct mbuf *); void alc_get_macaddr(struct alc_softc *); void alc_init_cmb(struct alc_softc *); void alc_init_rr_ring(struct alc_softc *); @@ -1265,16 +1265,14 @@ alc_dma_free(struct alc_softc *sc) } int -alc_encap(struct alc_softc *sc, struct mbuf **m_head) +alc_encap(struct alc_softc *sc, struct mbuf *m) { struct alc_txdesc *txd, *txd_last; struct tx_desc *desc; - struct mbuf *m; bus_dmamap_t map; uint32_t cflags, poff, vtag; int error, idx, prod; - m = *m_head; cflags = vtag = 0; poff = 0; @@ -1283,30 +1281,23 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head) txd_last = txd; map = txd->tx_dmamap; - error = bus_dmamap_load_mbuf(sc->sc_dmat, map, *m_head, BUS_DMA_NOWAIT); + error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT); if (error != 0 && error != EFBIG) goto drop; if (error != 0) { - if (m_defrag(*m_head, M_DONTWAIT)) { + if (m_defrag(m, M_DONTWAIT)) { error = ENOBUFS; goto drop; } - error = bus_dmamap_load_mbuf(sc->sc_dmat, map, *m_head, + error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT); if (error != 0) goto drop; } - /* Check descriptor overrun. */ - if (sc->alc_cdata.alc_tx_cnt + map->dm_nsegs >= ALC_TX_RING_CNT - 3) { - bus_dmamap_unload(sc->sc_dmat, map); - return (ENOBUFS); - } - bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, BUS_DMASYNC_PREWRITE); - m = *m_head; desc = NULL; idx = 0; #if NVLAN > 0 @@ -1353,8 +1344,7 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head) return (0); drop: - m_freem(*m_head); - *m_head = NULL; + m_freem(m); return (error); } @@ -1362,7 +1352,7 @@ void alc_start(struct ifnet *ifp) { struct alc_softc *sc = ifp->if_softc; - struct mbuf *m_head; + struct mbuf *m; int enq = 0; /* Reclaim transmitted frames. */ @@ -1377,23 +1367,19 @@ alc_start(struct ifnet *ifp) return; for (;;) { - IFQ_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) + if (sc->alc_cdata.alc_tx_cnt + ALC_MAXTXSEGS >= + ALC_TX_RING_CNT - 3) { + ifp->if_flags |= IFF_OACTIVE; break; + } - /* - * Pack the data into the transmit ring. If we - * don't have room, set the OACTIVE flag and wait - * for the NIC to drain the ring. - */ - if (alc_encap(sc, &m_head)) { - if (m_head == NULL) - ifp->if_oerrors++; - else { - IF_PREPEND(&ifp->if_snd, m_head); - ifp->if_flags |= IFF_OACTIVE; - } + IFQ_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) break; + + if (alc_encap(sc, m) != 0) { + ifp->if_oerrors++; + continue; } enq++; @@ -1403,7 +1389,7 @@ alc_start(struct ifnet *ifp) * to him. */ if (ifp->if_bpf != NULL) - bpf_mtap_ether(ifp->if_bpf, m_head, BPF_DIRECTION_OUT); + bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT); #endif } diff --git a/sys/dev/pci/if_ale.c b/sys/dev/pci/if_ale.c index 8622aef9c00..fded56a79b7 100644 --- a/sys/dev/pci/if_ale.c +++ b/sys/dev/pci/if_ale.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ale.c,v 1.40 2015/10/25 13:04:28 mpi Exp $ */ +/* $OpenBSD: if_ale.c,v 1.41 2015/11/09 00:29:06 dlg Exp $ */ /*- * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org> * All rights reserved. @@ -96,7 +96,7 @@ void ale_txeof(struct ale_softc *); int ale_dma_alloc(struct ale_softc *); void ale_dma_free(struct ale_softc *); -int ale_encap(struct ale_softc *, struct mbuf **); +int ale_encap(struct ale_softc *, struct mbuf *); void ale_init_rx_pages(struct ale_softc *); void ale_init_tx_ring(struct ale_softc *); @@ -866,16 +866,14 @@ ale_dma_free(struct ale_softc *sc) } int -ale_encap(struct ale_softc *sc, struct mbuf **m_head) +ale_encap(struct ale_softc *sc, struct mbuf *m) { struct ale_txdesc *txd, *txd_last; struct tx_desc *desc; - struct mbuf *m; bus_dmamap_t map; uint32_t cflags, poff, vtag; int error, i, prod; - m = *m_head; cflags = vtag = 0; poff = 0; @@ -884,30 +882,23 @@ ale_encap(struct ale_softc *sc, struct mbuf **m_head) txd_last = txd; map = txd->tx_dmamap; - error = bus_dmamap_load_mbuf(sc->sc_dmat, map, *m_head, BUS_DMA_NOWAIT); + error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT); if (error != 0 && error != EFBIG) goto drop; if (error != 0) { - if (m_defrag(*m_head, M_DONTWAIT)) { + if (m_defrag(m, M_DONTWAIT)) { error = ENOBUFS; goto drop; } - error = bus_dmamap_load_mbuf(sc->sc_dmat, map, *m_head, + error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT); if (error != 0) goto drop; } - /* Check descriptor overrun. */ - if (sc->ale_cdata.ale_tx_cnt + map->dm_nsegs >= ALE_TX_RING_CNT - 2) { - bus_dmamap_unload(sc->sc_dmat, map); - return (ENOBUFS); - } - bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, BUS_DMASYNC_PREWRITE); - m = *m_head; /* Configure Tx checksum offload. */ if ((m->m_pkthdr.csum_flags & ALE_CSUM_FEATURES) != 0) { /* @@ -980,8 +971,7 @@ ale_encap(struct ale_softc *sc, struct mbuf **m_head) return (0); drop: - m_freem(*m_head); - *m_head = NULL; + m_freem(m); return (error); } @@ -989,7 +979,7 @@ void ale_start(struct ifnet *ifp) { struct ale_softc *sc = ifp->if_softc; - struct mbuf *m_head; + struct mbuf *m; int enq; /* Reclaim transmitted frames. */ @@ -1005,8 +995,15 @@ ale_start(struct ifnet *ifp) enq = 0; for (;;) { - IFQ_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) + /* Check descriptor overrun. */ + if (sc->ale_cdata.ale_tx_cnt + ALE_MAXTXSEGS >= + ALE_TX_RING_CNT - 2) { + ifp->if_flags |= IFF_OACTIVE; + break; + } + + IFQ_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) break; /* @@ -1014,14 +1011,9 @@ ale_start(struct ifnet *ifp) * don't have room, set the OACTIVE flag and wait * for the NIC to drain the ring. */ - if (ale_encap(sc, &m_head)) { - if (m_head == NULL) - ifp->if_oerrors++; - else { - IF_PREPEND(&ifp->if_snd, m_head); - ifp->if_flags |= IFF_OACTIVE; - } - break; + if (ale_encap(sc, m) != 0) { + ifp->if_oerrors++; + continue; } enq = 1; @@ -1032,7 +1024,7 @@ ale_start(struct ifnet *ifp) * to him. */ if (ifp->if_bpf != NULL) - bpf_mtap_ether(ifp->if_bpf, m_head, BPF_DIRECTION_OUT); + bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT); #endif } diff --git a/sys/dev/pci/if_jme.c b/sys/dev/pci/if_jme.c index 3f2e36743a2..0aaf651e77d 100644 --- a/sys/dev/pci/if_jme.c +++ b/sys/dev/pci/if_jme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_jme.c,v 1.42 2015/10/25 13:04:28 mpi Exp $ */ +/* $OpenBSD: if_jme.c,v 1.43 2015/11/09 00:29:06 dlg Exp $ */ /*- * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org> * All rights reserved. @@ -100,7 +100,7 @@ int jme_init_rx_ring(struct jme_softc *); void jme_init_tx_ring(struct jme_softc *); void jme_init_ssb(struct jme_softc *); int jme_newbuf(struct jme_softc *, struct jme_rxdesc *); -int jme_encap(struct jme_softc *, struct mbuf **); +int jme_encap(struct jme_softc *, struct mbuf *); void jme_rxpkt(struct jme_softc *); void jme_tick(void *); @@ -1108,11 +1108,10 @@ jme_setwol(struct jme_softc *sc) #endif int -jme_encap(struct jme_softc *sc, struct mbuf **m_head) +jme_encap(struct jme_softc *sc, struct mbuf *m) { struct jme_txdesc *txd; struct jme_desc *desc; - struct mbuf *m; int error, i, prod; uint32_t cflags; @@ -1120,32 +1119,20 @@ jme_encap(struct jme_softc *sc, struct mbuf **m_head) txd = &sc->jme_cdata.jme_txdesc[prod]; error = bus_dmamap_load_mbuf(sc->sc_dmat, txd->tx_dmamap, - *m_head, BUS_DMA_NOWAIT); + m, BUS_DMA_NOWAIT); if (error != 0 && error != EFBIG) goto drop; if (error != 0) { - if (m_defrag(*m_head, M_DONTWAIT)) { + if (m_defrag(m, M_DONTWAIT)) { error = ENOBUFS; goto drop; } error = bus_dmamap_load_mbuf(sc->sc_dmat, txd->tx_dmamap, - *m_head, BUS_DMA_NOWAIT); + m, BUS_DMA_NOWAIT); if (error != 0) goto drop; } - /* - * Check descriptor overrun. Leave one free descriptor. - * Since we always use 64bit address mode for transmitting, - * each Tx request requires one more dummy descriptor. - */ - if (sc->jme_cdata.jme_tx_cnt + txd->tx_dmamap->dm_nsegs + JME_TXD_RSVD > - JME_TX_RING_CNT - JME_TXD_RSVD) { - bus_dmamap_unload(sc->sc_dmat, txd->tx_dmamap); - return (ENOBUFS); - } - - m = *m_head; cflags = 0; /* Configure checksum offload. */ @@ -1204,8 +1191,7 @@ jme_encap(struct jme_softc *sc, struct mbuf **m_head) return (0); drop: - m_freem(*m_head); - *m_head = NULL; + m_freem(m); return (error); } @@ -1213,7 +1199,7 @@ void jme_start(struct ifnet *ifp) { struct jme_softc *sc = ifp->if_softc; - struct mbuf *m_head; + struct mbuf *m; int enq = 0; /* Reclaim transmitted frames. */ @@ -1238,8 +1224,8 @@ jme_start(struct ifnet *ifp) break; } - IFQ_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) + IFQ_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) break; /* @@ -1247,14 +1233,9 @@ jme_start(struct ifnet *ifp) * don't have room, set the OACTIVE flag and wait * for the NIC to drain the ring. */ - if (jme_encap(sc, &m_head)) { - if (m_head == NULL) - ifp->if_oerrors++; - else { - IF_PREPEND(&ifp->if_snd, m_head); - ifp->if_flags |= IFF_OACTIVE; - } - break; + if (jme_encap(sc, m) != 0) { + ifp->if_oerrors++; + continue; } enq++; @@ -1265,7 +1246,7 @@ jme_start(struct ifnet *ifp) * to him. */ if (ifp->if_bpf != NULL) - bpf_mtap_ether(ifp->if_bpf, m_head, BPF_DIRECTION_OUT); + bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT); #endif } |