diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2024-11-26 10:28:28 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2024-11-26 10:28:28 +0000 |
commit | 01b8ed6aa673709aaaa6fa4820957bd172cc8e1e (patch) | |
tree | 582b4cc063cb104afebb141a5742bacff70982a0 /sys/dev/dt | |
parent | 33e06fc8f870a119b79b076d3d69e30e98a3f5ea (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.c | 25 | ||||
-rw-r--r-- | sys/dev/dt/dt_prov_profile.c | 19 | ||||
-rw-r--r-- | sys/dev/dt/dtvar.h | 5 |
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 *); |