55# SPDX-License-Identifier: BSD-3-Clause
66###########################################################################################################
77
8- from __future__ import print_function
98import logging
109import os
1110import platform
12- import re
1311import sys
1412import subprocess # nosec
1513import shlex # nosec
1614from argparse import ArgumentParser
1715from src import perf_helpers
1816from src import prepare_perf_events as prep_events
1917from src .common import crash
18+ from src import common
2019
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__ )
2820
2921SUPPORTED_ARCHITECTURES = [
3022 "Broadwell" ,
@@ -54,7 +46,9 @@ def write_metadata(
5446 with open (outcsv , "r" ) as original :
5547 time_stamp = original .readline ()
5648 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+ )
5852 return
5953 data = original .read ()
6054 with open (outcsv , "w" ) as modified :
@@ -164,22 +158,16 @@ def validate_file(fname):
164158 crash (str (fname ) + " not accessible" )
165159
166160
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-
173161if __name__ == "__main__" :
162+ common .configure_logging ("." )
174163 if platform .system () != "Linux" :
175164 crash ("PerfSpect currently supports Linux only" )
176165
177166 # fix the pyinstaller path
178167 script_path = os .path .dirname (os .path .realpath (__file__ ))
179168 if "_MEI" in script_path :
180169 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"
183171
184172 parser = ArgumentParser (description = "perf-collect: Time series dump of PMUs" )
185173 duration = parser .add_mutually_exclusive_group ()
@@ -225,7 +213,7 @@ def is_safe_file(fname, substr):
225213 "--outcsv" ,
226214 type = str ,
227215 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" ,
229217 )
230218 parser .add_argument (
231219 "-v" ,
@@ -237,7 +225,7 @@ def is_safe_file(fname, substr):
237225
238226 if args .version :
239227 print (perf_helpers .get_tool_version ())
240- sys .exit (0 )
228+ sys .exit ()
241229
242230 if os .geteuid () != 0 :
243231 crash ("Must run PerfSpect as root, please re-run" )
@@ -249,7 +237,7 @@ def is_safe_file(fname, substr):
249237 nmi_watchdog = f_nmi .read ()
250238 if int (nmi_watchdog ) != 0 :
251239 f_nmi .write ("0" )
252- log .info ("nmi_watchdog disabled" )
240+ logging .info ("nmi_watchdog disabled" )
253241 except FileNotFoundError :
254242 pass
255243
@@ -278,28 +266,24 @@ def is_safe_file(fname, substr):
278266 elif arch == "sapphirerapids" :
279267 eventfile = "spr.txt"
280268
269+ if eventfile is None :
270+ crash (f"failed to match architecture ({ arch } ) to event file name." )
271+
281272 # Convert path of event file to relative path if being packaged by pyInstaller into a binary
282273 if getattr (sys , "frozen" , False ):
283274 basepath = getattr (sys , "_MEIPASS" , os .path .dirname (os .path .abspath (__file__ )))
284275 eventfilename = eventfile
285- is_safe_file (eventfile , ".txt" )
286276 eventfile = os .path .join (basepath , eventfile )
287277 elif __file__ :
288278 eventfile = script_path + "/events/" + eventfile
289279 eventfilename = eventfile
290280 else :
291281 crash ("Unknown application type" )
292282
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+ )
303287
304288 mux_intervals = perf_helpers .get_perf_event_mux_interval ()
305289 if args .muxinterval > 0 :
@@ -311,22 +295,21 @@ def is_safe_file(fname, substr):
311295 cgroups = perf_helpers .get_cgroups_from_cids (args .cid .split ("," ))
312296 num_cgroups = len (cgroups )
313297
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-
323298 # get perf events to collect
324299 collection_events = []
325300 imc , cha , upi = perf_helpers .get_imc_cacheagent_count ()
326301 have_uncore = True
327302 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?)" )
329304 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+ )
330313 events , collection_events = prep_events .prepare_perf_events (
331314 eventfile ,
332315 (
@@ -341,7 +324,7 @@ def is_safe_file(fname, substr):
341324 collection_type = "-a" if not args .thread and not args .socket else "-a -A"
342325 # start perf stat
343326 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" )
345328 cmd = "perf stat -I %d -x , --pid %s -e %s -o %s sleep %d" % (
346329 interval ,
347330 args .pid ,
@@ -351,15 +334,15 @@ def is_safe_file(fname, substr):
351334 )
352335
353336 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" )
355338 cmd = "perf stat -I %d -x , --pid %s -e %s -o %s" % (
356339 interval ,
357340 args .pid ,
358341 events ,
359342 args .outcsv ,
360343 )
361344 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" )
363346 perf_format = prep_events .get_cgroup_events_format (
364347 cgroups , events , len (collection_events )
365348 )
@@ -370,7 +353,7 @@ def is_safe_file(fname, substr):
370353 args .timeout ,
371354 )
372355 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" )
374357 perf_format = prep_events .get_cgroup_events_format (
375358 cgroups , events , len (collection_events )
376359 )
@@ -402,13 +385,13 @@ def is_safe_file(fname, substr):
402385 validate_perfargs (perfargs )
403386 perf_helpers .pmu_contention_detect (msrs = initial_pmus , detect = True )
404387 if args .verbose :
405- log .info (cmd )
388+ logging .info (cmd )
406389 try :
407- log .info ("Collecting perf stat for events in : %s" % eventfilename )
390+ logging .info ("Collecting perf stat for events in : %s" % eventfilename )
408391 subprocess .call (perfargs ) # nosec
409- log .info ("Collection complete! Calculating TSC frequency now" )
392+ logging .info ("Collection complete! Calculating TSC frequency now" )
410393 except KeyboardInterrupt :
411- log .info ("Collection stopped! Caculating TSC frequency now" )
394+ logging .info ("Collection stopped! Caculating TSC frequency now" )
412395 except Exception :
413396 crash ("perf encountered errors" )
414397
@@ -425,13 +408,14 @@ def is_safe_file(fname, substr):
425408 False ,
426409 )
427410
411+ os .chmod (args .outcsv , 0o666 ) # nosec
412+
428413 # reset nmi_watchdog to what it was before running perfspect
429414 with open ("/proc/sys/kernel/nmi_watchdog" , "w" ) as f_nmi :
430415 if int (nmi_watchdog ) != 0 :
431416 f_nmi .write (nmi_watchdog )
432- log .info ("nmi_watchdog re-enabled" )
417+ logging .info ("nmi_watchdog re-enabled" )
433418
434419 perf_helpers .set_perf_event_mux_interval (True , 1 , mux_intervals )
435420
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