[DTrace-devel] [PATCH 04/16] cpc: Add probe-args tests
eugene.loh at oracle.com
eugene.loh at oracle.com
Fri Jan 27 02:23:17 UTC 2023
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
More information about the DTrace-devel
mailing list