5
5
# SPDX-License-Identifier: BSD-3-Clause
6
6
###########################################################################################################
7
7
8
- from __future__ import print_function
9
8
import logging
10
9
import os
11
10
import platform
12
- import re
13
11
import sys
14
12
import subprocess # nosec
15
13
import shlex # nosec
16
14
from argparse import ArgumentParser
17
15
from src import perf_helpers
18
16
from src import prepare_perf_events as prep_events
19
17
from src .common import crash
18
+ from src import common
20
19
21
- logging .basicConfig (
22
- format = "%(asctime)s %(levelname)s: %(message)s" ,
23
- datefmt = "%H:%M:%S" ,
24
- level = logging .NOTSET ,
25
- handlers = [logging .FileHandler ("debug.log" ), logging .StreamHandler (sys .stdout )],
26
- )
27
- log = logging .getLogger (__name__ )
28
20
29
21
SUPPORTED_ARCHITECTURES = [
30
22
"Broadwell" ,
@@ -54,7 +46,9 @@ def write_metadata(
54
46
with open (outcsv , "r" ) as original :
55
47
time_stamp = original .readline ()
56
48
if metadata_only and time_stamp .startswith ("### META DATA ###" ):
57
- log .warning ("Not prepending metadata, already present in %s " % (outcsv ))
49
+ logging .warning (
50
+ "Not prepending metadata, already present in %s " % (outcsv )
51
+ )
58
52
return
59
53
data = original .read ()
60
54
with open (outcsv , "w" ) as modified :
@@ -164,22 +158,16 @@ def validate_file(fname):
164
158
crash (str (fname ) + " not accessible" )
165
159
166
160
167
- def is_safe_file (fname , substr ):
168
- """verify if file name/format is accurate"""
169
- if not fname .endswith (substr ):
170
- crash (str (fname ) + " isn't appropriate format" )
171
-
172
-
173
161
if __name__ == "__main__" :
162
+ common .configure_logging ("." )
174
163
if platform .system () != "Linux" :
175
164
crash ("PerfSpect currently supports Linux only" )
176
165
177
166
# fix the pyinstaller path
178
167
script_path = os .path .dirname (os .path .realpath (__file__ ))
179
168
if "_MEI" in script_path :
180
169
script_path = script_path .rsplit ("/" , 1 )[0 ]
181
- result_dir = script_path + "/results"
182
- default_output_file = result_dir + "/perfstat.csv"
170
+ default_output_file = "perfstat.csv"
183
171
184
172
parser = ArgumentParser (description = "perf-collect: Time series dump of PMUs" )
185
173
duration = parser .add_mutually_exclusive_group ()
@@ -225,7 +213,7 @@ def is_safe_file(fname, substr):
225
213
"--outcsv" ,
226
214
type = str ,
227
215
default = default_output_file ,
228
- help = "perf stat output in csv format, default=results/ perfstat.csv" ,
216
+ help = "perf stat output in csv format, default=perfstat.csv" ,
229
217
)
230
218
parser .add_argument (
231
219
"-v" ,
@@ -237,7 +225,7 @@ def is_safe_file(fname, substr):
237
225
238
226
if args .version :
239
227
print (perf_helpers .get_tool_version ())
240
- sys .exit (0 )
228
+ sys .exit ()
241
229
242
230
if os .geteuid () != 0 :
243
231
crash ("Must run PerfSpect as root, please re-run" )
@@ -249,7 +237,7 @@ def is_safe_file(fname, substr):
249
237
nmi_watchdog = f_nmi .read ()
250
238
if int (nmi_watchdog ) != 0 :
251
239
f_nmi .write ("0" )
252
- log .info ("nmi_watchdog disabled" )
240
+ logging .info ("nmi_watchdog disabled" )
253
241
except FileNotFoundError :
254
242
pass
255
243
@@ -278,28 +266,24 @@ def is_safe_file(fname, substr):
278
266
elif arch == "sapphirerapids" :
279
267
eventfile = "spr.txt"
280
268
269
+ if eventfile is None :
270
+ crash (f"failed to match architecture ({ arch } ) to event file name." )
271
+
281
272
# Convert path of event file to relative path if being packaged by pyInstaller into a binary
282
273
if getattr (sys , "frozen" , False ):
283
274
basepath = getattr (sys , "_MEIPASS" , os .path .dirname (os .path .abspath (__file__ )))
284
275
eventfilename = eventfile
285
- is_safe_file (eventfile , ".txt" )
286
276
eventfile = os .path .join (basepath , eventfile )
287
277
elif __file__ :
288
278
eventfile = script_path + "/events/" + eventfile
289
279
eventfilename = eventfile
290
280
else :
291
281
crash ("Unknown application type" )
292
282
293
- if args .outcsv == default_output_file :
294
- # create results dir
295
- if not os .path .exists (result_dir ):
296
- os .mkdir (result_dir )
297
- perf_helpers .fix_path_ownership (result_dir )
298
- else :
299
- if not perf_helpers .validate_outfile (args .outcsv ):
300
- crash (
301
- "Output filename not accepted. Filename should be a .csv without special characters"
302
- )
283
+ if not perf_helpers .validate_outfile (args .outcsv ):
284
+ crash (
285
+ "Output filename not accepted. Filename should be a .csv without special characters"
286
+ )
303
287
304
288
mux_intervals = perf_helpers .get_perf_event_mux_interval ()
305
289
if args .muxinterval > 0 :
@@ -311,22 +295,21 @@ def is_safe_file(fname, substr):
311
295
cgroups = perf_helpers .get_cgroups_from_cids (args .cid .split ("," ))
312
296
num_cgroups = len (cgroups )
313
297
314
- try :
315
- reg = r"^[0-9]*\.[0-9][0-9]*"
316
- kernel = perf_helpers .get_version ().split ("Linux version" )[1 ].lstrip ()
317
- significant_kernel_version = re .match (reg , kernel ).group (0 )
318
- full_kernel_version = kernel
319
- except Exception as e :
320
- log .exception (e )
321
- crash ("Unable to get kernel version" )
322
-
323
298
# get perf events to collect
324
299
collection_events = []
325
300
imc , cha , upi = perf_helpers .get_imc_cacheagent_count ()
326
301
have_uncore = True
327
302
if imc == 0 and cha == 0 and upi == 0 :
328
- log .info ("disabling uncore (possibly in a vm?)" )
303
+ logging .info ("disabling uncore (possibly in a vm?)" )
329
304
have_uncore = False
305
+ if arch == "icelake" :
306
+ logging .warning (
307
+ "Due to lack of vPMU support, TMA L1 events will not be collected"
308
+ )
309
+ if arch == "sapphirerapids" :
310
+ logging .warning (
311
+ "Due to lack of vPMU support, TMA L1 & L2 events will not be collected"
312
+ )
330
313
events , collection_events = prep_events .prepare_perf_events (
331
314
eventfile ,
332
315
(
@@ -341,7 +324,7 @@ def is_safe_file(fname, substr):
341
324
collection_type = "-a" if not args .thread and not args .socket else "-a -A"
342
325
# start perf stat
343
326
if args .pid and args .timeout :
344
- log .info ("Only CPU/core events will be enabled with pid option" )
327
+ logging .info ("Only CPU/core events will be enabled with pid option" )
345
328
cmd = "perf stat -I %d -x , --pid %s -e %s -o %s sleep %d" % (
346
329
interval ,
347
330
args .pid ,
@@ -351,15 +334,15 @@ def is_safe_file(fname, substr):
351
334
)
352
335
353
336
elif args .pid :
354
- log .info ("Only CPU/core events will be enabled with pid option" )
337
+ logging .info ("Only CPU/core events will be enabled with pid option" )
355
338
cmd = "perf stat -I %d -x , --pid %s -e %s -o %s" % (
356
339
interval ,
357
340
args .pid ,
358
341
events ,
359
342
args .outcsv ,
360
343
)
361
344
elif args .cid and args .timeout :
362
- log .info ("Only CPU/core events will be enabled with cid option" )
345
+ logging .info ("Only CPU/core events will be enabled with cid option" )
363
346
perf_format = prep_events .get_cgroup_events_format (
364
347
cgroups , events , len (collection_events )
365
348
)
@@ -370,7 +353,7 @@ def is_safe_file(fname, substr):
370
353
args .timeout ,
371
354
)
372
355
elif args .cid :
373
- log .info ("Only CPU/core events will be enabled with cid option" )
356
+ logging .info ("Only CPU/core events will be enabled with cid option" )
374
357
perf_format = prep_events .get_cgroup_events_format (
375
358
cgroups , events , len (collection_events )
376
359
)
@@ -402,13 +385,13 @@ def is_safe_file(fname, substr):
402
385
validate_perfargs (perfargs )
403
386
perf_helpers .pmu_contention_detect (msrs = initial_pmus , detect = True )
404
387
if args .verbose :
405
- log .info (cmd )
388
+ logging .info (cmd )
406
389
try :
407
- log .info ("Collecting perf stat for events in : %s" % eventfilename )
390
+ logging .info ("Collecting perf stat for events in : %s" % eventfilename )
408
391
subprocess .call (perfargs ) # nosec
409
- log .info ("Collection complete! Calculating TSC frequency now" )
392
+ logging .info ("Collection complete! Calculating TSC frequency now" )
410
393
except KeyboardInterrupt :
411
- log .info ("Collection stopped! Caculating TSC frequency now" )
394
+ logging .info ("Collection stopped! Caculating TSC frequency now" )
412
395
except Exception :
413
396
crash ("perf encountered errors" )
414
397
@@ -425,13 +408,14 @@ def is_safe_file(fname, substr):
425
408
False ,
426
409
)
427
410
411
+ os .chmod (args .outcsv , 0o666 ) # nosec
412
+
428
413
# reset nmi_watchdog to what it was before running perfspect
429
414
with open ("/proc/sys/kernel/nmi_watchdog" , "w" ) as f_nmi :
430
415
if int (nmi_watchdog ) != 0 :
431
416
f_nmi .write (nmi_watchdog )
432
- log .info ("nmi_watchdog re-enabled" )
417
+ logging .info ("nmi_watchdog re-enabled" )
433
418
434
419
perf_helpers .set_perf_event_mux_interval (True , 1 , mux_intervals )
435
420
436
- log .info ("perf stat dumped to %s" % args .outcsv )
437
- perf_helpers .fix_path_ownership (result_dir , True )
421
+ logging .info ("perf stat dumped to %s" % args .outcsv )
0 commit comments