[DTrace-devel] [PATCH 04/16] cpc: Add probe-args tests
Kris Van Hees
kris.van.hees at oracle.com
Mon Feb 20 17:02:11 UTC 2023
I have seen some intermittent failures for these tests. It seems to be a bit
unstable (similar to the profile-n tst.args_*.sh tests). Perhaps we should
mark them as unstable for the upcoming release and do further investigation on
how they can be firmed up?
On Thu, Jan 26, 2023 at 09:23:17PM -0500, eugene.loh--- via DTrace-devel wrote:
> From: Eugene Loh <eugene.loh at oracle.com>
>
> A few additional utilities are added to support these and future tests:
>
> * workload_kernel.c is a simple, kernel-intensive workload
>
> * perf_count_event.sh uses "perf stat" to count some event for
> some executable
>
> Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
> ---
> test/unittest/cpc/tst.args_kernel.sh | 79 ++++++++++++++++++++++++
> test/unittest/cpc/tst.args_user.sh | 90 ++++++++++++++++++++++++++++
> test/utils/.gitignore | 1 +
> test/utils/Build | 2 +-
> test/utils/perf_count_event.sh | 28 +++++++++
> test/utils/workload_kernel.c | 44 ++++++++++++++
> 6 files changed, 243 insertions(+), 1 deletion(-)
> create mode 100755 test/unittest/cpc/tst.args_kernel.sh
> create mode 100755 test/unittest/cpc/tst.args_user.sh
> create mode 100755 test/utils/perf_count_event.sh
> create mode 100644 test/utils/workload_kernel.c
>
> diff --git a/test/unittest/cpc/tst.args_kernel.sh b/test/unittest/cpc/tst.args_kernel.sh
> new file mode 100755
> index 00000000..0cb2480a
> --- /dev/null
> +++ b/test/unittest/cpc/tst.args_kernel.sh
> @@ -0,0 +1,79 @@
> +#!/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
> +
> +# use "perf" to get total
> +total=`$utils/perf_count_event.sh cpu-clock $target $niters`
> +if [ $total -lt 0 ]; then
> + echo "perf_count_event.sh failed with $target"
> + exit 1
> +fi
> +
> +# set how many probe firings to expect
> +expect=100
> +period=$(($total / $expect))
> +
> +# run DTrace
> +echo $niters iterations and period $period
> +$dtrace $dt_flags -qn '
> + cpc:::cpu_clock-all-'$period'
> + /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/cpc/tst.args_user.sh b/test/unittest/cpc/tst.args_user.sh
> new file mode 100755
> index 00000000..a882635d
> --- /dev/null
> +++ b/test/unittest/cpc/tst.args_user.sh
> @@ -0,0 +1,90 @@
> +#!/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
> +
> +# use "perf" to get total
> +total=`$utils/perf_count_event.sh cpu-clock $target $niters`
> +if [ $total -lt 0 ]; then
> + echo "perf_count_event.sh failed with $target"
> + exit 1
> +fi
> +
> +# set how many probe firings to expect
> +expect=100
> +period=$(($total / $expect))
> +
> +# run DTrace
> +echo $niters iterations and period $period
> +$dtrace $dt_flags -qn '
> + cpc:::cpu_clock-all-'$period'
> + /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
> diff --git a/test/utils/.gitignore b/test/utils/.gitignore
> index d8e2ccb5..7c25cb18 100644
> --- a/test/utils/.gitignore
> +++ b/test/utils/.gitignore
> @@ -1,6 +1,7 @@
> # In-place built executables
> baddof
> badioctl
> +workload_kernel
> workload_user
> print-stack-layout
> showUSDT
> diff --git a/test/utils/Build b/test/utils/Build
> index b57cdda8..5cc8e090 100644
> --- a/test/utils/Build
> +++ b/test/utils/Build
> @@ -3,7 +3,7 @@
> # Licensed under the Universal Permissive License v 1.0 as shown at
> # http://oss.oracle.com/licenses/upl.
>
> -TEST_UTILS = baddof badioctl workload_user showUSDT print-stack-layout
> +TEST_UTILS = baddof badioctl workload_kernel workload_user showUSDT print-stack-layout
>
> define test-util-template
> CMDS += $(1)
> diff --git a/test/utils/perf_count_event.sh b/test/utils/perf_count_event.sh
> new file mode 100755
> index 00000000..606a18d6
> --- /dev/null
> +++ b/test/utils/perf_count_event.sh
> @@ -0,0 +1,28 @@
> +#!/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.
> +
> +# count some event for some executable
> +
> +# get the test/utils directory name
> +utils=`dirname $0`
> +
> +# get the event to count
> +event=$1
> +
> +# the rest of the command line is the executable and its arguments
> +shift
> +
> +# Use "perf stat" to count "event" for this executable and its children.
> +# If the output is no good, report -1.
> +# If the output is time in msec, convert to nsec.
> +# Otherwise, just report the count.
> +perf stat -e $event --no-big-num -x\ $utils/$* |& awk '
> +/^[^0-9]/ { print -1; exit 1 }
> +/ msec / { print int(1000000. * $1); exit 0 }
> +{ print $1; exit 0 }'
> +
> +exit 0
> diff --git a/test/utils/workload_kernel.c b/test/utils/workload_kernel.c
> new file mode 100644
> index 00000000..1368a300
> --- /dev/null
> +++ b/test/utils/workload_kernel.c
> @@ -0,0 +1,44 @@
> +/*
> + * 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.
> + */
> +
> +#include <stdlib.h>
> +#define BUFLEN 256
> +
> +#if 0
> +/* use getrandom() wrapper in glibc */
> +#include <sys/random.h>
> +#else
> +/* getrandom() wrapper was not added to glibc until 2.25 */
> +#include <unistd.h>
> +#include <sys/syscall.h>
> +#include <linux/random.h>
> +ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) {
> + return syscall(__NR_getrandom, buf, buflen, flags);
> +}
> +#endif
> +
> +/*
> + * The command-line argument specifies how many iterations to execute
> + * in this kernel-intensive loop to run.
> + */
> +
> +int
> +main(int argc, const char **argv)
> +{
> + char buf[BUFLEN];
> + long long n;
> +
> + if (argc < 2)
> + return 1;
> + n = atoll(argv[1]);
> +
> + for (long long i = 0; i < n; i++)
> + if (getrandom(buf, BUFLEN, GRND_NONBLOCK) != BUFLEN)
> + return 1;
> +
> + return 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