diff --git a/sys/net/iflib.h b/sys/net/iflib.h --- a/sys/net/iflib.h +++ b/sys/net/iflib.h @@ -503,4 +503,10 @@ int rid, iflib_intr_type_t type, driver_filter_t *filter, void *filter_arg, int qid, const char *name); + +/* + * iflib managed counters support + */ +uint64_t iflib_if_get_counter_default(if_ctx_t ctx, ift_counter cnt); + #endif /* __IFLIB_H_ */ diff --git a/sys/net/iflib.c b/sys/net/iflib.c --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -708,6 +708,7 @@ static void iflib_altq_if_start(if_t ifp); static int iflib_altq_if_transmit(if_t ifp, struct mbuf *m); #endif +static void iflib_save_stats(if_ctx_t); static int iflib_register(if_ctx_t); static void iflib_deregister(if_ctx_t); static void iflib_unregister_vlan_handlers(if_ctx_t ctx); @@ -2612,6 +2613,7 @@ netmap_disable_all_rings(ctx->ifc_ifp); iflib_debug_reset(); + iflib_save_stats(ctx); /* Wait for current tx queue users to exit to disarm watchdog timer. */ for (i = 0; i < scctx->isc_ntxqsets; i++, txq++) { /* make sure all transmitters have completed before proceeding XXX */ @@ -4648,6 +4650,37 @@ return (IFDI_GET_COUNTER(ctx, cnt)); } +uint64_t +iflib_if_get_counter_default(if_ctx_t ctx, ift_counter cnt) +{ + if_t ifp = ctx->ifc_ifp; + + if (cnt == IFCOUNTER_OQDROPS) { + uint64_t drops = 0; + iflib_txq_t txq = ctx->ifc_txqs; + + for (int i = 0; i < ctx->ifc_softc_ctx.isc_ntxqsets; i++, txq++) { + drops += counter_u64_fetch(txq->ift_br->drops); + } + return (drops + if_get_counter_default(ifp, cnt)); + } + + return (if_get_counter_default(ifp, cnt)); +} + +static void +iflib_save_stats(if_ctx_t ctx) +{ + /* Currenly only save out dropped packets */ + uint64_t drops = 0; + iflib_txq_t txq = ctx->ifc_txqs; + + for (int i = 0; i < ctx->ifc_softc_ctx.isc_ntxqsets; i++, txq++) + drops += counter_u64_fetch(txq->ift_br->drops); + + if_inc_counter(ctx->ifc_ifp, IFCOUNTER_OQDROPS, drops); +} + /********************************************************************* * * OTHER FUNCTIONS EXPORTED TO THE STACK