Index: net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.571 diff -u -p -r1.571 if.c --- net/if.c 9 Jan 2019 01:14:21 -0000 1.571 +++ net/if.c 26 Feb 2019 06:26:48 -0000 @@ -738,7 +738,7 @@ if_enqueue_ifq(struct ifnet *ifp, struct void if_input(struct ifnet *ifp, struct mbuf_list *ml) { - ifiq_input(&ifp->if_rcv, ml, 2048); + ifiq_input(&ifp->if_rcv, ml); } int @@ -895,12 +895,29 @@ if_ih_remove(struct ifnet *ifp, int (*in } void -if_input_process(struct ifnet *ifp, struct mbuf_list *ml) +if_input_ih(struct ifnet *ifp, struct mbuf *m) { - struct mbuf *m; struct ifih *ifih; struct srp_ref sr; - int s; + + /* + * Pass this mbuf to all input handlers of its + * interface until it is consumed. + */ + SRPL_FOREACH(ifih, &sr, &ifp->if_inputs, ifih_next) { + if ((*ifih->ifih_input)(ifp, m, ifih->ifih_cookie)) + break; + } + SRPL_LEAVE(&sr); + + if (ifih == NULL) + m_freem(m); +} + +void +if_input_process(struct ifnet *ifp, struct mbuf_list *ml) +{ + struct mbuf *m; if (ml_empty(ml)) return; @@ -921,23 +938,31 @@ if_input_process(struct ifnet *ifp, stru * lists. */ NET_RLOCK(); - s = splnet(); - while ((m = ml_dequeue(ml)) != NULL) { - /* - * Pass this mbuf to all input handlers of its - * interface until it is consumed. - */ - SRPL_FOREACH(ifih, &sr, &ifp->if_inputs, ifih_next) { - if ((*ifih->ifih_input)(ifp, m, ifih->ifih_cookie)) - break; - } - SRPL_LEAVE(&sr); + while ((m = ml_dequeue(ml)) != NULL) + if_input_ih(ifp, m); + NET_RUNLOCK(); +} - if (ifih == NULL) +void +if_vinput(struct ifnet *ifp, struct mbuf *m) +{ +#if NBPFILTER > 0 + caddr_t if_bpf = ifp->if_bpf; +#endif + + m->m_pkthdr.ph_ifidx = ifp->if_index; + m->m_pkthdr.ph_rtableid = ifp->if_rdomain; + +#if NBPFILTER > 0 + if (if_bpf) { + if (bpf_mtap_ether(if_bpf, m, BPF_DIRECTION_OUT)) { m_freem(m); + return; + } } - splx(s); - NET_RUNLOCK(); +#endif + + if_input_ih(ifp, m); } void @@ -2980,7 +3005,7 @@ if_rxr_adjust_cwm(struct if_rxring *rxr) rxr->rxr_cwm--; else return; - } else if (rxr->rxr_alive >= rxr->rxr_lwm) + } else if (rxr->rxr_alive >= 2) return; else if (rxr->rxr_cwm < rxr->rxr_hwm) rxr->rxr_cwm++; @@ -2993,11 +3018,14 @@ if_rxr_livelocked(struct if_rxring *rxr) { extern int ticks; - if (ticks - rxr->rxr_adjusted >= 1) { - if (rxr->rxr_cwm > rxr->rxr_lwm) - rxr->rxr_cwm--; + if (rxr->rxr_cwm > rxr->rxr_lwm) { + int lticks = ticks; + int diff = lticks - rxr->rxr_adjusted; - rxr->rxr_adjusted = ticks; + if (diff >= 1) { + rxr->rxr_cwm--; + rxr->rxr_adjusted = lticks; + } } } Index: net/if_var.h =================================================================== RCS file: /cvs/src/sys/net/if_var.h,v retrieving revision 1.94 diff -u -p -r1.94 if_var.h --- net/if_var.h 9 Jan 2019 01:14:21 -0000 1.94 +++ net/if_var.h 26 Feb 2019 06:26:48 -0000 @@ -334,6 +334,7 @@ void if_start(struct ifnet *); int if_enqueue(struct ifnet *, struct mbuf *); int if_enqueue_ifq(struct ifnet *, struct mbuf *); void if_input(struct ifnet *, struct mbuf_list *); +void if_vinput(struct ifnet *, struct mbuf *); void if_input_process(struct ifnet *, struct mbuf_list *); int if_input_local(struct ifnet *, struct mbuf *, sa_family_t); int if_output_local(struct ifnet *, struct mbuf *, sa_family_t); Index: net/if_vlan.c =================================================================== RCS file: /cvs/src/sys/net/if_vlan.c,v retrieving revision 1.183 diff -u -p -r1.183 if_vlan.c --- net/if_vlan.c 15 Feb 2019 13:00:51 -0000 1.183 +++ net/if_vlan.c 26 Feb 2019 06:26:48 -0000 @@ -342,12 +342,12 @@ int vlan_input(struct ifnet *ifp0, struct mbuf *m, void *cookie) { struct ifvlan *ifv; + struct ifnet *ifp; struct ether_vlan_header *evl; struct ether_header *eh; SRPL_HEAD(, ifvlan) *tagh, *list; struct srp_ref sr; u_int tag; - struct mbuf_list ml = MBUF_LIST_INITIALIZER(); u_int16_t etype; eh = mtod(m, struct ether_header *); @@ -359,7 +359,6 @@ vlan_input(struct ifnet *ifp0, struct mb } else if ((etype == ETHERTYPE_VLAN) || (etype == ETHERTYPE_QINQ)) { if (m->m_len < sizeof(*evl) && (m = m_pullup(m, sizeof(*evl))) == NULL) { - ifp0->if_ierrors++; return (1); } @@ -373,12 +372,6 @@ vlan_input(struct ifnet *ifp0, struct mb /* From now on ether_vtag is fine */ tag = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag); - m->m_pkthdr.pf.prio = EVL_PRIOFTAG(m->m_pkthdr.ether_vtag); - - /* IEEE 802.1p has prio 0 and 1 swapped */ - if (m->m_pkthdr.pf.prio <= 1) - m->m_pkthdr.pf.prio = !m->m_pkthdr.pf.prio; - list = &tagh[TAG_HASH(tag)]; SRPL_FOREACH(ifv, &sr, list, ifv_list) { if (ifp0->if_index == ifv->ifv_ifidx0 && tag == ifv->ifv_tag && @@ -386,14 +379,18 @@ vlan_input(struct ifnet *ifp0, struct mb break; } - if (ifv == NULL) { - ifp0->if_noproto++; - goto drop; + if (ifv == NULL || !ISSET(ifv->ifv_if.if_flags, IFF_RUNNING)) { + SRPL_LEAVE(&sr); + m_freem(m); + return (1); } - if ((ifv->ifv_if.if_flags & (IFF_UP|IFF_RUNNING)) != - (IFF_UP|IFF_RUNNING)) - goto drop; + /* The packet is ours now */ + + m->m_pkthdr.pf.prio = EVL_PRIOFTAG(m->m_pkthdr.ether_vtag); + /* IEEE 802.1p has prio 0 and 1 swapped */ + if (m->m_pkthdr.pf.prio <= 1) + m->m_pkthdr.pf.prio = !m->m_pkthdr.pf.prio; /* * Having found a valid vlan interface corresponding to @@ -403,19 +400,17 @@ vlan_input(struct ifnet *ifp0, struct mb if (m->m_flags & M_VLANTAG) { m->m_flags &= ~M_VLANTAG; } else { - eh->ether_type = evl->evl_proto; - memmove((char *)eh + EVL_ENCAPLEN, eh, sizeof(*eh)); + memmove((char *)evl + EVL_ENCAPLEN, evl, + offsetof(struct ether_vlan_header, evl_encap_proto)); m_adj(m, EVL_ENCAPLEN); } - ml_enqueue(&ml, m); - if_input(&ifv->ifv_if, &ml); - SRPL_LEAVE(&sr); - return (1); + ifp = &ifv->ifv_if; + counters_pkt(ifp->if_counters, + ifc_ipackets, ifc_ibytes, m->m_pkthdr.len); -drop: + if_vinput(ifp, m); SRPL_LEAVE(&sr); - m_freem(m); return (1); } Index: net/ifq.c =================================================================== RCS file: /cvs/src/sys/net/ifq.c,v retrieving revision 1.25 diff -u -p -r1.25 ifq.c --- net/ifq.c 16 Dec 2018 03:36:02 -0000 1.25 +++ net/ifq.c 26 Feb 2019 06:26:48 -0000 @@ -167,7 +167,6 @@ ifq_init(struct ifqueue *ifq, struct ifn ifq->ifq_softc = NULL; mtx_init(&ifq->ifq_mtx, IPL_NET); - ifq->ifq_qdrops = 0; /* default to priq */ ifq->ifq_ops = &priq_ops; @@ -446,11 +445,11 @@ ifiq_init(struct ifiqueue *ifiq, struct ml_init(&ifiq->ifiq_ml); task_set(&ifiq->ifiq_task, ifiq_process, ifiq); - ifiq->ifiq_qdrops = 0; ifiq->ifiq_packets = 0; ifiq->ifiq_bytes = 0; ifiq->ifiq_qdrops = 0; ifiq->ifiq_errors = 0; + ifiq->ifiq_mcasts = 0; ifiq->ifiq_idx = idx; } @@ -467,17 +466,25 @@ ifiq_destroy(struct ifiqueue *ifiq) ml_purge(&ifiq->ifiq_ml); } +unsigned int ifiq_pressure_drop = 2; +unsigned int ifiq_pressure_report = 1; + +unsigned int ifiq_qdrops; +unsigned int ifiq_maxpressure; +unsigned int ifiq_maxilen; +unsigned int ifiq_maxqlen; + int -ifiq_input(struct ifiqueue *ifiq, struct mbuf_list *ml, unsigned int cwm) +ifiq_input(struct ifiqueue *ifiq, struct mbuf_list *ml) { struct ifnet *ifp = ifiq->ifiq_if; struct mbuf *m; uint64_t packets; uint64_t bytes = 0; + unsigned int pressure; #if NBPFILTER > 0 caddr_t if_bpf; #endif - int rv = 1; if (ml_empty(ml)) return (0); @@ -518,11 +525,19 @@ ifiq_input(struct ifiqueue *ifiq, struct ifiq->ifiq_packets += packets; ifiq->ifiq_bytes += bytes; - if (ifiq_len(ifiq) >= cwm * 5) + pressure = ++ifiq->ifiq_pressure; + if (pressure > ifiq_pressure_drop) { ifiq->ifiq_qdrops += ml_len(ml); - else { - rv = (ifiq_len(ifiq) >= cwm * 3); + ifiq_qdrops += ml_len(ml); + } else { + unsigned int l; + l = ml_len(ml); + if (l > ifiq_maxilen) + ifiq_maxilen = l; ml_enlist(&ifiq->ifiq_ml, ml); + l = ml_len(&ifiq->ifiq_ml); + if (l > ifiq_maxqlen) + ifiq_maxqlen = l; } mtx_leave(&ifiq->ifiq_mtx); @@ -531,7 +546,10 @@ ifiq_input(struct ifiqueue *ifiq, struct else ml_purge(ml); - return (rv); + if (pressure > ifiq_maxpressure) + ifiq_maxpressure = pressure; + + return (pressure > ifiq_pressure_report); } void @@ -573,6 +591,7 @@ ifiq_process(void *arg) return; mtx_enter(&ifiq->ifiq_mtx); + ifiq->ifiq_pressure = 0; ml = ifiq->ifiq_ml; ml_init(&ifiq->ifiq_ml); mtx_leave(&ifiq->ifiq_mtx); Index: net/ifq.h =================================================================== RCS file: /cvs/src/sys/net/ifq.h,v retrieving revision 1.22 diff -u -p -r1.22 ifq.h --- net/ifq.h 11 Dec 2018 01:36:42 -0000 1.22 +++ net/ifq.h 26 Feb 2019 06:26:48 -0000 @@ -80,6 +80,7 @@ struct ifiqueue { struct mutex ifiq_mtx; struct mbuf_list ifiq_ml; struct task ifiq_task; + unsigned int ifiq_pressure; /* counters */ uint64_t ifiq_packets; @@ -473,8 +474,7 @@ ifq_idx(struct ifqueue *ifq, unsigned in void ifiq_init(struct ifiqueue *, struct ifnet *, unsigned int); void ifiq_destroy(struct ifiqueue *); -int ifiq_input(struct ifiqueue *, struct mbuf_list *, - unsigned int); +int ifiq_input(struct ifiqueue *, struct mbuf_list *); int ifiq_enqueue(struct ifiqueue *, struct mbuf *); void ifiq_add_data(struct ifiqueue *, struct if_data *); void ifiq_barrier(struct ifiqueue *); Index: dev/pci/if_ix.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_ix.c,v retrieving revision 1.155 diff -u -p -r1.155 if_ix.c --- dev/pci/if_ix.c 26 Feb 2019 04:04:30 -0000 1.155 +++ dev/pci/if_ix.c 26 Feb 2019 06:26:48 -0000 @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ix.c,v 1.155 2019/02/26 04:04:30 dlg Exp $ */ +/* $OpenBSD: if_ix.c,v 1.154 2019/02/26 03:09:50 dlg Exp $ */ /****************************************************************************** @@ -141,7 +141,8 @@ void ixgbe_iff(struct ix_softc *); void ixgbe_print_hw_stats(struct ix_softc *); #endif void ixgbe_update_link_status(struct ix_softc *); -int ixgbe_get_buf(struct rx_ring *, int); +static int + ixgbe_get_buf(struct rx_ring *, int); int ixgbe_encap(struct tx_ring *, struct mbuf *); int ixgbe_dma_malloc(struct ix_softc *, bus_size_t, struct ixgbe_dma_alloc *, int); @@ -2366,7 +2367,7 @@ ixgbe_txeof(struct tx_ring *txr) * Get a buffer from system mbuf buffer pool. * **********************************************************************/ -int +static int ixgbe_get_buf(struct rx_ring *rxr, int i) { struct ix_softc *sc = rxr->sc; @@ -2374,7 +2375,6 @@ ixgbe_get_buf(struct rx_ring *rxr, int i struct mbuf *mp; int error; union ixgbe_adv_rx_desc *rxdesc; - size_t dsize = sizeof(union ixgbe_adv_rx_desc); rxbuf = &rxr->rx_buffers[i]; rxdesc = &rxr->rx_base[i]; @@ -2403,14 +2403,8 @@ ixgbe_get_buf(struct rx_ring *rxr, int i 0, rxbuf->map->dm_mapsize, BUS_DMASYNC_PREREAD); rxbuf->buf = mp; - bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, - dsize * i, dsize, BUS_DMASYNC_POSTWRITE); - rxdesc->read.pkt_addr = htole64(rxbuf->map->dm_segs[0].ds_addr); - bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, - dsize * i, dsize, BUS_DMASYNC_PREWRITE); - return (0); } @@ -2503,6 +2497,10 @@ ixgbe_rxfill(struct rx_ring *rxr) u_int slots; int i; + bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, + 0, rxr->rxdma.dma_map->dm_mapsize, + BUS_DMASYNC_POSTWRITE); + i = rxr->last_desc_filled; for (slots = if_rxr_get(&rxr->rx_ring, sc->num_rx_desc); slots > 0; slots--) { @@ -2516,6 +2514,10 @@ ixgbe_rxfill(struct rx_ring *rxr) post = 1; } + bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, + 0, rxr->rxdma.dma_map->dm_mapsize, + BUS_DMASYNC_PREWRITE); + if_rxr_put(&rxr->rx_ring, slots); return (post); @@ -2902,7 +2904,8 @@ next_desc: } rxr->next_to_check = i; - if_input(ifp, &ml); + if (ifiq_input(&ifp->if_rcv, &ml)) + if_rxr_livelocked(&rxr->rx_ring); if (!(staterr & IXGBE_RXD_STAT_DD)) return FALSE; Index: dev/pci/if_ix.h =================================================================== RCS file: /cvs/src/sys/dev/pci/if_ix.h,v retrieving revision 1.33 diff -u -p -r1.33 if_ix.h --- dev/pci/if_ix.h 21 Feb 2019 03:16:47 -0000 1.33 +++ dev/pci/if_ix.h 26 Feb 2019 06:26:48 -0000 @@ -48,7 +48,7 @@ * bytes. Performance tests have show the 2K value to be optimal for top * performance. */ -#define DEFAULT_TXD 256 +#define DEFAULT_TXD 2048 #define PERFORM_TXD 2048 #define MAX_TXD 4096 #define MIN_TXD 64 @@ -63,7 +63,7 @@ * against the system mbuf pool limit, you can tune nmbclusters * to adjust for this. */ -#define DEFAULT_RXD 256 +#define DEFAULT_RXD 2048 #define PERFORM_RXD 2048 #define MAX_RXD 4096 #define MIN_RXD 64