[DTrace-devel] [PATCH 16/16] Fix profile-provider probe args arg0 and arg1
Kris Van Hees
kris.van.hees at oracle.com
Fri Feb 24 00:55:17 UTC 2023
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>
On Thu, Jan 26, 2023 at 09:23:29PM -0500, eugene.loh--- via DTrace-devel wrote:
> From: Eugene Loh <eugene.loh at oracle.com>
>
> Set arg0 and arg1 for the profile provider.
>
> Note that arg2 is still not unimplemented.
>
> Add stronger tests for profile-* probe args. (Since the new tests use
> a target process that might be running on a different CPU from where
> a tick-* probe fires, we do not add corresponding tick-* tests.
> On the other hand, testing arg0 and arg1 for profile-* ought to be
> sufficient.)
>
> Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
> ---
> libdtrace/dt_prov_profile.c | 34 ++++-----
> test/unittest/profile-n/tst.args_kernel.sh | 74 +++++++++++++++++++
> test/unittest/profile-n/tst.args_user.sh | 85 ++++++++++++++++++++++
> 3 files changed, 175 insertions(+), 18 deletions(-)
> create mode 100755 test/unittest/profile-n/tst.args_kernel.sh
> create mode 100755 test/unittest/profile-n/tst.args_user.sh
>
> diff --git a/libdtrace/dt_prov_profile.c b/libdtrace/dt_prov_profile.c
> index 6d1d3a80..cf391566 100644
> --- a/libdtrace/dt_prov_profile.c
> +++ b/libdtrace/dt_prov_profile.c
> @@ -1,6 +1,6 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2020, 2023, 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.
> *
> @@ -229,28 +229,26 @@ static void trampoline(dt_pcb_t *pcb)
> dt_cg_tramp_copy_regs(pcb);
>
> /*
> - * TODO:
> - * For profile-n probes:
> - * dctx->mst->argv[0] = kernel PC
> - * dctx->mst->argv[1] = userspace PC
> + * dctx->mst->argv[0] = kernel PC
> + * dctx->mst->argv[1] = userspace PC
> + */
> + dt_cg_tramp_copy_PC_from_regs(pcb);
> +
> + /*
> + * TODO: For profile-n probes:
> * dctx->mst->argv[2] = elapsed nsecs
> - *
> - * For tick-n probes:
> - * dctx->mst->argv[0] = kernel PC
> - * dctx->mst->argv[1] = userspace PC
> - *
> - * For now, we can only provide the first argument:
> - * dctx->mst->argv[0] = PT_REGS_IP((dt_pt_regs *)&dctx->ctx->regs);
> - * // lddw %r0, [%r8 + PT_REGS_IP]
> - * // stdw [%r7 + DMST_ARG(0)], %r0
> + * The documentation does not say elapsed since when?
> + * From the legacy port to Oracle Linux, in dtrace/profile_dev.c,
> + * in profile_prof_fn(), it appears that we have a per-CPU variable
> + * that tracks the expected time of the next profile probe.
> + * Each time the probe fires, we compute arg2 = time - expected
> + * and update expected+=interval.
> */
> - emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_IP));
> - emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
>
> /*
> - * (we clear dctx->mst->argv[1] and on)
> + * (we clear dctx->mst->argv[2] and on)
> */
> - for (i = 1; i < ARRAY_SIZE(((dt_mstate_t *)0)->argv); i++)
> + for (i = 2; i < ARRAY_SIZE(((dt_mstate_t *)0)->argv); i++)
> emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_7, DMST_ARG(i), 0));
>
> dt_cg_tramp_epilogue(pcb);
> diff --git a/test/unittest/profile-n/tst.args_kernel.sh b/test/unittest/profile-n/tst.args_kernel.sh
> new file mode 100755
> index 00000000..d489e554
> --- /dev/null
> +++ b/test/unittest/profile-n/tst.args_kernel.sh
> @@ -0,0 +1,74 @@
> +#!/bin/bash
> +#
> +# Oracle Linux DTrace.
> +# Copyright (c) 2023, 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.
> +
> +# @@reinvoke-failure: 1
> +
> +utils=`pwd`/test/utils
> +
> +dtrace=$1
> +tmpfile=$tmpdir/tst.args_kernel.$$
> +mkdir $tmpfile
> +cd $tmpfile
> +
> +target=workload_kernel
> +
> +# determine number of iterations for target number of seconds
> +nsecs=2
> +niters=`$utils/workload_get_iterations.sh $target $nsecs`
> +if [ $niters -lt 0 ]; then
> + echo "workload_get_iterations.sh failed with $target"
> + exit 1
> +fi
> +
> +# set how many probe firings to expect
> +expect=100
> +
> +# set the probe period (in msec)
> +period=$(($nsecs * 1000 / $expect))
> +
> +# run DTrace
> +echo $niters iterations and period $period msec
> +$dtrace $dt_flags -qn '
> + profile:::profile-'$period'ms
> + /pid == $target/
> + {
> + printf("%x %x\n", arg0, arg1);
> + }' -c "$utils/$target $niters" | awk 'NF == 2' | sort | uniq -c > D.out
> +if [[ $? -ne 0 ]]; then
> + echo ERROR running DTrace
> + cat D.out
> + exit 1
> +fi
> +
> +echo "summary of D output (occurrences, arg0, arg1)"
> +cat D.out
> +
> +# check the PCs
> +read ntotal nwarn nerror <<< `awk '
> +BEGIN { ntotal = nwarn = nerror = 0; }
> +
> +# file reports 1:occurrences, 2:arg0, 3:arg1
> + { ntotal += $1 }
> +$3 != 0 { nwarn += $1 }
> +$2 == 0 && $3 == 0 { nerror += $1 }
> +$2 != 0 && $3 != 0 { nerror += $1 }
> +rshift(strtonum("0x"$2), 63) == 0 && $2 != 0 { nerror += $1 }
> +rshift(strtonum("0x"$3), 63) != 0 { nerror += $1 }
> +
> +# report
> +END {
> + print ntotal, nwarn, nerror;
> +}' D.out`
> +
> +# report
> +status=0
> +margin=$(($expect / 10))
> +$utils/check_result.sh $ntotal $expect $margin; status=$(($status + $?))
> +$utils/check_result.sh $nwarn 0 $margin; status=$(($status + $?))
> +$utils/check_result.sh $nerror 0 0 ; status=$(($status + $?))
> +
> +exit $status
> diff --git a/test/unittest/profile-n/tst.args_user.sh b/test/unittest/profile-n/tst.args_user.sh
> new file mode 100755
> index 00000000..c40d2d52
> --- /dev/null
> +++ b/test/unittest/profile-n/tst.args_user.sh
> @@ -0,0 +1,85 @@
> +#!/bin/bash
> +#
> +# Oracle Linux DTrace.
> +# Copyright (c) 2023, 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.
> +
> +# @@reinvoke-failure: 1
> +
> +utils=`pwd`/test/utils
> +
> +dtrace=$1
> +tmpfile=$tmpdir/tst.args_user.$$
> +mkdir $tmpfile
> +cd $tmpfile
> +
> +target=workload_user
> +
> +# dump the loop PCs
> +$utils/workload_analyze_loop.sh $target | awk 'NF == 1' > PCs.txt
> +echo PCs in the loop: `cat PCs.txt`
> +
> +# determine number of iterations for target number of seconds
> +nsecs=2
> +niters=`$utils/workload_get_iterations.sh $target $nsecs`
> +if [ $niters -lt 0 ]; then
> + echo "workload_get_iterations.sh failed with $target"
> + exit 1
> +fi
> +
> +# set how many probe firings to expect
> +expect=100
> +
> +# set the probe period (in msec)
> +period=$(($nsecs * 1000 / $expect))
> +
> +# run DTrace
> +echo $niters iterations and period $period msec
> +$dtrace $dt_flags -qn '
> + profile:::profile-'$period'ms
> + /pid == $target/
> + {
> + printf("%x %x\n", arg0, arg1);
> + }' -c "$utils/$target $niters" | awk 'NF == 2' | sort | uniq -c > D.out
> +if [[ $? -ne 0 ]]; then
> + echo ERROR running DTrace
> + cat D.out
> + exit 1
> +fi
> +
> +echo "summary of D output (occurrences, arg0, arg1)"
> +cat D.out
> +
> +# check the PCs
> +read ntotal narg0 narg1 nwarn nerror <<< `awk '
> +BEGIN { ntotal = narg0 = narg1 = nwarn = nerror = 0; }
> +
> +# one file has the PCs that are in the inner loop
> +FILENAME == "PCs.txt" { PCs[$1] = 1; next; }
> +
> +# other file reports 1:occurrences, 2:arg0, 3:arg1
> + { ntotal += $1 }
> +($2 in PCs) { narg0 += $1 }
> +($3 in PCs) { narg1 += $1 }
> +$2 != 0 { nwarn += $1 }
> +$2 == 0 && $3 == 0 { nerror += $1 }
> +$2 != 0 && $3 != 0 { nerror += $1 }
> +rshift(strtonum("0x"$2), 63) == 0 && $2 != 0 { nerror += $1 }
> +rshift(strtonum("0x"$3), 63) != 0 { nerror += $1 }
> +
> +# report
> +END {
> + print ntotal, narg0, narg1, nwarn, nerror;
> +}' PCs.txt D.out`
> +
> +# report
> +status=0
> +margin=$(($expect / 10))
> +$utils/check_result.sh $ntotal $expect $margin; status=$(($status + $?))
> +$utils/check_result.sh $narg0 0 $margin; status=$(($status + $?))
> +$utils/check_result.sh $narg1 $expect $margin; status=$(($status + $?))
> +$utils/check_result.sh $nwarn 0 $margin; status=$(($status + $?))
> +$utils/check_result.sh $nerror 0 0 ; status=$(($status + $?))
> +
> +exit $status
> --
> 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