~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/turbostat/smi_aperf_mperf.py

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #!/bin/env python3
  2 # SPDX-License-Identifier: GPL-2.0
  3 
  4 import subprocess
  5 from shutil import which
  6 from os import pread
  7 
  8 # CDLL calls dlopen underneath.
  9 # Calling it with None (null), we get handle to the our own image (python interpreter).
 10 # We hope to find sched_getcpu() inside ;]
 11 # This is a bit ugly, but helps shipping working software, so..
 12 try:
 13         import ctypes
 14 
 15         this_image = ctypes.CDLL(None)
 16         BASE_CPU = this_image.sched_getcpu()
 17 except:
 18         BASE_CPU = 0 # If we fail, set to 0 and pray it's not offline.
 19 
 20 MSR_IA32_MPERF = 0x000000e7
 21 MSR_IA32_APERF = 0x000000e8
 22 
 23 def check_perf_access():
 24         perf = which('perf')
 25         if perf is None:
 26                 print('SKIP: Could not find perf binary, thus could not determine perf access.')
 27                 return False
 28 
 29         def has_perf_counter_access(counter_name):
 30                 proc_perf = subprocess.run([perf, 'stat', '-e', counter_name, '--timeout', '10'],
 31                                             capture_output = True)
 32 
 33                 if proc_perf.returncode != 0:
 34                         print(f'SKIP: Could not read {counter_name} perf counter, assuming no access.')
 35                         return False
 36 
 37                 if b'<not supported>' in proc_perf.stderr:
 38                         print(f'SKIP: Could not read {counter_name} perf counter, assuming no access.')
 39                         return False
 40 
 41                 return True
 42 
 43         if not has_perf_counter_access('msr/mperf/'):
 44                 return False
 45         if not has_perf_counter_access('msr/aperf/'):
 46                 return False
 47         if not has_perf_counter_access('msr/smi/'):
 48                 return False
 49 
 50         return True
 51 
 52 def check_msr_access():
 53         try:
 54                 file_msr = open(f'/dev/cpu/{BASE_CPU}/msr', 'rb')
 55         except:
 56                 return False
 57 
 58         if len(pread(file_msr.fileno(), 8, MSR_IA32_MPERF)) != 8:
 59                 return False
 60 
 61         if len(pread(file_msr.fileno(), 8, MSR_IA32_APERF)) != 8:
 62                 return False
 63 
 64         return True
 65 
 66 has_perf_access = check_perf_access()
 67 has_msr_access = check_msr_access()
 68 
 69 turbostat_counter_source_opts = ['']
 70 
 71 if has_msr_access:
 72         turbostat_counter_source_opts.append('--no-perf')
 73 else:
 74         print('SKIP: doesn\'t have MSR access, skipping run with --no-perf')
 75 
 76 if has_perf_access:
 77         turbostat_counter_source_opts.append('--no-msr')
 78 else:
 79         print('SKIP: doesn\'t have perf access, skipping run with --no-msr')
 80 
 81 if not has_msr_access and not has_perf_access:
 82         print('SKIP: No MSR nor perf access detected. Skipping the tests entirely')
 83         exit(0)
 84 
 85 turbostat = which('turbostat')
 86 if turbostat is None:
 87         print('Could not find turbostat binary')
 88         exit(1)
 89 
 90 timeout = which('timeout')
 91 if timeout is None:
 92         print('Could not find timeout binary')
 93         exit(1)
 94 
 95 proc_turbostat = subprocess.run([turbostat, '--list'], capture_output = True)
 96 if proc_turbostat.returncode != 0:
 97         print(f'turbostat failed with {proc_turbostat.returncode}')
 98         exit(1)
 99 
100 EXPECTED_COLUMNS_DEBUG_DEFAULT = b'usec\tTime_Of_Day_Seconds\tAPIC\tX2APIC'
101 
102 SMI_APERF_MPERF_DEPENDENT_BICS = [
103         'SMI',
104         'Avg_MHz',
105         'Busy%',
106         'Bzy_MHz',
107 ]
108 if has_perf_access:
109         SMI_APERF_MPERF_DEPENDENT_BICS.append('IPC')
110 
111 for bic in SMI_APERF_MPERF_DEPENDENT_BICS:
112         for counter_source_opt in turbostat_counter_source_opts:
113 
114                 # Ugly special case, but it is what it is..
115                 if counter_source_opt == '--no-perf' and bic == 'IPC':
116                         continue
117 
118                 expected_columns = bic.encode()
119                 expected_columns_debug = EXPECTED_COLUMNS_DEBUG_DEFAULT + f'\t{bic}'.encode()
120 
121                 #
122                 # Run turbostat for some time and send SIGINT
123                 #
124                 timeout_argv = [timeout, '--preserve-status', '-s', 'SIGINT', '-k', '3', '0.2s']
125                 turbostat_argv = [turbostat, '-i', '0.50', '--show', bic]
126 
127                 if counter_source_opt:
128                         turbostat_argv.append(counter_source_opt)
129 
130                 print(f'Running turbostat with {turbostat_argv=}... ', end = '', flush = True)
131                 proc_turbostat = subprocess.run(timeout_argv + turbostat_argv, capture_output = True)
132                 if proc_turbostat.returncode != 0:
133                         print(f'turbostat failed with {proc_turbostat.returncode}')
134                         exit(1)
135 
136                 actual_columns = proc_turbostat.stdout.split(b'\n')[0]
137                 if expected_columns != actual_columns:
138                         print(f'turbostat column check failed\n{expected_columns=}\n{actual_columns=}')
139                         exit(1)
140                 print('OK')
141 
142                 #
143                 # Same, but with --debug
144                 #
145                 turbostat_argv.append('--debug')
146 
147                 print(f'Running turbostat with {turbostat_argv=}... ', end = '', flush = True)
148                 proc_turbostat = subprocess.run(timeout_argv + turbostat_argv, capture_output = True)
149                 if proc_turbostat.returncode != 0:
150                         print(f'turbostat failed with {proc_turbostat.returncode}')
151                         exit(1)
152 
153                 actual_columns = proc_turbostat.stdout.split(b'\n')[0]
154                 if expected_columns_debug != actual_columns:
155                         print(f'turbostat column check failed\n{expected_columns_debug=}\n{actual_columns=}')
156                         exit(1)
157                 print('OK')

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php