summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
};