aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Watson <rwatson@FreeBSD.org>2021-02-16 15:19:05 +0000
committerRobert Watson <rwatson@FreeBSD.org>2021-02-25 21:38:30 +0000
commitbbcdd9faca55758b228b949f1c1bb41b85e90a8e (patch)
treea1adcd07fbafe9ce762710ab7161a6184df12288
parentcf9829d98dc771f9ca0696e493dc3bb635999536 (diff)
downloadsrc-bbcdd9faca55758b228b949f1c1bb41b85e90a8e.tar.gz
src-bbcdd9faca55758b228b949f1c1bb41b85e90a8e.zip
Reimplemen FreeBSD/arm64 dtrace_gethrtime() to use the system timer.
dtrace_gethrtime() is the high-resolution nanosecond timestemp used for the DTrace 'timestamp' built-in variable. The new implementation uses the EL0 cycle counter and frequency registers in ARMv8-A. This replaces a previous implementation that relied on an instrumentation-safe implementation of getnanotime(), which provided only timer resolution. Approved by: re (gjb) Reviewed by: andrew, bsdimp (older version) Useful comments appreciated: jrtc27, emaste Differential Revision: https://reviews.freebsd.org/D28723
-rw-r--r--sys/cddl/dev/dtrace/aarch64/dtrace_subr.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c b/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c
index 6646e51fc191..9bf9f0798bb5 100644
--- a/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c
@@ -153,23 +153,26 @@ dtrace_sync(void)
}
/*
- * DTrace needs a high resolution time function which can
- * be called from a probe context and guaranteed not to have
- * instrumented with probes itself.
+ * DTrace needs a high resolution time function which can be called from a
+ * probe context and guaranteed not to have instrumented with probes itself.
*
- * Returns nanoseconds since boot.
+ * Returns nanoseconds since some arbitrary point in time (likely SoC reset?).
*/
uint64_t
-dtrace_gethrtime()
+dtrace_gethrtime(void)
{
- struct timespec curtime;
-
- dtrace_getnanouptime(&curtime);
-
- return (curtime.tv_sec * 1000000000UL + curtime.tv_nsec);
+ uint64_t count, freq;
+ count = READ_SPECIALREG(cntvct_el0);
+ freq = READ_SPECIALREG(cntfrq_el0);
+ return ((1000000000UL * count) / freq);
}
+/*
+ * Return a much lower resolution wallclock time based on the system clock
+ * updated by the timer. If needed, we could add a version interpolated from
+ * the system clock as is the case with dtrace_gethrtime().
+ */
uint64_t
dtrace_gethrestime(void)
{