[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