git: 6577e32ea2c7 - main - iflib: report output drops and handle ENOBUFS properly
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 10 Sep 2025 14:00:31 UTC
The branch main has been updated by gallatin: URL: https://cgit.FreeBSD.org/src/commit/?id=6577e32ea2c7868c275eae6d1c68f1c37d418c71 commit 6577e32ea2c7868c275eae6d1c68f1c37d418c71 Author: Andrew Gallatin <gallatin@FreeBSD.org> AuthorDate: 2025-09-10 13:17:35 +0000 Commit: Andrew Gallatin <gallatin@FreeBSD.org> CommitDate: 2025-09-10 13:55:24 +0000 iflib: report output drops and handle ENOBUFS properly - Fix an mbuf leak with iflib.simple_tx=1 when we run out of tx descs in iflib_encap(). It seems odd to free the mbuf in iflib_encap(), but that routine consumes mbufs for other reasons, and it seemed safest to free there rather than have the simple tx routine parse return values to determine what needed to be freed. - Increment counters for output drops when ENOBUFS is encountered and output errors when other transmit errors are encountered for both the simple and normal tx routines. - Performed driver changes so that iflib drivers now add the generic output drop and output error counters to their private counters in their ifdi_get_counter routines. Reviewed by: kbowling, markj Differential Revision: https://reviews.freebsd.org/D52369 Sponsored by: Netflix --- sys/dev/axgbe/if_axgbe_pci.c | 3 ++- sys/dev/e1000/if_em.c | 4 ++-- sys/dev/enetc/if_enetc.c | 3 ++- sys/dev/ice/ice_lib.c | 6 ++++-- sys/dev/igc/if_igc.c | 4 ++-- sys/dev/ixgbe/if_ix.c | 2 -- sys/dev/ixl/if_ixl.c | 4 ++-- sys/net/iflib.c | 15 +++++++++++++++ 8 files changed, 29 insertions(+), 12 deletions(-) diff --git a/sys/dev/axgbe/if_axgbe_pci.c b/sys/dev/axgbe/if_axgbe_pci.c index 290156ff11ca..6bc4bd33e162 100644 --- a/sys/dev/axgbe/if_axgbe_pci.c +++ b/sys/dev/axgbe/if_axgbe_pci.c @@ -2415,7 +2415,8 @@ axgbe_if_get_counter(if_ctx_t ctx, ift_counter cnt) case IFCOUNTER_OPACKETS: return (pstats->txframecount_gb); case IFCOUNTER_OERRORS: - return (pstats->txframecount_gb - pstats->txframecount_g); + return (if_get_counter_default(ifp, cnt) + + pstats->txframecount_gb - pstats->txframecount_g); case IFCOUNTER_IBYTES: return (pstats->rxoctetcount_gb); case IFCOUNTER_OBYTES: diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 9c5ae2806f75..60959fe679b8 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -4782,8 +4782,8 @@ em_if_get_counter(if_ctx_t ctx, ift_counter cnt) sc->stats.ruc + sc->stats.roc + sc->stats.mpc + sc->stats.cexterr); case IFCOUNTER_OERRORS: - return (sc->stats.ecol + sc->stats.latecol + - sc->watchdog_events); + return (if_get_counter_default(ifp, cnt) + + sc->stats.ecol + sc->stats.latecol + sc->watchdog_events); default: return (if_get_counter_default(ifp, cnt)); } diff --git a/sys/dev/enetc/if_enetc.c b/sys/dev/enetc/if_enetc.c index 3a5d6ec23282..808397b229a7 100644 --- a/sys/dev/enetc/if_enetc.c +++ b/sys/dev/enetc/if_enetc.c @@ -1343,7 +1343,8 @@ enetc_get_counter(if_ctx_t ctx, ift_counter cnt) case IFCOUNTER_IERRORS: return (ENETC_PORT_RD8(sc, ENETC_PM0_RERR)); case IFCOUNTER_OERRORS: - return (ENETC_PORT_RD8(sc, ENETC_PM0_TERR)); + return (if_get_counter_default(ifp, cnt) + + ENETC_PORT_RD8(sc, ENETC_PM0_TERR)); default: return (if_get_counter_default(ifp, cnt)); } diff --git a/sys/dev/ice/ice_lib.c b/sys/dev/ice/ice_lib.c index 442111e5ffaf..8b6349f686eb 100644 --- a/sys/dev/ice/ice_lib.c +++ b/sys/dev/ice/ice_lib.c @@ -7818,7 +7818,8 @@ ice_get_ifnet_counter(struct ice_vsi *vsi, ift_counter counter) case IFCOUNTER_OPACKETS: return (es->tx_unicast + es->tx_multicast + es->tx_broadcast); case IFCOUNTER_OERRORS: - return (es->tx_errors); + return (if_get_counter_default(vsi->sc->ifp, counter) + + es->tx_errors); case IFCOUNTER_COLLISIONS: return (0); case IFCOUNTER_IBYTES: @@ -7832,7 +7833,8 @@ ice_get_ifnet_counter(struct ice_vsi *vsi, ift_counter counter) case IFCOUNTER_IQDROPS: return (es->rx_discards); case IFCOUNTER_OQDROPS: - return (hs->tx_dropped_link_down); + return (if_get_counter_default(vsi->sc->ifp, counter) + + hs->tx_dropped_link_down); case IFCOUNTER_NOPROTO: return (es->rx_unknown_protocol); default: diff --git a/sys/dev/igc/if_igc.c b/sys/dev/igc/if_igc.c index a1ae35c7aa43..f199a128c783 100644 --- a/sys/dev/igc/if_igc.c +++ b/sys/dev/igc/if_igc.c @@ -2599,8 +2599,8 @@ igc_if_get_counter(if_ctx_t ctx, ift_counter cnt) sc->stats.ruc + sc->stats.roc + sc->stats.mpc + sc->stats.htdpmc); case IFCOUNTER_OERRORS: - return (sc->stats.ecol + sc->stats.latecol + - sc->watchdog_events); + return (if_get_counter_default(ifp, cnt) + + sc->stats.ecol + sc->stats.latecol + sc->watchdog_events); default: return (if_get_counter_default(ifp, cnt)); } diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c index e1e05e008e8d..c9d35e834177 100644 --- a/sys/dev/ixgbe/if_ix.c +++ b/sys/dev/ixgbe/if_ix.c @@ -1350,8 +1350,6 @@ ixgbe_if_get_counter(if_ctx_t ctx, ift_counter cnt) return (0); case IFCOUNTER_IQDROPS: return (sc->iqdrops); - case IFCOUNTER_OQDROPS: - return (0); case IFCOUNTER_IERRORS: return (sc->ierrors); default: diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c index 43c3af056b67..261f76055901 100644 --- a/sys/dev/ixl/if_ixl.c +++ b/sys/dev/ixl/if_ixl.c @@ -1785,7 +1785,7 @@ ixl_if_get_counter(if_ctx_t ctx, ift_counter cnt) case IFCOUNTER_OPACKETS: return (vsi->opackets); case IFCOUNTER_OERRORS: - return (vsi->oerrors); + return (if_get_counter_default(ifp, cnt) + vsi->oerrors); case IFCOUNTER_COLLISIONS: /* Collisions are by standard impossible in 40G/10G Ethernet */ return (0); @@ -1800,7 +1800,7 @@ ixl_if_get_counter(if_ctx_t ctx, ift_counter cnt) case IFCOUNTER_IQDROPS: return (vsi->iqdrops); case IFCOUNTER_OQDROPS: - return (vsi->oqdrops); + return (if_get_counter_default(ifp, cnt) + vsi->oqdrops); case IFCOUNTER_NOPROTO: return (vsi->noproto); default: diff --git a/sys/net/iflib.c b/sys/net/iflib.c index 308ecad0a846..1e6d98291c04 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -3646,6 +3646,12 @@ defrag: bus_dmamap_unload(buf_tag, map); DBG_COUNTER_INC(encap_txq_avail_fail); DBG_COUNTER_INC(encap_txd_encap_fail); + if (ctx->ifc_sysctl_simple_tx) { + *m_headp = m_head = iflib_remove_mbuf(txq); + m_freem(*m_headp); + DBG_COUNTER_INC(tx_frees); + *m_headp = NULL; + } if ((txq->ift_task.gt_task.ta_flags & TASK_ENQUEUED) == 0) GROUPTASK_ENQUEUE(&txq->ift_task); return (ENOBUFS); @@ -4298,6 +4304,10 @@ iflib_if_transmit(if_t ifp, struct mbuf *m) ifmp_ring_check_drainage(txq->ift_br, TX_BATCH_SIZE); m_freem(m); DBG_COUNTER_INC(tx_frees); + if (err == ENOBUFS) + if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1); + else + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } return (err); @@ -7141,6 +7151,11 @@ iflib_simple_transmit(if_t ifp, struct mbuf *m) bytes_sent += m->m_pkthdr.len; mcast_sent += !!(m->m_flags & M_MCAST); (void)iflib_txd_db_check(txq, true); + } else { + if (error == ENOBUFS) + if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1); + else + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } (void)iflib_completed_tx_reclaim(txq, RECLAIM_THRESH(ctx)); mtx_unlock(&txq->ift_mtx);