[DTrace-devel] [PATCH v3] Add support for built-in variable walltimestamp
Kris Van Hees
kris.van.hees at oracle.com
Wed Jun 16 11:21:18 PDT 2021
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>
... with a very tiny nit below...
On Tue, Jun 15, 2021 at 02:43:58PM -0400, eugene.loh at oracle.com wrote:
> From: Eugene Loh <eugene.loh at oracle.com>
>
> In the pre-compiled function get_bvar(), use bpf_ktime_get_ns() to
> get the time (in nsec) since boot. This value is adjusted by adding
> the POSIX time when the system was booted.
>
> A few more walltimestamp tests pass now, but existing walltimestamp
> tests are rather lenient. Add a new, more stringent test. In particular,
> timestamp is supposed to be fixed for an entire clause while walltimestamp
> is fresh with every call.
>
> Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
> ---
> bpf/get_bvar.c | 3 ++
> libdtrace/dt_bpf.h | 1 +
> libdtrace/dt_cc.c | 19 +++++++++
> libdtrace/dt_dlibs.c | 1 +
> test/demo/act/time.d | 3 +-
> test/unittest/printa/tst.walltimestamp.sh | 2 +-
> .../variables/bvar/tst.walltimestamp.d | 1 -
> .../variables/bvar/tst.walltimestamp2.d | 29 ++++++++++++++
> .../variables/bvar/tst.walltimestamp2.r | 1 +
> .../variables/bvar/tst.walltimestamp2.r.p | 40 +++++++++++++++++++
> 10 files changed, 96 insertions(+), 4 deletions(-)
> create mode 100644 test/unittest/variables/bvar/tst.walltimestamp2.d
> create mode 100644 test/unittest/variables/bvar/tst.walltimestamp2.r
> create mode 100755 test/unittest/variables/bvar/tst.walltimestamp2.r.p
>
> diff --git a/bpf/get_bvar.c b/bpf/get_bvar.c
> index e92287aa..e28918cc 100644
> --- a/bpf/get_bvar.c
> +++ b/bpf/get_bvar.c
> @@ -27,6 +27,7 @@ extern struct bpf_map_def state;
> extern uint64_t STBSZ;
> extern uint64_t STKOFF;
> extern uint64_t STKSIZ;
> +extern uint64_t BOOTTM;
>
> #define error(dctx, fault, illval) \
> ({ \
> @@ -167,6 +168,8 @@ noinline uint64_t dt_get_bvar(dt_dctx_t *dctx, uint32_t id)
>
> return val & 0x00000000ffffffffUL;
> }
> + case DIF_VAR_WALLTIMESTAMP:
> + return bpf_ktime_get_ns() + ((uint64_t) &BOOTTM);
No space between cast and following expression, please.
> case DIF_VAR_PPID: {
> uint64_t ptr;
> int32_t val = -1;
> diff --git a/libdtrace/dt_bpf.h b/libdtrace/dt_bpf.h
> index 3afc95fa..dcc82b80 100644
> --- a/libdtrace/dt_bpf.h
> +++ b/libdtrace/dt_bpf.h
> @@ -25,6 +25,7 @@ extern "C" {
> #define DT_CONST_STBSZ 5
> #define DT_CONST_STKOFF 6
> #define DT_CONST_STKSIZ 7
> +#define DT_CONST_BOOTTM 8
>
> extern int perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu,
> int group_fd, unsigned long flags);
> diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
> index 009f9e64..70e461e3 100644
> --- a/libdtrace/dt_cc.c
> +++ b/libdtrace/dt_cc.c
> @@ -2211,6 +2211,20 @@ dt_link_layout(dtrace_hdl_t *dtp, const dtrace_difo_t *dp, uint_t *pcp,
> return pc;
> }
>
> +static uint64_t boottime = 0;
> +static int get_boottime() {
> + struct timespec t_real, t_boot;
> +
> + if (clock_gettime(CLOCK_REALTIME, &t_real))
> + return -1;
> + if (clock_gettime(CLOCK_MONOTONIC, &t_boot))
> + return -1;
> + boottime = t_real.tv_sec - t_boot.tv_sec;
> + boottime *= 1000000000;
> + boottime += t_real.tv_nsec - t_boot.tv_nsec;
> + return 0;
> +}
> +
> static int
> dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
> dt_ident_t *idp, const dtrace_difo_t *sdp, dt_strtab_t *stab,
> @@ -2334,6 +2348,11 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
> nrp->dofr_data = sizeof(uint64_t)
> * dtp->dt_options[DTRACEOPT_MAXFRAMES];
> continue;
> + case DT_CONST_BOOTTM:
> + if (boottime == 0 && get_boottime())
> + return -1;
> + nrp->dofr_data = boottime;
> + continue;
> default:
> /* probe name -> value is probe id */
> if (strchr(idp->di_name, ':') != NULL)
> diff --git a/libdtrace/dt_dlibs.c b/libdtrace/dt_dlibs.c
> index 10886adb..35a18596 100644
> --- a/libdtrace/dt_dlibs.c
> +++ b/libdtrace/dt_dlibs.c
> @@ -80,6 +80,7 @@ static const dt_ident_t dt_bpf_symbols[] = {
> DT_BPF_SYMBOL_ID(STBSZ, DT_IDENT_SCALAR, DT_CONST_STBSZ),
> DT_BPF_SYMBOL_ID(STKOFF, DT_IDENT_SCALAR, DT_CONST_STKOFF),
> DT_BPF_SYMBOL_ID(STKSIZ, DT_IDENT_SCALAR, DT_CONST_STKSIZ),
> + DT_BPF_SYMBOL_ID(BOOTTM, DT_IDENT_SCALAR, DT_CONST_BOOTTM),
> /* End-of-list marker */
> { NULL, }
> };
> diff --git a/test/demo/act/time.d b/test/demo/act/time.d
> index 61c97b30..76f2d22f 100644
> --- a/test/demo/act/time.d
> +++ b/test/demo/act/time.d
> @@ -1,11 +1,10 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
>
> -/* @@xfail: dtv2 */
> /* @@trigger: none */
>
> #pragma D option quiet
> diff --git a/test/unittest/printa/tst.walltimestamp.sh b/test/unittest/printa/tst.walltimestamp.sh
> index aaa627bc..8037ccab 100755
> --- a/test/unittest/printa/tst.walltimestamp.sh
> +++ b/test/unittest/printa/tst.walltimestamp.sh
> @@ -5,7 +5,7 @@
> # Licensed under the Universal Permissive License v 1.0 as shown at
> # http://oss.oracle.com/licenses/upl.
> #
> -# @@xfail: dtv2
> +
> if [ $# != 1 ]; then
> echo expected one argument: '<'dtrace-path'>'
> exit 2
> diff --git a/test/unittest/variables/bvar/tst.walltimestamp.d b/test/unittest/variables/bvar/tst.walltimestamp.d
> index 4797287d..95eed54a 100644
> --- a/test/unittest/variables/bvar/tst.walltimestamp.d
> +++ b/test/unittest/variables/bvar/tst.walltimestamp.d
> @@ -4,7 +4,6 @@
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION: The 'walltimestamp' variable can be accessed and is not -1.
> diff --git a/test/unittest/variables/bvar/tst.walltimestamp2.d b/test/unittest/variables/bvar/tst.walltimestamp2.d
> new file mode 100644
> index 00000000..98f142d9
> --- /dev/null
> +++ b/test/unittest/variables/bvar/tst.walltimestamp2.d
> @@ -0,0 +1,29 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
> + * Licensed under the Universal Permissive License v 1.0 as shown at
> + * http://oss.oracle.com/licenses/upl.
> + */
> +
> +#pragma D option quiet
> +#pragma D option destructive
> +
> +BEGIN {
> + /* baseline time stamp from system("date") */
> + system("date +'%%s.%%N'");
> +
> + /* get five consecutive time stamps from DTrace */
> + t1 = walltimestamp;
> + t2 = walltimestamp;
> + t3 = walltimestamp;
> + t4 = walltimestamp;
> + t5 = walltimestamp;
> +
> + /* report the first time stamp and the subsequent deltas */
> + printf("%d\n", t1);
> + printf("%d\n", t2 - t1);
> + printf("%d\n", t3 - t2);
> + printf("%d\n", t4 - t3);
> + printf("%d\n", t5 - t4);
> + exit(0);
> +}
> diff --git a/test/unittest/variables/bvar/tst.walltimestamp2.r b/test/unittest/variables/bvar/tst.walltimestamp2.r
> new file mode 100644
> index 00000000..2e9ba477
> --- /dev/null
> +++ b/test/unittest/variables/bvar/tst.walltimestamp2.r
> @@ -0,0 +1 @@
> +success
> diff --git a/test/unittest/variables/bvar/tst.walltimestamp2.r.p b/test/unittest/variables/bvar/tst.walltimestamp2.r.p
> new file mode 100755
> index 00000000..48652ded
> --- /dev/null
> +++ b/test/unittest/variables/bvar/tst.walltimestamp2.r.p
> @@ -0,0 +1,40 @@
> +#!/usr/bin/gawk -f
> +#
> +# Oracle Linux DTrace.
> +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
> +# Licensed under the Universal Permissive License v 1.0 as shown at
> +# http://oss.oracle.com/licenses/upl.
> +
> +{
> + # read the value generated by system("date")
> + t0 = $1; getline;
> +
> + # read a walltimestamp value from DTrace
> + t1 = $1; getline;
> +
> + # read a few walltimestamp deltas from DTrace
> + d2 = $1; getline;
> + d3 = $1; getline;
> + d4 = $1; getline;
> + d5 = $1;
> +
> + # check that the deltas are all positive
> + if (d2 <= 0 ||
> + d3 <= 0 ||
> + d4 <= 0 ||
> + d5 <= 0) print "ERROR: walltimestamp did not advance.";
> +
> + # check that the deltas are all under 0.2 seconds
> + if (d2 > 200000000 ||
> + d3 > 200000000 ||
> + d4 > 200000000 ||
> + d5 > 200000000) print "ERROR: walltimestamp delta is high.";
> +
> + # check walltimestamp against system("date")
> + t_error = 1.e-9 * t1 - t0;
> + if (t_error < 0) t_error *= -1;
> + if (t_error > 0.2) print "ERROR: walltimestamp and system(date) disagree.";
> +
> + print "success";
> + exit 0;
> +}
> --
> 2.18.4
>
>
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel
More information about the DTrace-devel
mailing list