Testcase stat+csv_output.sh fails in powerpc:
84: perf stat CSV output linter: FAILED!
The testcase "stat+csv_output.sh" verifies perf stat CSV output. The
test covers aggregation modes like per-socket, per-core, per-die, -A
(no_aggr mode) along with few other tests. It counts expected fields for
various commands. For example say -A (i.e, AGGR_NONE mode), expects 7
fields in the output having "CPU" as first field. Same way, for
per-socket, it expects the first field in result to point to socket id.
The testcases compares the result with expected count.
The values for socket, die, core and cpu are fetched from topology
directory:
/sys/devices/system/cpu/cpu*/topology.
For example, socket value is fetched from "physical_package_id" file of
topology directory. (cpu__get_topology_int() in util/cpumap.c)
If a platform fails to fetch the topology information, values will be
set to -1. For example, incase of pSeries platform of powerpc, value for
"physical_package_id" is restricted and not exposed. So, -1 will be
assigned.
Perf code has a checks for valid cpu id in "aggr_printout"
(stat-display.c), which displays the fields. So, in cases where topology
values not exposed, first field of the output displaying will be empty.
This cause the testcase to fail, as it counts number of fields in the
output.
Incase of -A (AGGR_NONE mode,), testcase expects 7 fields in the output,
becos of -1 value obtained from topology files for some, only 6 fields
are printed. Hence a testcase failure reported due to mismatch in number
of fields in the output.
Patch here adds a sanity check in the testcase for topology. Check will
help to skip the test if -1 value found.
Fixes: 7473ee56db
("perf test: Add checking for perf stat CSV output.")
Reported-by: Disha Goel <disgoel@linux.vnet.ibm.com>
Suggested-by: Ian Rogers <irogers@google.com>
Suggested-by: James Clark <james.clark@arm.com>
Signed-off-by: Athira Jajeev <atrajeev@linux.vnet.ibm.com>
Cc: Claire Jensen <cjense@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nageswara R Sastry <rnsastry@linux.ibm.com>
Link: https://lore.kernel.org/r/20221006155149.67205-1-atrajeev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
204 lines
4.4 KiB
Bash
Executable file
204 lines
4.4 KiB
Bash
Executable file
#!/bin/bash
|
|
# perf stat CSV output linter
|
|
# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
|
# Tests various perf stat CSV output commands for the
|
|
# correct number of fields and the CSV separator set to ','.
|
|
|
|
set -e
|
|
|
|
skip_test=0
|
|
|
|
function commachecker()
|
|
{
|
|
local -i cnt=0
|
|
local exp=0
|
|
|
|
case "$1"
|
|
in "--no-args") exp=6
|
|
;; "--system-wide") exp=6
|
|
;; "--event") exp=6
|
|
;; "--interval") exp=7
|
|
;; "--per-thread") exp=7
|
|
;; "--system-wide-no-aggr") exp=7
|
|
[ $(uname -m) = "s390x" ] && exp='^[6-7]$'
|
|
;; "--per-core") exp=8
|
|
;; "--per-socket") exp=8
|
|
;; "--per-node") exp=8
|
|
;; "--per-die") exp=8
|
|
esac
|
|
|
|
while read line
|
|
do
|
|
# Check for lines beginning with Failed
|
|
x=${line:0:6}
|
|
[ "$x" = "Failed" ] && continue
|
|
|
|
# Count the number of commas
|
|
x=$(echo $line | tr -d -c ',')
|
|
cnt="${#x}"
|
|
# echo $line $cnt
|
|
[[ ! "$cnt" =~ $exp ]] && {
|
|
echo "wrong number of fields. expected $exp in $line" 1>&2
|
|
exit 1;
|
|
}
|
|
done
|
|
return 0
|
|
}
|
|
|
|
# Return true if perf_event_paranoid is > $1 and not running as root.
|
|
function ParanoidAndNotRoot()
|
|
{
|
|
[ $(id -u) != 0 ] && [ $(cat /proc/sys/kernel/perf_event_paranoid) -gt $1 ]
|
|
}
|
|
|
|
check_no_args()
|
|
{
|
|
echo -n "Checking CSV output: no args "
|
|
perf stat -x, true 2>&1 | commachecker --no-args
|
|
echo "[Success]"
|
|
}
|
|
|
|
check_system_wide()
|
|
{
|
|
echo -n "Checking CSV output: system wide "
|
|
if ParanoidAndNotRoot 0
|
|
then
|
|
echo "[Skip] paranoid and not root"
|
|
return
|
|
fi
|
|
perf stat -x, -a true 2>&1 | commachecker --system-wide
|
|
echo "[Success]"
|
|
}
|
|
|
|
check_system_wide_no_aggr()
|
|
{
|
|
echo -n "Checking CSV output: system wide "
|
|
if ParanoidAndNotRoot 0
|
|
then
|
|
echo "[Skip] paranoid and not root"
|
|
return
|
|
fi
|
|
echo -n "Checking CSV output: system wide no aggregation "
|
|
perf stat -x, -A -a --no-merge true 2>&1 | commachecker --system-wide-no-aggr
|
|
echo "[Success]"
|
|
}
|
|
|
|
check_interval()
|
|
{
|
|
echo -n "Checking CSV output: interval "
|
|
perf stat -x, -I 1000 true 2>&1 | commachecker --interval
|
|
echo "[Success]"
|
|
}
|
|
|
|
|
|
check_event()
|
|
{
|
|
echo -n "Checking CSV output: event "
|
|
perf stat -x, -e cpu-clock true 2>&1 | commachecker --event
|
|
echo "[Success]"
|
|
}
|
|
|
|
check_per_core()
|
|
{
|
|
echo -n "Checking CSV output: per core "
|
|
if ParanoidAndNotRoot 0
|
|
then
|
|
echo "[Skip] paranoid and not root"
|
|
return
|
|
fi
|
|
perf stat -x, --per-core -a true 2>&1 | commachecker --per-core
|
|
echo "[Success]"
|
|
}
|
|
|
|
check_per_thread()
|
|
{
|
|
echo -n "Checking CSV output: per thread "
|
|
if ParanoidAndNotRoot 0
|
|
then
|
|
echo "[Skip] paranoid and not root"
|
|
return
|
|
fi
|
|
perf stat -x, --per-thread -a true 2>&1 | commachecker --per-thread
|
|
echo "[Success]"
|
|
}
|
|
|
|
check_per_die()
|
|
{
|
|
echo -n "Checking CSV output: per die "
|
|
if ParanoidAndNotRoot 0
|
|
then
|
|
echo "[Skip] paranoid and not root"
|
|
return
|
|
fi
|
|
perf stat -x, --per-die -a true 2>&1 | commachecker --per-die
|
|
echo "[Success]"
|
|
}
|
|
|
|
check_per_node()
|
|
{
|
|
echo -n "Checking CSV output: per node "
|
|
if ParanoidAndNotRoot 0
|
|
then
|
|
echo "[Skip] paranoid and not root"
|
|
return
|
|
fi
|
|
perf stat -x, --per-node -a true 2>&1 | commachecker --per-node
|
|
echo "[Success]"
|
|
}
|
|
|
|
check_per_socket()
|
|
{
|
|
echo -n "Checking CSV output: per socket "
|
|
if ParanoidAndNotRoot 0
|
|
then
|
|
echo "[Skip] paranoid and not root"
|
|
return
|
|
fi
|
|
perf stat -x, --per-socket -a true 2>&1 | commachecker --per-socket
|
|
echo "[Success]"
|
|
}
|
|
|
|
# The perf stat options for per-socket, per-core, per-die
|
|
# and -A ( no_aggr mode ) uses the info fetched from this
|
|
# directory: "/sys/devices/system/cpu/cpu*/topology". For
|
|
# example, socket value is fetched from "physical_package_id"
|
|
# file in topology directory.
|
|
# Reference: cpu__get_topology_int in util/cpumap.c
|
|
# If the platform doesn't expose topology information, values
|
|
# will be set to -1. For example, incase of pSeries platform
|
|
# of powerpc, value for "physical_package_id" is restricted
|
|
# and set to -1. Check here validates the socket-id read from
|
|
# topology file before proceeding further
|
|
|
|
FILE_LOC="/sys/devices/system/cpu/cpu*/topology/"
|
|
FILE_NAME="physical_package_id"
|
|
|
|
check_for_topology()
|
|
{
|
|
if ! ParanoidAndNotRoot 0
|
|
then
|
|
socket_file=`ls $FILE_LOC/$FILE_NAME | head -n 1`
|
|
[ -z $socket_file ] && return 0
|
|
socket_id=`cat $socket_file`
|
|
[ $socket_id == -1 ] && skip_test=1
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
check_for_topology
|
|
check_no_args
|
|
check_system_wide
|
|
check_interval
|
|
check_event
|
|
check_per_thread
|
|
check_per_node
|
|
if [ $skip_test -ne 1 ]
|
|
then
|
|
check_system_wide_no_aggr
|
|
check_per_core
|
|
check_per_die
|
|
check_per_socket
|
|
else
|
|
echo "[Skip] Skipping tests for system_wide_no_aggr, per_core, per_die and per_socket since socket id exposed via topology is invalid"
|
|
fi
|
|
exit 0
|