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 | |
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.
-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 | ||||
-rw-r--r-- | usr.sbin/btrace/btrace.c | 6 |
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); } } |