Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#!/bin/bash
2# perf stat JSON output linter
3# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
4# Checks various perf stat JSON output commands for the
5# correct number of fields.
6
7set -e
8
9skip_test=0
10
11pythonchecker=$(dirname $0)/lib/perf_json_output_lint.py
12if [ "x$PYTHON" == "x" ]
13then
14 if which python3 > /dev/null
15 then
16 PYTHON=python3
17 elif which python > /dev/null
18 then
19 PYTHON=python
20 else
21 echo Skipping test, python not detected please set environment variable PYTHON.
22 exit 2
23 fi
24fi
25
26stat_output=$(mktemp /tmp/__perf_test.stat_output.json.XXXXX)
27
28cleanup() {
29 rm -f "${stat_output}"
30
31 trap - EXIT TERM INT
32}
33
34trap_cleanup() {
35 cleanup
36 exit 1
37}
38trap trap_cleanup EXIT TERM INT
39
40# Return true if perf_event_paranoid is > $1 and not running as root.
41function ParanoidAndNotRoot()
42{
43 [ "$(id -u)" != 0 ] && [ "$(cat /proc/sys/kernel/perf_event_paranoid)" -gt $1 ]
44}
45
46check_no_args()
47{
48 echo -n "Checking json output: no args "
49 perf stat -j -o "${stat_output}" true
50 $PYTHON $pythonchecker --no-args --file "${stat_output}"
51 echo "[Success]"
52}
53
54check_system_wide()
55{
56 echo -n "Checking json output: system wide "
57 if ParanoidAndNotRoot 0
58 then
59 echo "[Skip] paranoia and not root"
60 return
61 fi
62 perf stat -j -a -o "${stat_output}" true
63 $PYTHON $pythonchecker --system-wide --file "${stat_output}"
64 echo "[Success]"
65}
66
67check_system_wide_no_aggr()
68{
69 echo -n "Checking json output: system wide no aggregation "
70 if ParanoidAndNotRoot 0
71 then
72 echo "[Skip] paranoia and not root"
73 return
74 fi
75 perf stat -j -A -a --no-merge -o "${stat_output}" true
76 $PYTHON $pythonchecker --system-wide-no-aggr --file "${stat_output}"
77 echo "[Success]"
78}
79
80check_interval()
81{
82 echo -n "Checking json output: interval "
83 perf stat -j -I 1000 -o "${stat_output}" true
84 $PYTHON $pythonchecker --interval --file "${stat_output}"
85 echo "[Success]"
86}
87
88
89check_event()
90{
91 echo -n "Checking json output: event "
92 perf stat -j -e cpu-clock -o "${stat_output}" true
93 $PYTHON $pythonchecker --event --file "${stat_output}"
94 echo "[Success]"
95}
96
97check_per_core()
98{
99 echo -n "Checking json output: per core "
100 if ParanoidAndNotRoot 0
101 then
102 echo "[Skip] paranoia and not root"
103 return
104 fi
105 perf stat -j --per-core -a -o "${stat_output}" true
106 $PYTHON $pythonchecker --per-core --file "${stat_output}"
107 echo "[Success]"
108}
109
110check_per_thread()
111{
112 echo -n "Checking json output: per thread "
113 if ParanoidAndNotRoot 0
114 then
115 echo "[Skip] paranoia and not root"
116 return
117 fi
118 perf stat -j --per-thread -a -o "${stat_output}" true
119 $PYTHON $pythonchecker --per-thread --file "${stat_output}"
120 echo "[Success]"
121}
122
123check_per_cache_instance()
124{
125 echo -n "Checking json output: per cache_instance "
126 if ParanoidAndNotRoot 0
127 then
128 echo "[Skip] paranoia and not root"
129 return
130 fi
131 perf stat -j --per-cache -a true 2>&1 | $PYTHON $pythonchecker --per-cache
132 echo "[Success]"
133}
134
135check_per_die()
136{
137 echo -n "Checking json output: per die "
138 if ParanoidAndNotRoot 0
139 then
140 echo "[Skip] paranoia and not root"
141 return
142 fi
143 perf stat -j --per-die -a -o "${stat_output}" true
144 $PYTHON $pythonchecker --per-die --file "${stat_output}"
145 echo "[Success]"
146}
147
148check_per_node()
149{
150 echo -n "Checking json output: per node "
151 if ParanoidAndNotRoot 0
152 then
153 echo "[Skip] paranoia and not root"
154 return
155 fi
156 perf stat -j --per-node -a -o "${stat_output}" true
157 $PYTHON $pythonchecker --per-node --file "${stat_output}"
158 echo "[Success]"
159}
160
161check_per_socket()
162{
163 echo -n "Checking json output: per socket "
164 if ParanoidAndNotRoot 0
165 then
166 echo "[Skip] paranoia and not root"
167 return
168 fi
169 perf stat -j --per-socket -a -o "${stat_output}" true
170 $PYTHON $pythonchecker --per-socket --file "${stat_output}"
171 echo "[Success]"
172}
173
174# The perf stat options for per-socket, per-core, per-die
175# and -A ( no_aggr mode ) uses the info fetched from this
176# directory: "/sys/devices/system/cpu/cpu*/topology". For
177# example, socket value is fetched from "physical_package_id"
178# file in topology directory.
179# Reference: cpu__get_topology_int in util/cpumap.c
180# If the platform doesn't expose topology information, values
181# will be set to -1. For example, incase of pSeries platform
182# of powerpc, value for "physical_package_id" is restricted
183# and set to -1. Check here validates the socket-id read from
184# topology file before proceeding further
185
186FILE_LOC="/sys/devices/system/cpu/cpu*/topology/"
187FILE_NAME="physical_package_id"
188
189check_for_topology()
190{
191 if ! ParanoidAndNotRoot 0
192 then
193 socket_file=`ls $FILE_LOC/$FILE_NAME | head -n 1`
194 [ -z $socket_file ] && return 0
195 socket_id=`cat $socket_file`
196 [ $socket_id == -1 ] && skip_test=1
197 return 0
198 fi
199}
200
201check_for_topology
202check_no_args
203check_system_wide
204check_interval
205check_event
206check_per_thread
207check_per_node
208if [ $skip_test -ne 1 ]
209then
210 check_system_wide_no_aggr
211 check_per_core
212 check_per_cache_instance
213 check_per_die
214 check_per_socket
215else
216 echo "[Skip] Skipping tests for system_wide_no_aggr, per_core, per_die and per_socket since socket id exposed via topology is invalid"
217fi
218cleanup
219exit 0