summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2024-11-26 10:28:28 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2024-11-26 10:28:28 +0000
commit01b8ed6aa673709aaaa6fa4820957bd172cc8e1e (patch)
tree582b4cc063cb104afebb141a5742bacff70982a0
parent33e06fc8f870a119b79b076d3d69e30e98a3f5ea (diff)
Generate a single event when timers advance for more than one tick.
Also report the number of events missed due to recursions or skipped ticks to btrace(8). From Christian Ludwig.
-rw-r--r--sys/dev/dt/dt_dev.c25
-rw-r--r--sys/dev/dt/dt_prov_profile.c19
-rw-r--r--sys/dev/dt/dtvar.h5
-rw-r--r--usr.sbin/btrace/btrace.c6
4 files changed, 42 insertions, 13 deletions
diff --git a/sys/dev/dt/dt_dev.c b/sys/dev/dt/dt_dev.c
index 70273c4ae03..0d9e7282264 100644
--- a/sys/dev/dt/dt_dev.c
+++ b/sys/dev/dt/dt_dev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dt_dev.c,v 1.40 2024/11/05 08:11:54 mpi Exp $ */
+/* $OpenBSD: dt_dev.c,v 1.41 2024/11/26 10:28:27 mpi Exp $ */
/*
* Copyright (c) 2019 Martin Pieuchot <mpi@openbsd.org>
@@ -102,6 +102,8 @@ struct dt_cpubuf {
/* Counters */
unsigned int dc_dropevt; /* [p] # of events dropped */
+ unsigned int dc_skiptick; /* [p] # of ticks skipped */
+ unsigned int dc_recurevt; /* [p] # of recursive events */
unsigned int dc_readevt; /* [r] # of events read */
};
@@ -490,19 +492,24 @@ int
dt_ioctl_get_stats(struct dt_softc *sc, struct dtioc_stat *dtst)
{
struct dt_cpubuf *dc;
- uint64_t readevt = 0, dropevt = 0;
+ uint64_t readevt, dropevt, skiptick, recurevt;
int i;
+ readevt = dropevt = skiptick = 0;
for (i = 0; i < ncpusfound; i++) {
dc = &sc->ds_cpu[i];
membar_consumer();
dropevt += dc->dc_dropevt;
+ skiptick = dc->dc_skiptick;
+ recurevt = dc->dc_recurevt;
readevt += dc->dc_readevt;
}
dtst->dtst_readevt = readevt;
dtst->dtst_dropevt = dropevt;
+ dtst->dtst_skiptick = skiptick;
+ dtst->dtst_recurevt = recurevt;
return 0;
}
@@ -725,6 +732,15 @@ dt_pcb_purge(struct dt_pcb_list *plist)
}
}
+void
+dt_pcb_ring_skiptick(struct dt_pcb *dp, unsigned int skip)
+{
+ struct dt_cpubuf *dc = &dp->dp_sc->ds_cpu[cpu_number()];
+
+ dc->dc_skiptick += skip;
+ membar_producer();
+}
+
/*
* Get a reference to the next free event state from the ring.
*/
@@ -736,8 +752,11 @@ dt_pcb_ring_get(struct dt_pcb *dp, int profiling)
int prod, cons, distance;
struct dt_cpubuf *dc = &dp->dp_sc->ds_cpu[cpu_number()];
- if (dc->dc_inevt == 1)
+ if (dc->dc_inevt == 1) {
+ dc->dc_recurevt++;
+ membar_producer();
return NULL;
+ }
dc->dc_inevt = 1;
diff --git a/sys/dev/dt/dt_prov_profile.c b/sys/dev/dt/dt_prov_profile.c
index 62900152e14..394cda9cd28 100644
--- a/sys/dev/dt/dt_prov_profile.c
+++ b/sys/dev/dt/dt_prov_profile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dt_prov_profile.c,v 1.8 2024/04/06 11:18:02 mpi Exp $ */
+/* $OpenBSD: dt_prov_profile.c,v 1.9 2024/11/26 10:28:27 mpi Exp $ */
/*
* Copyright (c) 2019 Martin Pieuchot <mpi@openbsd.org>
@@ -101,15 +101,18 @@ dt_prov_profile_alloc(struct dt_probe *dtp, struct dt_softc *sc,
void
dt_clock(struct clockrequest *cr, void *cf, void *arg)
{
- uint64_t count, i;
+ uint64_t count;
struct dt_evt *dtev;
struct dt_pcb *dp = arg;
count = clockrequest_advance(cr, dp->dp_nsecs);
- for (i = 0; i < count; i++) {
- dtev = dt_pcb_ring_get(dp, 1);
- if (dtev == NULL)
- return;
- dt_pcb_ring_consume(dp, dtev);
- }
+ if (count == 0)
+ return;
+ else if (count > 1)
+ dt_pcb_ring_skiptick(dp, count - 1);
+
+ dtev = dt_pcb_ring_get(dp, 1);
+ if (dtev == NULL)
+ return;
+ dt_pcb_ring_consume(dp, dtev);
}
diff --git a/sys/dev/dt/dtvar.h b/sys/dev/dt/dtvar.h
index c6cfa7f66b3..1ca135d5eb4 100644
--- a/sys/dev/dt/dtvar.h
+++ b/sys/dev/dt/dtvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dtvar.h,v 1.20 2024/11/02 16:59:22 mpi Exp $ */
+/* $OpenBSD: dtvar.h,v 1.21 2024/11/26 10:28:27 mpi Exp $ */
/*
* Copyright (c) 2019 Martin Pieuchot <mpi@openbsd.org>
@@ -116,6 +116,8 @@ struct dtioc_req {
struct dtioc_stat {
uint64_t dtst_readevt; /* events read */
uint64_t dtst_dropevt; /* events dropped */
+ uint64_t dtst_skiptick; /* clock ticks skipped */
+ uint64_t dtst_recurevt; /* recursive events */
};
struct dtioc_getaux {
@@ -179,6 +181,7 @@ struct dt_pcb *dt_pcb_alloc(struct dt_probe *, struct dt_softc *);
void dt_pcb_free(struct dt_pcb *);
void dt_pcb_purge(struct dt_pcb_list *);
+void dt_pcb_ring_skiptick(struct dt_pcb *, unsigned int);
struct dt_evt *dt_pcb_ring_get(struct dt_pcb *, int);
void dt_pcb_ring_consume(struct dt_pcb *, struct dt_evt *);
diff --git a/usr.sbin/btrace/btrace.c b/usr.sbin/btrace/btrace.c
index aa75a12f676..e755431be8c 100644
--- a/usr.sbin/btrace/btrace.c
+++ b/usr.sbin/btrace/btrace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: btrace.c,v 1.92 2024/07/09 16:08:30 mpi Exp $ */
+/* $OpenBSD: btrace.c,v 1.93 2024/11/26 10:28:27 mpi Exp $ */
/*
* Copyright (c) 2019 - 2023 Martin Pieuchot <mpi@openbsd.org>
@@ -452,6 +452,10 @@ rules_do(int fd)
fprintf(stderr, "%llu events read\n", dtst.dtst_readevt);
fprintf(stderr, "%llu events dropped\n", dtst.dtst_dropevt);
fprintf(stderr, "%llu events filtered\n", bt_filtered);
+ fprintf(stderr, "%llu clock ticks skipped\n",
+ dtst.dtst_skiptick);
+ fprintf(stderr, "%llu recursive events dropped\n",
+ dtst.dtst_recurevt);
}
}