summaryrefslogtreecommitdiff
path: root/sys/dev/dt
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 /sys/dev/dt
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.
Diffstat (limited to 'sys/dev/dt')
-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
3 files changed, 37 insertions, 12 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 *);