Page MenuHomeFreeBSD

D18418.id51527.diff
No OneTemporary

D18418.id51527.diff

Index: sys/dev/sfxge/sfxge.h
===================================================================
--- sys/dev/sfxge/sfxge.h
+++ sys/dev/sfxge/sfxge.h
@@ -184,6 +184,10 @@
unsigned int buf_base_id;
unsigned int entries;
char lock_name[SFXGE_LOCK_NAME_MAX];
+#if EFSYS_OPT_QSTATS
+ clock_t stats_update_time;
+ uint64_t stats[EV_NQSTATS];
+#endif
} __aligned(CACHE_LINE_SIZE);
#define SFXGE_NDESCS 1024
@@ -275,6 +279,9 @@
struct ifnet *ifnet;
unsigned int if_flags;
struct sysctl_oid *stats_node;
+#if EFSYS_OPT_QSTATS
+ struct sysctl_oid *evqs_stats_node;
+#endif
struct sysctl_oid *txqs_node;
struct task task_reset;
Index: sys/dev/sfxge/sfxge_ev.c
===================================================================
--- sys/dev/sfxge/sfxge_ev.c
+++ sys/dev/sfxge/sfxge_ev.c
@@ -446,30 +446,95 @@
#if EFSYS_OPT_QSTATS
+static void
+sfxge_evq_stat_update(struct sfxge_evq *evq)
+{
+ clock_t now;
+
+ SFXGE_EVQ_LOCK(evq);
+
+ if (__predict_false(evq->init_state != SFXGE_EVQ_STARTED))
+ goto out;
+
+ now = ticks;
+ if ((unsigned int)(now - evq->stats_update_time) < (unsigned int)hz)
+ goto out;
+
+ evq->stats_update_time = now;
+ efx_ev_qstats_update(evq->common, evq->stats);
+
+out:
+ SFXGE_EVQ_UNLOCK(evq);
+}
+
+static int
+sfxge_evq_stat_handler(SYSCTL_HANDLER_ARGS)
+{
+ struct sfxge_evq *evq = arg1;
+ struct sfxge_softc *sc = evq->sc;
+ unsigned int id = arg2;
+
+ SFXGE_ADAPTER_LOCK(sc);
+
+ sfxge_evq_stat_update(evq);
+
+ SFXGE_ADAPTER_UNLOCK(sc);
+
+ return (SYSCTL_OUT(req, &evq->stats[id], sizeof(evq->stats[id])));
+}
+
+static int
+sfxge_evq_stat_init(struct sfxge_evq *evq)
+{
+ struct sfxge_softc *sc = evq->sc;
+ struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
+ char name[16];
+ struct sysctl_oid *evq_stats_node;
+ unsigned int id;
+
+ snprintf(name, sizeof(name), "%u", evq->index);
+ evq_stats_node = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(sc->evqs_stats_node),
+ OID_AUTO, name, CTLFLAG_RD, NULL, "");
+ if (evq_stats_node == NULL)
+ return (ENOMEM);
+
+ for (id = 0; id < EV_NQSTATS; id++) {
+ SYSCTL_ADD_PROC(
+ ctx, SYSCTL_CHILDREN(evq_stats_node),
+ OID_AUTO, efx_ev_qstat_name(sc->enp, id),
+ CTLTYPE_U64|CTLFLAG_RD,
+ evq, id, sfxge_evq_stat_handler, "Q",
+ "");
+ }
+
+ return (0);
+}
+
static void
sfxge_ev_stat_update(struct sfxge_softc *sc)
{
struct sfxge_evq *evq;
unsigned int index;
clock_t now;
+ unsigned int id;
SFXGE_ADAPTER_LOCK(sc);
- if (__predict_false(sc->evq[0]->init_state != SFXGE_EVQ_STARTED))
- goto out;
-
now = ticks;
if ((unsigned int)(now - sc->ev_stats_update_time) < (unsigned int)hz)
goto out;
sc->ev_stats_update_time = now;
- /* Add event counts from each event queue in turn */
+ memset(sc->ev_stats, 0, sizeof(sc->ev_stats));
+
+ /* Update and add event counts from each event queue in turn */
for (index = 0; index < sc->evq_count; index++) {
evq = sc->evq[index];
- SFXGE_EVQ_LOCK(evq);
- efx_ev_qstats_update(evq->common, sc->ev_stats);
- SFXGE_EVQ_UNLOCK(evq);
+ sfxge_evq_stat_update(evq);
+ for (id = 0; id < EV_NQSTATS; id++)
+ sc->ev_stats[id] += evq->stats[id];
}
out:
SFXGE_ADAPTER_UNLOCK(sc);
@@ -676,7 +741,7 @@
#if EFSYS_OPT_QSTATS
/* Add event counts before discarding the common evq state */
- efx_ev_qstats_update(evq->common, sc->ev_stats);
+ efx_ev_qstats_update(evq->common, evq->stats);
#endif
efx_ev_qdestroy(evq->common);
@@ -877,7 +942,24 @@
evq->init_state = SFXGE_EVQ_INITIALIZED;
+#if EFSYS_OPT_QSTATS
+ rc = sfxge_evq_stat_init(evq);
+ if (rc != 0)
+ goto fail_evq_stat_init;
+#endif
+
return (0);
+
+#if EFSYS_OPT_QSTATS
+fail_evq_stat_init:
+ evq->init_state = SFXGE_EVQ_UNINITIALIZED;
+ SFXGE_EVQ_LOCK_DESTROY(evq);
+ sfxge_dma_free(esmp);
+ sc->evq[index] = NULL;
+ free(evq, M_SFXGE);
+
+ return (rc);
+#endif
}
void
@@ -926,6 +1008,16 @@
sc, 0, sfxge_int_mod_handler, "IU",
"sfxge interrupt moderation (us)");
+#if EFSYS_OPT_QSTATS
+ sc->evqs_stats_node = SYSCTL_ADD_NODE(
+ device_get_sysctl_ctx(sc->dev), SYSCTL_CHILDREN(sc->stats_node),
+ OID_AUTO, "evq", CTLFLAG_RD, NULL, "Event queues stats");
+ if (sc->evqs_stats_node == NULL) {
+ rc = ENOMEM;
+ goto fail_evqs_stats_node;
+ }
+#endif
+
/*
* Initialize the event queue(s) - one per interrupt.
*/
@@ -944,6 +1036,9 @@
while (--index >= 0)
sfxge_ev_qfini(sc, index);
+#if EFSYS_OPT_QSTATS
+fail_evqs_stats_node:
+#endif
sc->evq_count = 0;
return (rc);
}

File Metadata

Mime Type
text/plain
Expires
Mon, Mar 3, 3:56 AM (2 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16939407
Default Alt Text
D18418.id51527.diff (4 KB)

Event Timeline