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 CSV output linter
3# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
4# Tests various perf stat CSV output commands for the
5# correct number of fields and the CSV separator set to ','.
6
7set -e
8
9skip_test=0
10csv_sep=@
11
12function commachecker()
13{
14 local -i cnt=0
15 local exp=0
16
17 case "$1"
18 in "--no-args") exp=6
19 ;; "--system-wide") exp=6
20 ;; "--event") exp=6
21 ;; "--interval") exp=7
22 ;; "--per-thread") exp=7
23 ;; "--system-wide-no-aggr") exp=7
24 [ $(uname -m) = "s390x" ] && exp='^[6-7]$'
25 ;; "--per-core") exp=8
26 ;; "--per-socket") exp=8
27 ;; "--per-node") exp=8
28 ;; "--per-die") exp=8
29 esac
30
31 while read line
32 do
33 # Check for lines beginning with Failed
34 x=${line:0:6}
35 [ "$x" = "Failed" ] && continue
36
37 # Count the number of commas
38 x=$(echo $line | tr -d -c $csv_sep)
39 cnt="${#x}"
40 # echo $line $cnt
41 [[ ! "$cnt" =~ $exp ]] && {
42 echo "wrong number of fields. expected $exp in $line" 1>&2
43 exit 1;
44 }
45 done
46 return 0
47}
48
49# Return true if perf_event_paranoid is > $1 and not running as root.
50function ParanoidAndNotRoot()
51{
52 [ $(id -u) != 0 ] && [ $(cat /proc/sys/kernel/perf_event_paranoid) -gt $1 ]
53}
54
55check_no_args()
56{
57 echo -n "Checking CSV output: no args "
58 perf stat -x$csv_sep true 2>&1 | commachecker --no-args
59 echo "[Success]"
60}
61
62check_system_wide()
63{
64 echo -n "Checking CSV output: system wide "
65 if ParanoidAndNotRoot 0
66 then
67 echo "[Skip] paranoid and not root"
68 return
69 fi
70 perf stat -x$csv_sep -a true 2>&1 | commachecker --system-wide
71 echo "[Success]"
72}
73
74check_system_wide_no_aggr()
75{
76 echo -n "Checking CSV output: system wide "
77 if ParanoidAndNotRoot 0
78 then
79 echo "[Skip] paranoid and not root"
80 return
81 fi
82 echo -n "Checking CSV output: system wide no aggregation "
83 perf stat -x$csv_sep -A -a --no-merge true 2>&1 | commachecker --system-wide-no-aggr
84 echo "[Success]"
85}
86
87check_interval()
88{
89 echo -n "Checking CSV output: interval "
90 perf stat -x$csv_sep -I 1000 true 2>&1 | commachecker --interval
91 echo "[Success]"
92}
93
94
95check_event()
96{
97 echo -n "Checking CSV output: event "
98 perf stat -x$csv_sep -e cpu-clock true 2>&1 | commachecker --event
99 echo "[Success]"
100}
101
102check_per_core()
103{
104 echo -n "Checking CSV output: per core "
105 if ParanoidAndNotRoot 0
106 then
107 echo "[Skip] paranoid and not root"
108 return
109 fi
110 perf stat -x$csv_sep --per-core -a true 2>&1 | commachecker --per-core
111 echo "[Success]"
112}
113
114check_per_thread()
115{
116 echo -n "Checking CSV output: per thread "
117 if ParanoidAndNotRoot 0
118 then
119 echo "[Skip] paranoid and not root"
120 return
121 fi
122 perf stat -x$csv_sep --per-thread -a true 2>&1 | commachecker --per-thread
123 echo "[Success]"
124}
125
126check_per_die()
127{
128 echo -n "Checking CSV output: per die "
129 if ParanoidAndNotRoot 0
130 then
131 echo "[Skip] paranoid and not root"
132 return
133 fi
134 perf stat -x$csv_sep --per-die -a true 2>&1 | commachecker --per-die
135 echo "[Success]"
136}
137
138check_per_node()
139{
140 echo -n "Checking CSV output: per node "
141 if ParanoidAndNotRoot 0
142 then
143 echo "[Skip] paranoid and not root"
144 return
145 fi
146 perf stat -x$csv_sep --per-node -a true 2>&1 | commachecker --per-node
147 echo "[Success]"
148}
149
150check_per_socket()
151{
152 echo -n "Checking CSV output: per socket "
153 if ParanoidAndNotRoot 0
154 then
155 echo "[Skip] paranoid and not root"
156 return
157 fi
158 perf stat -x$csv_sep --per-socket -a true 2>&1 | commachecker --per-socket
159 echo "[Success]"
160}
161
162# The perf stat options for per-socket, per-core, per-die
163# and -A ( no_aggr mode ) uses the info fetched from this
164# directory: "/sys/devices/system/cpu/cpu*/topology". For
165# example, socket value is fetched from "physical_package_id"
166# file in topology directory.
167# Reference: cpu__get_topology_int in util/cpumap.c
168# If the platform doesn't expose topology information, values
169# will be set to -1. For example, incase of pSeries platform
170# of powerpc, value for "physical_package_id" is restricted
171# and set to -1. Check here validates the socket-id read from
172# topology file before proceeding further
173
174FILE_LOC="/sys/devices/system/cpu/cpu*/topology/"
175FILE_NAME="physical_package_id"
176
177check_for_topology()
178{
179 if ! ParanoidAndNotRoot 0
180 then
181 socket_file=`ls $FILE_LOC/$FILE_NAME | head -n 1`
182 [ -z $socket_file ] && return 0
183 socket_id=`cat $socket_file`
184 [ $socket_id == -1 ] && skip_test=1
185 return 0
186 fi
187}
188
189check_for_topology
190check_no_args
191check_system_wide
192check_interval
193check_event
194check_per_thread
195check_per_node
196if [ $skip_test -ne 1 ]
197then
198 check_system_wide_no_aggr
199 check_per_core
200 check_per_die
201 check_per_socket
202else
203 echo "[Skip] Skipping tests for system_wide_no_aggr, per_core, per_die and per_socket since socket id exposed via topology is invalid"
204fi
205exit 0