diff options
| author | Kevin Bowling <kbowling@FreeBSD.org> | 2026-07-29 09:11:19 +0000 |
|---|---|---|
| committer | Kevin Bowling <kbowling@FreeBSD.org> | 2026-07-30 05:11:31 +0000 |
| commit | d2cd0b57532ba35fe39744a60d53b90e6f13b5e4 (patch) | |
| tree | f5abb64ac1ced5a64d87cb8301c6e5a93924ea99 | |
| parent | e8f3b96ba794521af9904a451da33cf119381da8 (diff) | |
e1000: Sample statistics at timer cadence
Mailbox and link interrupts share iflib admin service with the periodic
timer. Mark timer-driven passes explicitly and run the hardware
statistics sweep only for those samples instead of repeating 66 PF MMIO
reads for every VF mailbox message.
DTrace on the I350 DUT measured the PF sweep at about 79 us on average.
The normal hz/2 timer continues to extend clear-on-read counters
safely; exported counters may trail hardware by up to 500 ms.
Sponsored by: BBOX.io
| -rw-r--r-- | sys/dev/e1000/if_em.c | 15 | ||||
| -rw-r--r-- | sys/dev/e1000/if_em.h | 1 | ||||
| -rw-r--r-- | sys/dev/e1000/if_igbv.c | 3 |
3 files changed, 17 insertions, 2 deletions
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 4612653cf1bc..d8bde14c6c20 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -1626,6 +1626,7 @@ em_if_attach_post(if_ctx_t ctx) sc->ustats.stats = (struct e1000_hw_stats){}; em_update_stats_counters(sc); + atomic_readandclear_32(&sc->stats_pending); hw->mac.get_link_status = 1; if (sc->vf_ifp) igbv_if_update_admin_status(ctx); @@ -2595,9 +2596,13 @@ em_if_multi_set(if_ctx_t ctx) static void em_if_timer(if_ctx_t ctx, uint16_t qid) { + struct e1000_softc *sc; + if (qid != 0) return; + sc = iflib_get_softc(ctx); + atomic_set_32(&sc->stats_pending, 1); iflib_admin_intr_deferred(ctx); } @@ -2733,7 +2738,15 @@ em_if_update_admin_status(if_ctx_t ctx) iflib_link_state_change(ctx, LINK_STATE_DOWN, 0); igb_iov_ping_all_vfs(sc); } - em_update_stats_counters(sc); + /* + * Mailbox, link, and timer events share this admin task. The PF + * statistics sweep performs 66 MMIO reads, so run it only when the + * ordinary iflib timer requests a sample rather than once per mailbox + * message. Exported counters can consequently trail hardware by the + * timer interval (normally 500 ms). + */ + if (atomic_readandclear_32(&sc->stats_pending) != 0) + em_update_stats_counters(sc); /* Reset LAA into RAR[0] on 82571 */ if (hw->mac.type == e1000_82571 && e1000_get_laa_state_82571(hw)) diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h index 1692fdf41295..9cdf013c994a 100644 --- a/sys/dev/e1000/if_em.h +++ b/sys/dev/e1000/if_em.h @@ -596,6 +596,7 @@ struct e1000_softc { int link_mask; int tso_automasked; u32 promisc_pending; + u32 stats_pending; #ifdef PCI_IOV struct igb_vf *vfs; diff --git a/sys/dev/e1000/if_igbv.c b/sys/dev/e1000/if_igbv.c index 4f869388ce81..378a0065242b 100644 --- a/sys/dev/e1000/if_igbv.c +++ b/sys/dev/e1000/if_igbv.c @@ -151,7 +151,8 @@ igbv_if_update_admin_status(if_ctx_t ctx) iflib_admin_intr_deferred(ctx); } /* em_if_init() establishes a new counter baseline after the reset. */ - if (!sc->vf_reset_pending) + if (!sc->vf_reset_pending && + atomic_readandclear_32(&sc->stats_pending) != 0) em_update_stats_counters(sc); } |
