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 26# Return true if perf_event_paranoid is > $1 and not running as root. 27function ParanoidAndNotRoot() 28{ 29 [ $(id -u) != 0 ] && [ $(cat /proc/sys/kernel/perf_event_paranoid) -gt $1 ] 30} 31 32check_no_args() 33{ 34 echo -n "Checking json output: no args " 35 perf stat -j true 2>&1 | $PYTHON $pythonchecker --no-args 36 echo "[Success]" 37} 38 39check_system_wide() 40{ 41 echo -n "Checking json output: system wide " 42 if ParanoidAndNotRoot 0 43 then 44 echo "[Skip] paranoia and not root" 45 return 46 fi 47 perf stat -j -a true 2>&1 | $PYTHON $pythonchecker --system-wide 48 echo "[Success]" 49} 50 51check_system_wide_no_aggr() 52{ 53 echo -n "Checking json output: system wide " 54 if ParanoidAndNotRoot 0 55 then 56 echo "[Skip] paranoia and not root" 57 return 58 fi 59 echo -n "Checking json output: system wide no aggregation " 60 perf stat -j -A -a --no-merge true 2>&1 | $PYTHON $pythonchecker --system-wide-no-aggr 61 echo "[Success]" 62} 63 64check_interval() 65{ 66 echo -n "Checking json output: interval " 67 perf stat -j -I 1000 true 2>&1 | $PYTHON $pythonchecker --interval 68 echo "[Success]" 69} 70 71 72check_event() 73{ 74 echo -n "Checking json output: event " 75 perf stat -j -e cpu-clock true 2>&1 | $PYTHON $pythonchecker --event 76 echo "[Success]" 77} 78 79check_per_core() 80{ 81 echo -n "Checking json output: per core " 82 if ParanoidAndNotRoot 0 83 then 84 echo "[Skip] paranoia and not root" 85 return 86 fi 87 perf stat -j --per-core -a true 2>&1 | $PYTHON $pythonchecker --per-core 88 echo "[Success]" 89} 90 91check_per_thread() 92{ 93 echo -n "Checking json output: per thread " 94 if ParanoidAndNotRoot 0 95 then 96 echo "[Skip] paranoia and not root" 97 return 98 fi 99 perf stat -j --per-thread -a true 2>&1 | $PYTHON $pythonchecker --per-thread 100 echo "[Success]" 101} 102 103check_per_die() 104{ 105 echo -n "Checking json output: per die " 106 if ParanoidAndNotRoot 0 107 then 108 echo "[Skip] paranoia and not root" 109 return 110 fi 111 perf stat -j --per-die -a true 2>&1 | $PYTHON $pythonchecker --per-die 112 echo "[Success]" 113} 114 115check_per_node() 116{ 117 echo -n "Checking json output: per node " 118 if ParanoidAndNotRoot 0 119 then 120 echo "[Skip] paranoia and not root" 121 return 122 fi 123 perf stat -j --per-node -a true 2>&1 | $PYTHON $pythonchecker --per-node 124 echo "[Success]" 125} 126 127check_per_socket() 128{ 129 echo -n "Checking json output: per socket " 130 if ParanoidAndNotRoot 0 131 then 132 echo "[Skip] paranoia and not root" 133 return 134 fi 135 perf stat -j --per-socket -a true 2>&1 | $PYTHON $pythonchecker --per-socket 136 echo "[Success]" 137} 138 139# The perf stat options for per-socket, per-core, per-die 140# and -A ( no_aggr mode ) uses the info fetched from this 141# directory: "/sys/devices/system/cpu/cpu*/topology". For 142# example, socket value is fetched from "physical_package_id" 143# file in topology directory. 144# Reference: cpu__get_topology_int in util/cpumap.c 145# If the platform doesn't expose topology information, values 146# will be set to -1. For example, incase of pSeries platform 147# of powerpc, value for "physical_package_id" is restricted 148# and set to -1. Check here validates the socket-id read from 149# topology file before proceeding further 150 151FILE_LOC="/sys/devices/system/cpu/cpu*/topology/" 152FILE_NAME="physical_package_id" 153 154check_for_topology() 155{ 156 if ! ParanoidAndNotRoot 0 157 then 158 socket_file=`ls $FILE_LOC/$FILE_NAME | head -n 1` 159 [ -z $socket_file ] && return 0 160 socket_id=`cat $socket_file` 161 [ $socket_id == -1 ] && skip_test=1 162 return 0 163 fi 164} 165 166check_for_topology 167check_no_args 168check_system_wide 169check_interval 170check_event 171check_per_thread 172check_per_node 173if [ $skip_test -ne 1 ] 174then 175 check_system_wide_no_aggr 176 check_per_core 177 check_per_die 178 check_per_socket 179else 180 echo "[Skip] Skipping tests for system_wide_no_aggr, per_core, per_die and per_socket since socket id exposed via topology is invalid" 181fi 182exit 0 183