summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2020-07-07 00:00:04 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2020-07-07 00:00:04 +0000
commitf435648b783901fc6f430e780bc7c8e0ea202f7c (patch)
treecce54f8f2798c87d25abf645148b233c025c6d2f
parent4e526a6aa77e6abcee3f8ea6ff3eab4e57605701 (diff)
add kstats for rx queues (ifiqs) and transmit queues (ifqs).
this means you can observe what the network stack is trying to do when it's working with a nic driver that supports multiple rings. a nic with only one set of rings still gets queues though, and this still exports their stats. here is a small example of what kstat(8) currently outputs for these stats: em0:0:rxq:0 packets: 2292 packets bytes: 229846 bytes qdrops: 0 packets errors: 0 packets qlen: 0 packets em0:0:txq:0 packets: 1297 packets bytes: 193413 bytes qdrops: 0 packets errors: 0 packets qlen: 0 packets maxqlen: 511 packets oactive: false
-rw-r--r--sys/net/ifq.c124
-rw-r--r--sys/net/ifq.h7
2 files changed, 129 insertions, 2 deletions
diff --git a/sys/net/ifq.c b/sys/net/ifq.c
index 2846d23ed03..5e97c4e2e43 100644
--- a/sys/net/ifq.c
+++ b/sys/net/ifq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ifq.c,v 1.40 2020/06/17 06:45:22 dlg Exp $ */
+/* $OpenBSD: ifq.c,v 1.41 2020/07/07 00:00:03 dlg Exp $ */
/*
* Copyright (c) 2015 David Gwynne <dlg@openbsd.org>
@@ -17,6 +17,7 @@
*/
#include "bpfilter.h"
+#include "kstat.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -32,6 +33,10 @@
#include <net/bpf.h>
#endif
+#if NKSTAT > 0
+#include <sys/kstat.h>
+#endif
+
/*
* priq glue
*/
@@ -188,6 +193,52 @@ ifq_barrier_task(void *p)
* ifqueue mbuf queue API
*/
+#if NKSTAT > 0
+struct ifq_kstat_data {
+ struct kstat_kv kd_packets;
+ struct kstat_kv kd_bytes;
+ struct kstat_kv kd_qdrops;
+ struct kstat_kv kd_errors;
+ struct kstat_kv kd_qlen;
+ struct kstat_kv kd_maxqlen;
+ struct kstat_kv kd_oactive;
+};
+
+static const struct ifq_kstat_data ifq_kstat_tpl = {
+ KSTAT_KV_UNIT_INITIALIZER("packets",
+ KSTAT_KV_T_COUNTER64, KSTAT_KV_U_PACKETS),
+ KSTAT_KV_UNIT_INITIALIZER("bytes",
+ KSTAT_KV_T_COUNTER64, KSTAT_KV_U_BYTES),
+ KSTAT_KV_UNIT_INITIALIZER("qdrops",
+ KSTAT_KV_T_COUNTER64, KSTAT_KV_U_PACKETS),
+ KSTAT_KV_UNIT_INITIALIZER("errors",
+ KSTAT_KV_T_COUNTER64, KSTAT_KV_U_PACKETS),
+ KSTAT_KV_UNIT_INITIALIZER("qlen",
+ KSTAT_KV_T_UINT32, KSTAT_KV_U_PACKETS),
+ KSTAT_KV_UNIT_INITIALIZER("maxqlen",
+ KSTAT_KV_T_UINT32, KSTAT_KV_U_PACKETS),
+ KSTAT_KV_INITIALIZER("oactive", KSTAT_KV_T_BOOL),
+};
+
+int
+ifq_kstat_copy(struct kstat *ks, void *dst)
+{
+ struct ifqueue *ifq = ks->ks_softc;
+ struct ifq_kstat_data *kd = dst;
+
+ *kd = ifq_kstat_tpl;
+ kstat_kv_u64(&kd->kd_packets) = ifq->ifq_packets;
+ kstat_kv_u64(&kd->kd_bytes) = ifq->ifq_bytes;
+ kstat_kv_u64(&kd->kd_qdrops) = ifq->ifq_qdrops;
+ kstat_kv_u64(&kd->kd_errors) = ifq->ifq_errors;
+ kstat_kv_u32(&kd->kd_qlen) = ifq->ifq_len;
+ kstat_kv_u32(&kd->kd_maxqlen) = ifq->ifq_maxlen;
+ kstat_kv_bool(&kd->kd_oactive) = ifq->ifq_oactive;
+
+ return (0);
+}
+#endif
+
void
ifq_init(struct ifqueue *ifq, struct ifnet *ifp, unsigned int idx)
{
@@ -222,6 +273,18 @@ ifq_init(struct ifqueue *ifq, struct ifnet *ifp, unsigned int idx)
ifq_set_maxlen(ifq, IFQ_MAXLEN);
ifq->ifq_idx = idx;
+
+#if NKSTAT > 0
+ /* XXX xname vs driver name and unit */
+ ifq->ifq_kstat = kstat_create(ifp->if_xname, 0,
+ "txq", ifq->ifq_idx, KSTAT_T_KV, 0);
+ KASSERT(ifq->ifq_kstat != NULL);
+ kstat_set_mutex(ifq->ifq_kstat, &ifq->ifq_mtx);
+ ifq->ifq_kstat->ks_softc = ifq;
+ ifq->ifq_kstat->ks_datalen = sizeof(ifq_kstat_tpl);
+ ifq->ifq_kstat->ks_copy = ifq_kstat_copy;
+ kstat_install(ifq->ifq_kstat);
+#endif
}
void
@@ -265,6 +328,10 @@ ifq_destroy(struct ifqueue *ifq)
{
struct mbuf_list ml = MBUF_LIST_INITIALIZER();
+#if NKSTAT > 0
+ kstat_destroy(ifq->ifq_kstat);
+#endif
+
NET_ASSERT_UNLOCKED();
if (!task_del(ifq->ifq_softnet, &ifq->ifq_bundle))
taskq_barrier(ifq->ifq_softnet);
@@ -505,6 +572,45 @@ ifq_mfreeml(struct ifqueue *ifq, struct mbuf_list *ml)
* ifiq
*/
+#if NKSTAT > 0
+struct ifiq_kstat_data {
+ struct kstat_kv kd_packets;
+ struct kstat_kv kd_bytes;
+ struct kstat_kv kd_qdrops;
+ struct kstat_kv kd_errors;
+ struct kstat_kv kd_qlen;
+};
+
+static const struct ifiq_kstat_data ifiq_kstat_tpl = {
+ KSTAT_KV_UNIT_INITIALIZER("packets",
+ KSTAT_KV_T_COUNTER64, KSTAT_KV_U_PACKETS),
+ KSTAT_KV_UNIT_INITIALIZER("bytes",
+ KSTAT_KV_T_COUNTER64, KSTAT_KV_U_BYTES),
+ KSTAT_KV_UNIT_INITIALIZER("qdrops",
+ KSTAT_KV_T_COUNTER64, KSTAT_KV_U_PACKETS),
+ KSTAT_KV_UNIT_INITIALIZER("errors",
+ KSTAT_KV_T_COUNTER64, KSTAT_KV_U_PACKETS),
+ KSTAT_KV_UNIT_INITIALIZER("qlen",
+ KSTAT_KV_T_UINT32, KSTAT_KV_U_PACKETS),
+};
+
+int
+ifiq_kstat_copy(struct kstat *ks, void *dst)
+{
+ struct ifiqueue *ifiq = ks->ks_softc;
+ struct ifiq_kstat_data *kd = dst;
+
+ *kd = ifiq_kstat_tpl;
+ kstat_kv_u64(&kd->kd_packets) = ifiq->ifiq_packets;
+ kstat_kv_u64(&kd->kd_bytes) = ifiq->ifiq_bytes;
+ kstat_kv_u64(&kd->kd_qdrops) = ifiq->ifiq_qdrops;
+ kstat_kv_u64(&kd->kd_errors) = ifiq->ifiq_errors;
+ kstat_kv_u32(&kd->kd_qlen) = ml_len(&ifiq->ifiq_ml);
+
+ return (0);
+}
+#endif
+
static void ifiq_process(void *);
void
@@ -525,11 +631,27 @@ ifiq_init(struct ifiqueue *ifiq, struct ifnet *ifp, unsigned int idx)
ifiq->ifiq_errors = 0;
ifiq->ifiq_idx = idx;
+
+#if NKSTAT > 0
+ /* XXX xname vs driver name and unit */
+ ifiq->ifiq_kstat = kstat_create(ifp->if_xname, 0,
+ "rxq", ifiq->ifiq_idx, KSTAT_T_KV, 0);
+ KASSERT(ifiq->ifiq_kstat != NULL);
+ kstat_set_mutex(ifiq->ifiq_kstat, &ifiq->ifiq_mtx);
+ ifiq->ifiq_kstat->ks_softc = ifiq;
+ ifiq->ifiq_kstat->ks_datalen = sizeof(ifiq_kstat_tpl);
+ ifiq->ifiq_kstat->ks_copy = ifiq_kstat_copy;
+ kstat_install(ifiq->ifiq_kstat);
+#endif
}
void
ifiq_destroy(struct ifiqueue *ifiq)
{
+#if NKSTAT > 0
+ kstat_destroy(ifiq->ifiq_kstat);
+#endif
+
NET_ASSERT_UNLOCKED();
if (!task_del(ifiq->ifiq_softnet, &ifiq->ifiq_task))
taskq_barrier(ifiq->ifiq_softnet);
diff --git a/sys/net/ifq.h b/sys/net/ifq.h
index 0ffc64f0f52..fe8aa7781df 100644
--- a/sys/net/ifq.h
+++ b/sys/net/ifq.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ifq.h,v 1.31 2020/05/22 07:02:24 dlg Exp $ */
+/* $OpenBSD: ifq.h,v 1.32 2020/07/07 00:00:03 dlg Exp $ */
/*
* Copyright (c) 2015 David Gwynne <dlg@openbsd.org>
@@ -20,6 +20,7 @@
#define _NET_IFQ_H_
struct ifnet;
+struct kstat;
struct ifq_ops;
@@ -54,6 +55,8 @@ struct ifqueue {
uint64_t ifq_errors;
uint64_t ifq_mcasts;
+ struct kstat *ifq_kstat;
+
/* work serialisation */
struct mutex ifq_task_mtx;
struct task_list ifq_task_list;
@@ -92,6 +95,8 @@ struct ifiqueue {
uint64_t ifiq_mcasts;
uint64_t ifiq_noproto;
+ struct kstat *ifiq_kstat;
+
/* properties */
unsigned int ifiq_idx;
};