accel/qaic: Add AIC200 support
[drm/drm-misc.git] / tools / testing / selftests / turbostat / smi_aperf_mperf.py
blob6289cc47d5f00e29dcee4b7c206bcebf38640589
1 #!/bin/env python3
2 # SPDX-License-Identifier: GPL-2.0
4 import subprocess
5 from shutil import which
6 from os import pread
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
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.
20 MSR_IA32_MPERF = 0x000000e7
21 MSR_IA32_APERF = 0x000000e8
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
29 def has_perf_counter_access(counter_name):
30 proc_perf = subprocess.run([perf, 'stat', '-e', counter_name, '--timeout', '10'],
31 capture_output = True)
33 if proc_perf.returncode != 0:
34 print(f'SKIP: Could not read {counter_name} perf counter, assuming no access.')
35 return False
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
41 return True
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
50 return True
52 def check_msr_access():
53 try:
54 file_msr = open(f'/dev/cpu/{BASE_CPU}/msr', 'rb')
55 except:
56 return False
58 if len(pread(file_msr.fileno(), 8, MSR_IA32_MPERF)) != 8:
59 return False
61 if len(pread(file_msr.fileno(), 8, MSR_IA32_APERF)) != 8:
62 return False
64 return True
66 has_perf_access = check_perf_access()
67 has_msr_access = check_msr_access()
69 turbostat_counter_source_opts = ['']
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')
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')
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)
85 turbostat = which('turbostat')
86 if turbostat is None:
87 print('Could not find turbostat binary')
88 exit(1)
90 timeout = which('timeout')
91 if timeout is None:
92 print('Could not find timeout binary')
93 exit(1)
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)
100 EXPECTED_COLUMNS_DEBUG_DEFAULT = b'usec\tTime_Of_Day_Seconds\tAPIC\tX2APIC'
102 SMI_APERF_MPERF_DEPENDENT_BICS = [
103 'SMI',
104 'Avg_MHz',
105 'Busy%',
106 'Bzy_MHz',
108 if has_perf_access:
109 SMI_APERF_MPERF_DEPENDENT_BICS.append('IPC')
111 for bic in SMI_APERF_MPERF_DEPENDENT_BICS:
112 for counter_source_opt in turbostat_counter_source_opts:
114 # Ugly special case, but it is what it is..
115 if counter_source_opt == '--no-perf' and bic == 'IPC':
116 continue
118 expected_columns = bic.encode()
119 expected_columns_debug = EXPECTED_COLUMNS_DEBUG_DEFAULT + f'\t{bic}'.encode()
122 # Run turbostat for some time and send SIGINT
124 timeout_argv = [timeout, '--preserve-status', '-s', 'SIGINT', '-k', '3', '0.2s']
125 turbostat_argv = [turbostat, '-i', '0.50', '--show', bic]
127 if counter_source_opt:
128 turbostat_argv.append(counter_source_opt)
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)
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')
143 # Same, but with --debug
145 turbostat_argv.append('--debug')
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)
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')