aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNavdeep Parhar <np@FreeBSD.org>2021-04-23 00:45:52 +0000
committerNavdeep Parhar <np@FreeBSD.org>2021-04-23 00:45:52 +0000
commitb47b28e5b28aeaa42e87f905fe6a0fe65dbfc184 (patch)
treeb93de72729907d85ace72f33c6bb36b383484829
parent3cfd08c1c74058451a02bac35307bf7fa509c617 (diff)
downloadsrc-b47b28e5b28aeaa42e87f905fe6a0fe65dbfc184.tar.gz
src-b47b28e5b28aeaa42e87f905fe6a0fe65dbfc184.zip
cxgbe(4): Add flag to reliably stop the driver from accessing hw stats.
There are two kinds of routines in the driver that read statistics from the hardware: the cxgbe_* variants read the per-port MPS/MAC registers and the vi_* variants read the per-VI registers. They can be called from the 1Hz callout or if_get_counter. All stats collection now takes place under the callout lock and there is a new flag to indicate that these routines should not access any hardware register. MFC after: 2 weeks Sponsored by: Chelsio Communications
-rw-r--r--sys/dev/cxgbe/adapter.h4
-rw-r--r--sys/dev/cxgbe/t4_main.c59
2 files changed, 38 insertions, 25 deletions
diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h
index c46f9626b95b..7bdad292c752 100644
--- a/sys/dev/cxgbe/adapter.h
+++ b/sys/dev/cxgbe/adapter.h
@@ -175,6 +175,7 @@ enum {
VI_INIT_DONE = (1 << 1),
VI_SYSCTL_CTX = (1 << 2),
TX_USES_VM_WR = (1 << 3),
+ VI_SKIP_STATS = (1 << 4),
/* adapter debug_flags */
DF_DUMP_MBOX = (1 << 0), /* Log all mbox cmd/rpl. */
@@ -311,7 +312,6 @@ struct port_info {
struct link_config link_cfg;
struct ifmedia media;
- struct timeval last_refreshed;
struct port_stats stats;
u_int tnl_cong_drops;
u_int tx_parse_error;
@@ -1213,11 +1213,9 @@ void end_synchronized_op(struct adapter *, int);
int update_mac_settings(struct ifnet *, int);
int adapter_full_init(struct adapter *);
int adapter_full_uninit(struct adapter *);
-uint64_t cxgbe_get_counter(struct ifnet *, ift_counter);
int vi_full_init(struct vi_info *);
int vi_full_uninit(struct vi_info *);
void vi_sysctls(struct vi_info *);
-void vi_tick(void *);
int rw_via_memwin(struct adapter *, int, uint32_t, uint32_t *, int, int);
int alloc_atid(struct adapter *, void *);
void *lookup_atid(struct adapter *, int);
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index 07fd43a06edc..6774e1bbb833 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -735,9 +735,10 @@ static int t4_free_irq(struct adapter *, struct irq *);
static void t4_init_atid_table(struct adapter *);
static void t4_free_atid_table(struct adapter *);
static void get_regs(struct adapter *, struct t4_regdump *, uint8_t *);
-static void vi_refresh_stats(struct adapter *, struct vi_info *);
-static void cxgbe_refresh_stats(struct adapter *, struct port_info *);
+static void vi_refresh_stats(struct vi_info *);
+static void cxgbe_refresh_stats(struct vi_info *);
static void cxgbe_tick(void *);
+static void vi_tick(void *);
static void cxgbe_sysctls(struct port_info *);
static int sysctl_int_array(SYSCTL_HANDLER_ARGS);
static int sysctl_bitfield_8b(SYSCTL_HANDLER_ARGS);
@@ -820,6 +821,8 @@ static int ktls_capability(struct adapter *, bool);
#endif
static int mod_event(module_t, int, void *);
static int notify_siblings(device_t, int);
+static uint64_t vi_get_counter(struct ifnet *, ift_counter);
+static uint64_t cxgbe_get_counter(struct ifnet *, ift_counter);
struct {
uint16_t device;
@@ -1818,7 +1821,10 @@ cxgbe_vi_attach(device_t dev, struct vi_info *vi)
ifp->if_ioctl = cxgbe_ioctl;
ifp->if_transmit = cxgbe_transmit;
ifp->if_qflush = cxgbe_qflush;
- ifp->if_get_counter = cxgbe_get_counter;
+ if (vi->pi->nvi > 1 || sc->flags & IS_VF)
+ ifp->if_get_counter = vi_get_counter;
+ else
+ ifp->if_get_counter = cxgbe_get_counter;
#if defined(KERN_TLS) || defined(RATELIMIT)
ifp->if_snd_tag_alloc = cxgbe_snd_tag_alloc;
ifp->if_snd_tag_modify = cxgbe_snd_tag_modify;
@@ -2336,7 +2342,9 @@ vi_get_counter(struct ifnet *ifp, ift_counter c)
struct vi_info *vi = ifp->if_softc;
struct fw_vi_stats_vf *s = &vi->stats;
- vi_refresh_stats(vi->adapter, vi);
+ mtx_lock(&vi->tick_mtx);
+ vi_refresh_stats(vi);
+ mtx_unlock(&vi->tick_mtx);
switch (c) {
case IFCOUNTER_IPACKETS:
@@ -2380,18 +2388,16 @@ vi_get_counter(struct ifnet *ifp, ift_counter c)
}
}
-uint64_t
+static uint64_t
cxgbe_get_counter(struct ifnet *ifp, ift_counter c)
{
struct vi_info *vi = ifp->if_softc;
struct port_info *pi = vi->pi;
- struct adapter *sc = pi->adapter;
struct port_stats *s = &pi->stats;
- if (pi->nvi > 1 || sc->flags & IS_VF)
- return (vi_get_counter(ifp, c));
-
- cxgbe_refresh_stats(sc, pi);
+ mtx_lock(&vi->tick_mtx);
+ cxgbe_refresh_stats(vi);
+ mtx_unlock(&vi->tick_mtx);
switch (c) {
case IFCOUNTER_IPACKETS:
@@ -5586,7 +5592,7 @@ cxgbe_init_synchronized(struct vi_info *vi)
PORT_UNLOCK(pi);
mtx_lock(&vi->tick_mtx);
- if (pi->nvi > 1 || sc->flags & IS_VF)
+ if (ifp->if_get_counter == vi_get_counter)
callout_reset(&vi->tick, hz, vi_tick, vi);
else
callout_reset(&vi->tick, hz, cxgbe_tick, vi);
@@ -6334,12 +6340,14 @@ t4_clr_vi_stats(struct adapter *sc, u_int vin)
}
static void
-vi_refresh_stats(struct adapter *sc, struct vi_info *vi)
+vi_refresh_stats(struct vi_info *vi)
{
struct timeval tv;
const struct timeval interval = {0, 250000}; /* 250ms */
- if (!(vi->flags & VI_INIT_DONE))
+ mtx_assert(&vi->tick_mtx, MA_OWNED);
+
+ if (!(vi->flags & VI_INIT_DONE) || vi->flags & VI_SKIP_STATS)
return;
getmicrotime(&tv);
@@ -6347,22 +6355,31 @@ vi_refresh_stats(struct adapter *sc, struct vi_info *vi)
if (timevalcmp(&tv, &vi->last_refreshed, <))
return;
- t4_get_vi_stats(sc, vi->vin, &vi->stats);
+ t4_get_vi_stats(vi->adapter, vi->vin, &vi->stats);
getmicrotime(&vi->last_refreshed);
}
static void
-cxgbe_refresh_stats(struct adapter *sc, struct port_info *pi)
+cxgbe_refresh_stats(struct vi_info *vi)
{
u_int i, v, tnl_cong_drops, chan_map;
struct timeval tv;
const struct timeval interval = {0, 250000}; /* 250ms */
+ struct port_info *pi;
+ struct adapter *sc;
+
+ mtx_assert(&vi->tick_mtx, MA_OWNED);
+
+ if (vi->flags & VI_SKIP_STATS)
+ return;
getmicrotime(&tv);
timevalsub(&tv, &interval);
- if (timevalcmp(&tv, &pi->last_refreshed, <))
+ if (timevalcmp(&tv, &vi->last_refreshed, <))
return;
+ pi = vi->pi;
+ sc = vi->adapter;
tnl_cong_drops = 0;
t4_get_port_stats(sc, pi->tx_chan, &pi->stats);
chan_map = pi->rx_e_chan_map;
@@ -6376,31 +6393,29 @@ cxgbe_refresh_stats(struct adapter *sc, struct port_info *pi)
chan_map &= ~(1 << i);
}
pi->tnl_cong_drops = tnl_cong_drops;
- getmicrotime(&pi->last_refreshed);
+ getmicrotime(&vi->last_refreshed);
}
static void
cxgbe_tick(void *arg)
{
struct vi_info *vi = arg;
- struct adapter *sc = vi->adapter;
MPASS(IS_MAIN_VI(vi));
mtx_assert(&vi->tick_mtx, MA_OWNED);
- cxgbe_refresh_stats(sc, vi->pi);
+ cxgbe_refresh_stats(vi);
callout_schedule(&vi->tick, hz);
}
-void
+static void
vi_tick(void *arg)
{
struct vi_info *vi = arg;
- struct adapter *sc = vi->adapter;
mtx_assert(&vi->tick_mtx, MA_OWNED);
- vi_refresh_stats(sc, vi);
+ vi_refresh_stats(vi);
callout_schedule(&vi->tick, hz);
}