git: d2cd0b57532b - main - e1000: Sample statistics at timer cadence
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 30 Jul 2026 05:15:13 UTC
The branch main has been updated by kbowling:
URL: https://cgit.FreeBSD.org/src/commit/?id=d2cd0b57532ba35fe39744a60d53b90e6f13b5e4
commit d2cd0b57532ba35fe39744a60d53b90e6f13b5e4
Author: Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-07-29 09:11:19 +0000
Commit: Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-07-30 05:11:31 +0000
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
---
sys/dev/e1000/if_em.c | 15 ++++++++++++++-
sys/dev/e1000/if_em.h | 1 +
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);
}