diff options
Diffstat (limited to 'tools/perf/scripts/python')
| -rw-r--r-- | tools/perf/scripts/python/Perf-Trace-Util/Build | 2 | ||||
| -rw-r--r-- | tools/perf/scripts/python/export-to-postgresql.py | 2 | ||||
| -rw-r--r-- | tools/perf/scripts/python/export-to-sqlite.py | 2 | ||||
| -rwxr-xr-x | tools/perf/scripts/python/exported-sql-viewer.py | 511 | ||||
| -rw-r--r-- | tools/perf/scripts/python/failed-syscalls-by-pid.py | 21 | ||||
| -rw-r--r-- | tools/perf/scripts/python/mem-phys-addr.py | 24 | ||||
| -rwxr-xr-x | tools/perf/scripts/python/net_dropmonitor.py | 10 | ||||
| -rw-r--r-- | tools/perf/scripts/python/netdev-times.py | 82 | ||||
| -rw-r--r-- | tools/perf/scripts/python/powerpc-hcalls.py | 18 | ||||
| -rw-r--r-- | tools/perf/scripts/python/sched-migration.py | 2 | ||||
| -rw-r--r-- | tools/perf/scripts/python/sctop.py | 24 | ||||
| -rwxr-xr-x | tools/perf/scripts/python/stackcollapse.py | 7 | ||||
| -rw-r--r-- | tools/perf/scripts/python/stat-cpi.py | 11 | ||||
| -rw-r--r-- | tools/perf/scripts/python/syscall-counts-by-pid.py | 22 | ||||
| -rw-r--r-- | tools/perf/scripts/python/syscall-counts.py | 18 | 
15 files changed, 485 insertions, 271 deletions
| diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Build b/tools/perf/scripts/python/Perf-Trace-Util/Build index aefc15c9444a..7d0e33ce6aba 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/Build +++ b/tools/perf/scripts/python/Perf-Trace-Util/Build @@ -1,3 +1,3 @@ -libperf-y += Context.o +perf-y += Context.o  CFLAGS_Context.o += $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs diff --git a/tools/perf/scripts/python/export-to-postgresql.py b/tools/perf/scripts/python/export-to-postgresql.py index 0564dd7377f2..30130213da7e 100644 --- a/tools/perf/scripts/python/export-to-postgresql.py +++ b/tools/perf/scripts/python/export-to-postgresql.py @@ -478,7 +478,7 @@ if perf_db_export_calls:  			'branch_count,'  			'call_id,'  			'return_id,' -			'CASE WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' ELSE \'\' END AS flags,' +			'CASE WHEN flags=0 THEN \'\' WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' WHEN flags=6 THEN \'jump\' ELSE flags END AS flags,'  			'parent_call_path_id'  		' FROM calls INNER JOIN call_paths ON call_paths.id = call_path_id') diff --git a/tools/perf/scripts/python/export-to-sqlite.py b/tools/perf/scripts/python/export-to-sqlite.py index 245caf2643ed..ed237f2ed03f 100644 --- a/tools/perf/scripts/python/export-to-sqlite.py +++ b/tools/perf/scripts/python/export-to-sqlite.py @@ -320,7 +320,7 @@ if perf_db_export_calls:  			'branch_count,'  			'call_id,'  			'return_id,' -			'CASE WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' ELSE \'\' END AS flags,' +			'CASE WHEN flags=0 THEN \'\' WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' WHEN flags=6 THEN \'jump\' ELSE flags END AS flags,'  			'parent_call_path_id'  		' FROM calls INNER JOIN call_paths ON call_paths.id = call_path_id') diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py index f278ce5ebab7..09ce73b07d35 100755 --- a/tools/perf/scripts/python/exported-sql-viewer.py +++ b/tools/perf/scripts/python/exported-sql-viewer.py @@ -1,4 +1,4 @@ -#!/usr/bin/python2 +#!/usr/bin/env python2  # SPDX-License-Identifier: GPL-2.0  # exported-sql-viewer.py: view data from sql database  # Copyright (c) 2014-2018, Intel Corporation. @@ -1398,18 +1398,28 @@ class BranchModel(TreeModel):  	def HasMoreRecords(self):  		return self.more +# Report Variables + +class ReportVars(): + +	def __init__(self, name = "", where_clause = "", limit = ""): +		self.name = name +		self.where_clause = where_clause +		self.limit = limit + +	def UniqueId(self): +		return str(self.where_clause + ";" + self.limit) +  # Branch window  class BranchWindow(QMdiSubWindow): -	def __init__(self, glb, event_id, name, where_clause, parent=None): +	def __init__(self, glb, event_id, report_vars, parent=None):  		super(BranchWindow, self).__init__(parent) -		model_name = "Branch Events " + str(event_id) -		if len(where_clause): -			model_name = where_clause + " " + model_name +		model_name = "Branch Events " + str(event_id) +  " " + report_vars.UniqueId() -		self.model = LookupCreateModel(model_name, lambda: BranchModel(glb, event_id, where_clause)) +		self.model = LookupCreateModel(model_name, lambda: BranchModel(glb, event_id, report_vars.where_clause))  		self.view = QTreeView()  		self.view.setUniformRowHeights(True) @@ -1427,7 +1437,7 @@ class BranchWindow(QMdiSubWindow):  		self.setWidget(self.vbox.Widget()) -		AddSubWindow(glb.mainwindow.mdi_area, self, name + " Branch Events") +		AddSubWindow(glb.mainwindow.mdi_area, self, report_vars.name + " Branch Events")  	def ResizeColumnToContents(self, column, n):  		# Using the view's resizeColumnToContents() here is extrememly slow @@ -1472,47 +1482,134 @@ class BranchWindow(QMdiSubWindow):  		else:  			self.find_bar.NotFound() -# Dialog data item converted and validated using a SQL table +# Line edit data item -class SQLTableDialogDataItem(): +class LineEditDataItem(object): -	def __init__(self, glb, label, placeholder_text, table_name, match_column, column_name1, column_name2, parent): +	def __init__(self, glb, label, placeholder_text, parent, id = "", default = ""):  		self.glb = glb  		self.label = label  		self.placeholder_text = placeholder_text -		self.table_name = table_name -		self.match_column = match_column -		self.column_name1 = column_name1 -		self.column_name2 = column_name2  		self.parent = parent +		self.id = id -		self.value = "" +		self.value = default -		self.widget = QLineEdit() +		self.widget = QLineEdit(default)  		self.widget.editingFinished.connect(self.Validate)  		self.widget.textChanged.connect(self.Invalidate)  		self.red = False  		self.error = ""  		self.validated = True -		self.last_id = 0 -		self.first_time = 0 -		self.last_time = 2 ** 64 -		if self.table_name == "<timeranges>": -			query = QSqlQuery(self.glb.db) -			QueryExec(query, "SELECT id, time FROM samples ORDER BY id DESC LIMIT 1") -			if query.next(): -				self.last_id = int(query.value(0)) -				self.last_time = int(query.value(1)) -			QueryExec(query, "SELECT time FROM samples WHERE time != 0 ORDER BY id LIMIT 1") -			if query.next(): -				self.first_time = int(query.value(0)) -			if placeholder_text: -				placeholder_text += ", between " + str(self.first_time) + " and " + str(self.last_time) -  		if placeholder_text:  			self.widget.setPlaceholderText(placeholder_text) +	def TurnTextRed(self): +		if not self.red: +			palette = QPalette() +			palette.setColor(QPalette.Text,Qt.red) +			self.widget.setPalette(palette) +			self.red = True + +	def TurnTextNormal(self): +		if self.red: +			palette = QPalette() +			self.widget.setPalette(palette) +			self.red = False + +	def InvalidValue(self, value): +		self.value = "" +		self.TurnTextRed() +		self.error = self.label + " invalid value '" + value + "'" +		self.parent.ShowMessage(self.error) + +	def Invalidate(self): +		self.validated = False + +	def DoValidate(self, input_string): +		self.value = input_string.strip() + +	def Validate(self): +		self.validated = True +		self.error = "" +		self.TurnTextNormal() +		self.parent.ClearMessage() +		input_string = self.widget.text() +		if not len(input_string.strip()): +			self.value = "" +			return +		self.DoValidate(input_string) + +	def IsValid(self): +		if not self.validated: +			self.Validate() +		if len(self.error): +			self.parent.ShowMessage(self.error) +			return False +		return True + +	def IsNumber(self, value): +		try: +			x = int(value) +		except: +			x = 0 +		return str(x) == value + +# Non-negative integer ranges dialog data item + +class NonNegativeIntegerRangesDataItem(LineEditDataItem): + +	def __init__(self, glb, label, placeholder_text, column_name, parent): +		super(NonNegativeIntegerRangesDataItem, self).__init__(glb, label, placeholder_text, parent) + +		self.column_name = column_name + +	def DoValidate(self, input_string): +		singles = [] +		ranges = [] +		for value in [x.strip() for x in input_string.split(",")]: +			if "-" in value: +				vrange = value.split("-") +				if len(vrange) != 2 or not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]): +					return self.InvalidValue(value) +				ranges.append(vrange) +			else: +				if not self.IsNumber(value): +					return self.InvalidValue(value) +				singles.append(value) +		ranges = [("(" + self.column_name + " >= " + r[0] + " AND " + self.column_name + " <= " + r[1] + ")") for r in ranges] +		if len(singles): +			ranges.append(self.column_name + " IN (" + ",".join(singles) + ")") +		self.value = " OR ".join(ranges) + +# Positive integer dialog data item + +class PositiveIntegerDataItem(LineEditDataItem): + +	def __init__(self, glb, label, placeholder_text, parent, id = "", default = ""): +		super(PositiveIntegerDataItem, self).__init__(glb, label, placeholder_text, parent, id, default) + +	def DoValidate(self, input_string): +		if not self.IsNumber(input_string.strip()): +			return self.InvalidValue(input_string) +		value = int(input_string.strip()) +		if value <= 0: +			return self.InvalidValue(input_string) +		self.value = str(value) + +# Dialog data item converted and validated using a SQL table + +class SQLTableDataItem(LineEditDataItem): + +	def __init__(self, glb, label, placeholder_text, table_name, match_column, column_name1, column_name2, parent): +		super(SQLTableDataItem, self).__init__(glb, label, placeholder_text, parent) + +		self.table_name = table_name +		self.match_column = match_column +		self.column_name1 = column_name1 +		self.column_name2 = column_name2 +  	def ValueToIds(self, value):  		ids = []  		query = QSqlQuery(self.glb.db) @@ -1523,6 +1620,42 @@ class SQLTableDialogDataItem():  				ids.append(str(query.value(0)))  		return ids +	def DoValidate(self, input_string): +		all_ids = [] +		for value in [x.strip() for x in input_string.split(",")]: +			ids = self.ValueToIds(value) +			if len(ids): +				all_ids.extend(ids) +			else: +				return self.InvalidValue(value) +		self.value = self.column_name1 + " IN (" + ",".join(all_ids) + ")" +		if self.column_name2: +			self.value = "( " + self.value + " OR " + self.column_name2 + " IN (" + ",".join(all_ids) + ") )" + +# Sample time ranges dialog data item converted and validated using 'samples' SQL table + +class SampleTimeRangesDataItem(LineEditDataItem): + +	def __init__(self, glb, label, placeholder_text, column_name, parent): +		self.column_name = column_name + +		self.last_id = 0 +		self.first_time = 0 +		self.last_time = 2 ** 64 + +		query = QSqlQuery(glb.db) +		QueryExec(query, "SELECT id, time FROM samples ORDER BY id DESC LIMIT 1") +		if query.next(): +			self.last_id = int(query.value(0)) +			self.last_time = int(query.value(1)) +		QueryExec(query, "SELECT time FROM samples WHERE time != 0 ORDER BY id LIMIT 1") +		if query.next(): +			self.first_time = int(query.value(0)) +		if placeholder_text: +			placeholder_text += ", between " + str(self.first_time) + " and " + str(self.last_time) + +		super(SampleTimeRangesDataItem, self).__init__(glb, label, placeholder_text, parent) +  	def IdBetween(self, query, lower_id, higher_id, order):  		QueryExec(query, "SELECT id FROM samples WHERE id > " + str(lower_id) + " AND id < " + str(higher_id) + " ORDER BY id " + order + " LIMIT 1")  		if query.next(): @@ -1560,7 +1693,6 @@ class SQLTableDialogDataItem():  					return str(lower_id)  	def ConvertRelativeTime(self, val): -		print "val ", val  		mult = 1  		suffix = val[-2:]  		if suffix == "ms": @@ -1582,29 +1714,23 @@ class SQLTableDialogDataItem():  		return str(val)  	def ConvertTimeRange(self, vrange): -		print "vrange ", vrange  		if vrange[0] == "":  			vrange[0] = str(self.first_time)  		if vrange[1] == "":  			vrange[1] = str(self.last_time)  		vrange[0] = self.ConvertRelativeTime(vrange[0])  		vrange[1] = self.ConvertRelativeTime(vrange[1]) -		print "vrange2 ", vrange  		if not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]):  			return False -		print "ok1"  		beg_range = max(int(vrange[0]), self.first_time)  		end_range = min(int(vrange[1]), self.last_time)  		if beg_range > self.last_time or end_range < self.first_time:  			return False -		print "ok2"  		vrange[0] = self.BinarySearchTime(0, self.last_id, beg_range, True)  		vrange[1] = self.BinarySearchTime(1, self.last_id + 1, end_range, False) -		print "vrange3 ", vrange  		return True  	def AddTimeRange(self, value, ranges): -		print "value ", value  		n = value.count("-")  		if n == 1:  			pass @@ -1622,111 +1748,31 @@ class SQLTableDialogDataItem():  			return True  		return False -	def InvalidValue(self, value): -		self.value = "" -		palette = QPalette() -		palette.setColor(QPalette.Text,Qt.red) -		self.widget.setPalette(palette) -		self.red = True -		self.error = self.label + " invalid value '" + value + "'" -		self.parent.ShowMessage(self.error) +	def DoValidate(self, input_string): +		ranges = [] +		for value in [x.strip() for x in input_string.split(",")]: +			if not self.AddTimeRange(value, ranges): +				return self.InvalidValue(value) +		ranges = [("(" + self.column_name + " >= " + r[0] + " AND " + self.column_name + " <= " + r[1] + ")") for r in ranges] +		self.value = " OR ".join(ranges) -	def IsNumber(self, value): -		try: -			x = int(value) -		except: -			x = 0 -		return str(x) == value +# Report Dialog Base -	def Invalidate(self): -		self.validated = False +class ReportDialogBase(QDialog): -	def Validate(self): -		input_string = self.widget.text() -		self.validated = True -		if self.red: -			palette = QPalette() -			self.widget.setPalette(palette) -			self.red = False -		if not len(input_string.strip()): -			self.error = "" -			self.value = "" -			return -		if self.table_name == "<timeranges>": -			ranges = [] -			for value in [x.strip() for x in input_string.split(",")]: -				if not self.AddTimeRange(value, ranges): -					return self.InvalidValue(value) -			ranges = [("(" + self.column_name1 + " >= " + r[0] + " AND " + self.column_name1 + " <= " + r[1] + ")") for r in ranges] -			self.value = " OR ".join(ranges) -		elif self.table_name == "<ranges>": -			singles = [] -			ranges = [] -			for value in [x.strip() for x in input_string.split(",")]: -				if "-" in value: -					vrange = value.split("-") -					if len(vrange) != 2 or not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]): -						return self.InvalidValue(value) -					ranges.append(vrange) -				else: -					if not self.IsNumber(value): -						return self.InvalidValue(value) -					singles.append(value) -			ranges = [("(" + self.column_name1 + " >= " + r[0] + " AND " + self.column_name1 + " <= " + r[1] + ")") for r in ranges] -			if len(singles): -				ranges.append(self.column_name1 + " IN (" + ",".join(singles) + ")") -			self.value = " OR ".join(ranges) -		elif self.table_name: -			all_ids = [] -			for value in [x.strip() for x in input_string.split(",")]: -				ids = self.ValueToIds(value) -				if len(ids): -					all_ids.extend(ids) -				else: -					return self.InvalidValue(value) -			self.value = self.column_name1 + " IN (" + ",".join(all_ids) + ")" -			if self.column_name2: -				self.value = "( " + self.value + " OR " + self.column_name2 + " IN (" + ",".join(all_ids) + ") )" -		else: -			self.value = input_string.strip() -		self.error = "" -		self.parent.ClearMessage() - -	def IsValid(self): -		if not self.validated: -			self.Validate() -		if len(self.error): -			self.parent.ShowMessage(self.error) -			return False -		return True - -# Selected branch report creation dialog - -class SelectedBranchDialog(QDialog): - -	def __init__(self, glb, parent=None): -		super(SelectedBranchDialog, self).__init__(parent) +	def __init__(self, glb, title, items, partial, parent=None): +		super(ReportDialogBase, self).__init__(parent)  		self.glb = glb -		self.name = "" -		self.where_clause = "" +		self.report_vars = ReportVars() -		self.setWindowTitle("Selected Branches") +		self.setWindowTitle(title)  		self.setMinimumWidth(600) -		items = ( -			("Report name:", "Enter a name to appear in the window title bar", "", "", "", ""), -			("Time ranges:", "Enter time ranges", "<timeranges>", "", "samples.id", ""), -			("CPUs:", "Enter CPUs or ranges e.g. 0,5-6", "<ranges>", "", "cpu", ""), -			("Commands:", "Only branches with these commands will be included", "comms", "comm", "comm_id", ""), -			("PIDs:", "Only branches with these process IDs will be included", "threads", "pid", "thread_id", ""), -			("TIDs:", "Only branches with these thread IDs will be included", "threads", "tid", "thread_id", ""), -			("DSOs:", "Only branches with these DSOs will be included", "dsos", "short_name", "samples.dso_id", "to_dso_id"), -			("Symbols:", "Only branches with these symbols will be included", "symbols", "name", "symbol_id", "to_symbol_id"), -			("Raw SQL clause: ", "Enter a raw SQL WHERE clause", "", "", "", ""), -			) -		self.data_items = [SQLTableDialogDataItem(glb, *x, parent=self) for x in items] +		self.data_items = [x(glb, self) for x in items] + +		self.partial = partial  		self.grid = QGridLayout() @@ -1758,23 +1804,28 @@ class SelectedBranchDialog(QDialog):  		self.setLayout(self.vbox);  	def Ok(self): -		self.name = self.data_items[0].value -		if not self.name: +		vars = self.report_vars +		for d in self.data_items: +			if d.id == "REPORTNAME": +				vars.name = d.value +		if not vars.name:  			self.ShowMessage("Report name is required")  			return  		for d in self.data_items:  			if not d.IsValid():  				return  		for d in self.data_items[1:]: -			if len(d.value): -				if len(self.where_clause): -					self.where_clause += " AND " -				self.where_clause += d.value -		if len(self.where_clause): -			self.where_clause = " AND ( " + self.where_clause + " ) " -		else: -			self.ShowMessage("No selection") -			return +			if d.id == "LIMIT": +				vars.limit = d.value +			elif len(d.value): +				if len(vars.where_clause): +					vars.where_clause += " AND " +				vars.where_clause += d.value +		if len(vars.where_clause): +			if self.partial: +				vars.where_clause = " AND ( " + vars.where_clause + " ) " +			else: +				vars.where_clause = " WHERE " + vars.where_clause + " "  		self.accept()  	def ShowMessage(self, msg): @@ -1783,6 +1834,23 @@ class SelectedBranchDialog(QDialog):  	def ClearMessage(self):  		self.status.setText("") +# Selected branch report creation dialog + +class SelectedBranchDialog(ReportDialogBase): + +	def __init__(self, glb, parent=None): +		title = "Selected Branches" +		items = (lambda g, p: LineEditDataItem(g, "Report name:", "Enter a name to appear in the window title bar", p, "REPORTNAME"), +			 lambda g, p: SampleTimeRangesDataItem(g, "Time ranges:", "Enter time ranges", "samples.id", p), +			 lambda g, p: NonNegativeIntegerRangesDataItem(g, "CPUs:", "Enter CPUs or ranges e.g. 0,5-6", "cpu", p), +			 lambda g, p: SQLTableDataItem(g, "Commands:", "Only branches with these commands will be included", "comms", "comm", "comm_id", "", p), +			 lambda g, p: SQLTableDataItem(g, "PIDs:", "Only branches with these process IDs will be included", "threads", "pid", "thread_id", "", p), +			 lambda g, p: SQLTableDataItem(g, "TIDs:", "Only branches with these thread IDs will be included", "threads", "tid", "thread_id", "", p), +			 lambda g, p: SQLTableDataItem(g, "DSOs:", "Only branches with these DSOs will be included", "dsos", "short_name", "samples.dso_id", "to_dso_id", p), +			 lambda g, p: SQLTableDataItem(g, "Symbols:", "Only branches with these symbols will be included", "symbols", "name", "symbol_id", "to_symbol_id", p), +			 lambda g, p: LineEditDataItem(g, "Raw SQL clause: ", "Enter a raw SQL WHERE clause", p)) +		super(SelectedBranchDialog, self).__init__(glb, title, items, True, parent) +  # Event list  def GetEventList(db): @@ -1793,6 +1861,16 @@ def GetEventList(db):  		events.append(query.value(0))  	return events +# Is a table selectable + +def IsSelectable(db, table): +	query = QSqlQuery(db) +	try: +		QueryExec(query, "SELECT * FROM " + table + " LIMIT 1") +	except: +		return False +	return True +  # SQL data preparation  def SQLTableDataPrep(query, count): @@ -1818,12 +1896,13 @@ class SQLTableModel(TableModel):  	progress = Signal(object) -	def __init__(self, glb, sql, column_count, parent=None): +	def __init__(self, glb, sql, column_headers, parent=None):  		super(SQLTableModel, self).__init__(parent)  		self.glb = glb  		self.more = True  		self.populated = 0 -		self.fetcher = SQLFetcher(glb, sql, lambda x, y=column_count: SQLTableDataPrep(x, y), self.AddSample) +		self.column_headers = column_headers +		self.fetcher = SQLFetcher(glb, sql, lambda x, y=len(column_headers): SQLTableDataPrep(x, y), self.AddSample)  		self.fetcher.done.connect(self.Update)  		self.fetcher.Fetch(glb_chunk_sz) @@ -1861,6 +1940,12 @@ class SQLTableModel(TableModel):  	def HasMoreRecords(self):  		return self.more +	def columnCount(self, parent=None): +		return len(self.column_headers) + +	def columnHeader(self, column): +		return self.column_headers[column] +  # SQL automatic table data model  class SQLAutoTableModel(SQLTableModel): @@ -1870,12 +1955,12 @@ class SQLAutoTableModel(SQLTableModel):  		if table_name == "comm_threads_view":  			# For now, comm_threads_view has no id column  			sql = "SELECT * FROM " + table_name + " WHERE comm_id > $$last_id$$ ORDER BY comm_id LIMIT " + str(glb_chunk_sz) -		self.column_headers = [] +		column_headers = []  		query = QSqlQuery(glb.db)  		if glb.dbref.is_sqlite3:  			QueryExec(query, "PRAGMA table_info(" + table_name + ")")  			while query.next(): -				self.column_headers.append(query.value(1)) +				column_headers.append(query.value(1))  			if table_name == "sqlite_master":  				sql = "SELECT * FROM " + table_name  		else: @@ -1888,14 +1973,8 @@ class SQLAutoTableModel(SQLTableModel):  				schema = "public"  			QueryExec(query, "SELECT column_name FROM information_schema.columns WHERE table_schema = '" + schema + "' and table_name = '" + select_table_name + "'")  			while query.next(): -				self.column_headers.append(query.value(0)) -		super(SQLAutoTableModel, self).__init__(glb, sql, len(self.column_headers), parent) - -	def columnCount(self, parent=None): -		return len(self.column_headers) - -	def columnHeader(self, column): -		return self.column_headers[column] +				column_headers.append(query.value(0)) +		super(SQLAutoTableModel, self).__init__(glb, sql, column_headers, parent)  # Base class for custom ResizeColumnsToContents @@ -1998,6 +2077,103 @@ def GetTableList(glb):  		tables.append("information_schema.columns")  	return tables +# Top Calls data model + +class TopCallsModel(SQLTableModel): + +	def __init__(self, glb, report_vars, parent=None): +		text = "" +		if not glb.dbref.is_sqlite3: +			text = "::text" +		limit = "" +		if len(report_vars.limit): +			limit = " LIMIT " + report_vars.limit +		sql = ("SELECT comm, pid, tid, name," +			" CASE" +			" WHEN (short_name = '[kernel.kallsyms]') THEN '[kernel]'" + text + +			" ELSE short_name" +			" END AS dso," +			" call_time, return_time, (return_time - call_time) AS elapsed_time, branch_count, " +			" CASE" +			" WHEN (calls.flags = 1) THEN 'no call'" + text + +			" WHEN (calls.flags = 2) THEN 'no return'" + text + +			" WHEN (calls.flags = 3) THEN 'no call/return'" + text + +			" ELSE ''" + text + +			" END AS flags" +			" FROM calls" +			" INNER JOIN call_paths ON calls.call_path_id = call_paths.id" +			" INNER JOIN symbols ON call_paths.symbol_id = symbols.id" +			" INNER JOIN dsos ON symbols.dso_id = dsos.id" +			" INNER JOIN comms ON calls.comm_id = comms.id" +			" INNER JOIN threads ON calls.thread_id = threads.id" + +			report_vars.where_clause + +			" ORDER BY elapsed_time DESC" + +			limit +			) +		column_headers = ("Command", "PID", "TID", "Symbol", "Object", "Call Time", "Return Time", "Elapsed Time (ns)", "Branch Count", "Flags") +		self.alignment = (Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignRight, Qt.AlignRight, Qt.AlignLeft) +		super(TopCallsModel, self).__init__(glb, sql, column_headers, parent) + +	def columnAlignment(self, column): +		return self.alignment[column] + +# Top Calls report creation dialog + +class TopCallsDialog(ReportDialogBase): + +	def __init__(self, glb, parent=None): +		title = "Top Calls by Elapsed Time" +		items = (lambda g, p: LineEditDataItem(g, "Report name:", "Enter a name to appear in the window title bar", p, "REPORTNAME"), +			 lambda g, p: SQLTableDataItem(g, "Commands:", "Only calls with these commands will be included", "comms", "comm", "comm_id", "", p), +			 lambda g, p: SQLTableDataItem(g, "PIDs:", "Only calls with these process IDs will be included", "threads", "pid", "thread_id", "", p), +			 lambda g, p: SQLTableDataItem(g, "TIDs:", "Only calls with these thread IDs will be included", "threads", "tid", "thread_id", "", p), +			 lambda g, p: SQLTableDataItem(g, "DSOs:", "Only calls with these DSOs will be included", "dsos", "short_name", "dso_id", "", p), +			 lambda g, p: SQLTableDataItem(g, "Symbols:", "Only calls with these symbols will be included", "symbols", "name", "symbol_id", "", p), +			 lambda g, p: LineEditDataItem(g, "Raw SQL clause: ", "Enter a raw SQL WHERE clause", p), +			 lambda g, p: PositiveIntegerDataItem(g, "Record limit:", "Limit selection to this number of records", p, "LIMIT", "100")) +		super(TopCallsDialog, self).__init__(glb, title, items, False, parent) + +# Top Calls window + +class TopCallsWindow(QMdiSubWindow, ResizeColumnsToContentsBase): + +	def __init__(self, glb, report_vars, parent=None): +		super(TopCallsWindow, self).__init__(parent) + +		self.data_model = LookupCreateModel("Top Calls " + report_vars.UniqueId(), lambda: TopCallsModel(glb, report_vars)) +		self.model = self.data_model + +		self.view = QTableView() +		self.view.setModel(self.model) +		self.view.setEditTriggers(QAbstractItemView.NoEditTriggers) +		self.view.verticalHeader().setVisible(False) + +		self.ResizeColumnsToContents() + +		self.find_bar = FindBar(self, self, True) + +		self.finder = ChildDataItemFinder(self.model) + +		self.fetch_bar = FetchMoreRecordsBar(self.data_model, self) + +		self.vbox = VBox(self.view, self.find_bar.Widget(), self.fetch_bar.Widget()) + +		self.setWidget(self.vbox.Widget()) + +		AddSubWindow(glb.mainwindow.mdi_area, self, report_vars.name) + +	def Find(self, value, direction, pattern, context): +		self.view.setFocus() +		self.find_bar.Busy() +		self.finder.Find(value, direction, pattern, context, self.FindDone) + +	def FindDone(self, row): +		self.find_bar.Idle() +		if row >= 0: +			self.view.setCurrentIndex(self.model.index(row, 0, QModelIndex())) +		else: +			self.find_bar.NotFound() +  # Action Definition  def CreateAction(label, tip, callback, parent=None, shortcut=None): @@ -2101,6 +2277,7 @@ p.c2 {  <p class=c2><a href=#callgraph>1.1 Context-Sensitive Call Graph</a></p>  <p class=c2><a href=#allbranches>1.2 All branches</a></p>  <p class=c2><a href=#selectedbranches>1.3 Selected branches</a></p> +<p class=c2><a href=#topcallsbyelapsedtime>1.4 Top calls by elapsed time</a></p>  <p class=c1><a href=#tables>2. Tables</a></p>  <h1 id=reports>1. Reports</h1>  <h2 id=callgraph>1.1 Context-Sensitive Call Graph</h2> @@ -2176,6 +2353,10 @@ ms, us or ns. Also, negative values are relative to the end of trace.  Examples:  	-10ms-			The last 10ms  </pre>  N.B. Due to the granularity of timestamps, there could be no branches in any given time range. +<h2 id=topcallsbyelapsedtime>1.4 Top calls by elapsed time</h2> +The Top calls by elapsed time report displays calls in descending order of time elapsed between when the function was called and when it returned. +The data is reduced by various selection criteria. A dialog box displays available criteria which are AND'ed together. +If not all data is fetched, a Fetch bar is provided. Ctrl-F displays a Find bar.  <h1 id=tables>2. Tables</h1>  The Tables menu shows all tables and views in the database. Most tables have an associated view  which displays the information in a more friendly way. Not all data for large tables is fetched @@ -2305,10 +2486,14 @@ class MainWindow(QMainWindow):  		edit_menu.addAction(CreateAction("&Enlarge Font", "Make text bigger", self.EnlargeFont, self, [QKeySequence("Ctrl++")]))  		reports_menu = menu.addMenu("&Reports") -		reports_menu.addAction(CreateAction("Context-Sensitive Call &Graph", "Create a new window containing a context-sensitive call graph", self.NewCallGraph, self)) +		if IsSelectable(glb.db, "calls"): +			reports_menu.addAction(CreateAction("Context-Sensitive Call &Graph", "Create a new window containing a context-sensitive call graph", self.NewCallGraph, self))  		self.EventMenu(GetEventList(glb.db), reports_menu) +		if IsSelectable(glb.db, "calls"): +			reports_menu.addAction(CreateAction("&Top calls by elapsed time", "Create a new window displaying top calls by elapsed time", self.NewTopCalls, self)) +  		self.TableMenu(GetTableList(glb), menu)  		self.window_menu = WindowMenu(self.mdi_area, menu) @@ -2364,14 +2549,20 @@ class MainWindow(QMainWindow):  	def NewCallGraph(self):  		CallGraphWindow(self.glb, self) +	def NewTopCalls(self): +		dialog = TopCallsDialog(self.glb, self) +		ret = dialog.exec_() +		if ret: +			TopCallsWindow(self.glb, dialog.report_vars, self) +  	def NewBranchView(self, event_id): -		BranchWindow(self.glb, event_id, "", "", self) +		BranchWindow(self.glb, event_id, ReportVars(), self)  	def NewSelectedBranchView(self, event_id):  		dialog = SelectedBranchDialog(self.glb, self)  		ret = dialog.exec_()  		if ret: -			BranchWindow(self.glb, event_id, dialog.name, dialog.where_clause, self) +			BranchWindow(self.glb, event_id, dialog.report_vars, self)  	def NewTableView(self, table_name):  		TableWindow(self.glb, table_name, self) diff --git a/tools/perf/scripts/python/failed-syscalls-by-pid.py b/tools/perf/scripts/python/failed-syscalls-by-pid.py index cafeff3d74db..3648e8b986ec 100644 --- a/tools/perf/scripts/python/failed-syscalls-by-pid.py +++ b/tools/perf/scripts/python/failed-syscalls-by-pid.py @@ -5,6 +5,8 @@  # Displays system-wide failed system call totals, broken down by pid.  # If a [comm] arg is specified, only syscalls called by [comm] are displayed. +from __future__ import print_function +  import os  import sys @@ -32,7 +34,7 @@ if len(sys.argv) > 1:  syscalls = autodict()  def trace_begin(): -	print "Press control+C to stop and show the summary" +	print("Press control+C to stop and show the summary")  def trace_end():  	print_error_totals() @@ -57,22 +59,21 @@ def syscalls__sys_exit(event_name, context, common_cpu,  def print_error_totals():      if for_comm is not None: -	    print "\nsyscall errors for %s:\n\n" % (for_comm), +	    print("\nsyscall errors for %s:\n" % (for_comm))      else: -	    print "\nsyscall errors:\n\n", +	    print("\nsyscall errors:\n") -    print "%-30s  %10s\n" % ("comm [pid]", "count"), -    print "%-30s  %10s\n" % ("------------------------------", \ -                                 "----------"), +    print("%-30s  %10s" % ("comm [pid]", "count")) +    print("%-30s  %10s" % ("------------------------------", "----------"))      comm_keys = syscalls.keys()      for comm in comm_keys:  	    pid_keys = syscalls[comm].keys()  	    for pid in pid_keys: -		    print "\n%s [%d]\n" % (comm, pid), +		    print("\n%s [%d]" % (comm, pid))  		    id_keys = syscalls[comm][pid].keys()  		    for id in id_keys: -			    print "  syscall: %-16s\n" % syscall_name(id), +			    print("  syscall: %-16s" % syscall_name(id))  			    ret_keys = syscalls[comm][pid][id].keys() -			    for ret, val in sorted(syscalls[comm][pid][id].iteritems(), key = lambda(k, v): (v, k),  reverse = True): -				    print "    err = %-20s  %10d\n" % (strerror(ret), val), +			    for ret, val in sorted(syscalls[comm][pid][id].items(), key = lambda kv: (kv[1], kv[0]),  reverse = True): +				    print("    err = %-20s  %10d" % (strerror(ret), val)) diff --git a/tools/perf/scripts/python/mem-phys-addr.py b/tools/perf/scripts/python/mem-phys-addr.py index ebee2c5ae496..fb0bbcbfa0f0 100644 --- a/tools/perf/scripts/python/mem-phys-addr.py +++ b/tools/perf/scripts/python/mem-phys-addr.py @@ -4,6 +4,8 @@  # Copyright (c) 2018, Intel Corporation.  from __future__ import division +from __future__ import print_function +  import os  import sys  import struct @@ -31,21 +33,23 @@ def parse_iomem():  	for i, j in enumerate(f):  		m = re.split('-|:',j,2)  		if m[2].strip() == 'System RAM': -			system_ram.append(long(m[0], 16)) -			system_ram.append(long(m[1], 16)) +			system_ram.append(int(m[0], 16)) +			system_ram.append(int(m[1], 16))  		if m[2].strip() == 'Persistent Memory': -			pmem.append(long(m[0], 16)) -			pmem.append(long(m[1], 16)) +			pmem.append(int(m[0], 16)) +			pmem.append(int(m[1], 16))  def print_memory_type(): -	print "Event: %s" % (event_name) -	print "%-40s  %10s  %10s\n" % ("Memory type", "count", "percentage"), -	print "%-40s  %10s  %10s\n" % ("----------------------------------------", \ +	print("Event: %s" % (event_name)) +	print("%-40s  %10s  %10s\n" % ("Memory type", "count", "percentage"), end='') +	print("%-40s  %10s  %10s\n" % ("----------------------------------------",  					"-----------", "-----------"), +                                        end='');  	total = sum(load_mem_type_cnt.values())  	for mem_type, count in sorted(load_mem_type_cnt.most_common(), \ -					key = lambda(k, v): (v, k), reverse = True): -		print "%-40s  %10d  %10.1f%%\n" % (mem_type, count, 100 * count / total), +					key = lambda kv: (kv[1], kv[0]), reverse = True): +		print("%-40s  %10d  %10.1f%%\n" % (mem_type, count, 100 * count / total), +                        end='')  def trace_begin():  	parse_iomem() @@ -80,7 +84,7 @@ def find_memory_type(phys_addr):  	f.seek(0, 0)  	for j in f:  		m = re.split('-|:',j,2) -		if long(m[0], 16) <= phys_addr <= long(m[1], 16): +		if int(m[0], 16) <= phys_addr <= int(m[1], 16):  			return m[2]  	return "N/A" diff --git a/tools/perf/scripts/python/net_dropmonitor.py b/tools/perf/scripts/python/net_dropmonitor.py index a150164b44a3..212557a02c50 100755 --- a/tools/perf/scripts/python/net_dropmonitor.py +++ b/tools/perf/scripts/python/net_dropmonitor.py @@ -1,6 +1,8 @@  # Monitor the system for dropped packets and proudce a report of drop locations and counts  # SPDX-License-Identifier: GPL-2.0 +from __future__ import print_function +  import os  import sys @@ -50,19 +52,19 @@ def get_sym(sloc):  		return (None, 0)  def print_drop_table(): -	print "%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT") +	print("%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT"))  	for i in drop_log.keys():  		(sym, off) = get_sym(i)  		if sym == None:  			sym = i -		print "%25s %25s %25s" % (sym, off, drop_log[i]) +		print("%25s %25s %25s" % (sym, off, drop_log[i]))  def trace_begin(): -	print "Starting trace (Ctrl-C to dump results)" +	print("Starting trace (Ctrl-C to dump results)")  def trace_end(): -	print "Gathering kallsyms data" +	print("Gathering kallsyms data")  	get_kallsyms_table()  	print_drop_table() diff --git a/tools/perf/scripts/python/netdev-times.py b/tools/perf/scripts/python/netdev-times.py index 9b2050f778f1..267bda49325d 100644 --- a/tools/perf/scripts/python/netdev-times.py +++ b/tools/perf/scripts/python/netdev-times.py @@ -8,6 +8,8 @@  # dev=: show only thing related to specified device  # debug: work with debug mode. It shows buffer status. +from __future__ import print_function +  import os  import sys @@ -17,6 +19,7 @@ sys.path.append(os.environ['PERF_EXEC_PATH'] + \  from perf_trace_context import *  from Core import *  from Util import * +from functools import cmp_to_key  all_event_list = []; # insert all tracepoint event related with this script  irq_dic = {}; # key is cpu and value is a list which stacks irqs @@ -61,12 +64,12 @@ def diff_msec(src, dst):  def print_transmit(hunk):  	if dev != 0 and hunk['dev'].find(dev) < 0:  		return -	print "%7s %5d %6d.%06dsec %12.3fmsec      %12.3fmsec" % \ +	print("%7s %5d %6d.%06dsec %12.3fmsec      %12.3fmsec" %  		(hunk['dev'], hunk['len'],  		nsecs_secs(hunk['queue_t']),  		nsecs_nsecs(hunk['queue_t'])/1000,  		diff_msec(hunk['queue_t'], hunk['xmit_t']), -		diff_msec(hunk['xmit_t'], hunk['free_t'])) +		diff_msec(hunk['xmit_t'], hunk['free_t'])))  # Format for displaying rx packet processing  PF_IRQ_ENTRY= "  irq_entry(+%.3fmsec irq=%d:%s)" @@ -98,55 +101,55 @@ def print_receive(hunk):  	if show_hunk == 0:  		return -	print "%d.%06dsec cpu=%d" % \ -		(nsecs_secs(base_t), nsecs_nsecs(base_t)/1000, cpu) +	print("%d.%06dsec cpu=%d" % +		(nsecs_secs(base_t), nsecs_nsecs(base_t)/1000, cpu))  	for i in range(len(irq_list)): -		print PF_IRQ_ENTRY % \ +		print(PF_IRQ_ENTRY %  			(diff_msec(base_t, irq_list[i]['irq_ent_t']), -			irq_list[i]['irq'], irq_list[i]['name']) -		print PF_JOINT +			irq_list[i]['irq'], irq_list[i]['name'])) +		print(PF_JOINT)  		irq_event_list = irq_list[i]['event_list']  		for j in range(len(irq_event_list)):  			irq_event = irq_event_list[j]  			if irq_event['event'] == 'netif_rx': -				print PF_NET_RX % \ +				print(PF_NET_RX %  					(diff_msec(base_t, irq_event['time']), -					irq_event['skbaddr']) -				print PF_JOINT -	print PF_SOFT_ENTRY % \ -		diff_msec(base_t, hunk['sirq_ent_t']) -	print PF_JOINT +					irq_event['skbaddr'])) +				print(PF_JOINT) +	print(PF_SOFT_ENTRY % +		diff_msec(base_t, hunk['sirq_ent_t'])) +	print(PF_JOINT)  	event_list = hunk['event_list']  	for i in range(len(event_list)):  		event = event_list[i]  		if event['event_name'] == 'napi_poll': -			print PF_NAPI_POLL % \ -			    (diff_msec(base_t, event['event_t']), event['dev']) +			print(PF_NAPI_POLL % +			    (diff_msec(base_t, event['event_t']), event['dev']))  			if i == len(event_list) - 1: -				print "" +				print("")  			else: -				print PF_JOINT +				print(PF_JOINT)  		else: -			print PF_NET_RECV % \ +			print(PF_NET_RECV %  			    (diff_msec(base_t, event['event_t']), event['skbaddr'], -				event['len']) +				event['len']))  			if 'comm' in event.keys(): -				print PF_WJOINT -				print PF_CPY_DGRAM % \ +				print(PF_WJOINT) +				print(PF_CPY_DGRAM %  					(diff_msec(base_t, event['comm_t']), -					event['pid'], event['comm']) +					event['pid'], event['comm']))  			elif 'handle' in event.keys(): -				print PF_WJOINT +				print(PF_WJOINT)  				if event['handle'] == "kfree_skb": -					print PF_KFREE_SKB % \ +					print(PF_KFREE_SKB %  						(diff_msec(base_t,  						event['comm_t']), -						event['location']) +						event['location']))  				elif event['handle'] == "consume_skb": -					print PF_CONS_SKB % \ +					print(PF_CONS_SKB %  						diff_msec(base_t, -							event['comm_t']) -			print PF_JOINT +							event['comm_t'])) +			print(PF_JOINT)  def trace_begin():  	global show_tx @@ -172,8 +175,7 @@ def trace_begin():  def trace_end():  	# order all events in time -	all_event_list.sort(lambda a,b :cmp(a[EINFO_IDX_TIME], -					    b[EINFO_IDX_TIME])) +	all_event_list.sort(key=cmp_to_key(lambda a,b :a[EINFO_IDX_TIME] < b[EINFO_IDX_TIME]))  	# process all events  	for i in range(len(all_event_list)):  		event_info = all_event_list[i] @@ -210,19 +212,19 @@ def trace_end():  			print_receive(receive_hunk_list[i])  	# display transmit hunks  	if show_tx: -		print "   dev    len      Qdisc        " \ -			"       netdevice             free" +		print("   dev    len      Qdisc        " +			"       netdevice             free")  		for i in range(len(tx_free_list)):  			print_transmit(tx_free_list[i])  	if debug: -		print "debug buffer status" -		print "----------------------------" -		print "xmit Qdisc:remain:%d overflow:%d" % \ -			(len(tx_queue_list), of_count_tx_queue_list) -		print "xmit netdevice:remain:%d overflow:%d" % \ -			(len(tx_xmit_list), of_count_tx_xmit_list) -		print "receive:remain:%d overflow:%d" % \ -			(len(rx_skb_list), of_count_rx_skb_list) +		print("debug buffer status") +		print("----------------------------") +		print("xmit Qdisc:remain:%d overflow:%d" % +			(len(tx_queue_list), of_count_tx_queue_list)) +		print("xmit netdevice:remain:%d overflow:%d" % +			(len(tx_xmit_list), of_count_tx_xmit_list)) +		print("receive:remain:%d overflow:%d" % +			(len(rx_skb_list), of_count_rx_skb_list))  # called from perf, when it finds a correspoinding event  def irq__softirq_entry(name, context, cpu, sec, nsec, pid, comm, callchain, vec): diff --git a/tools/perf/scripts/python/powerpc-hcalls.py b/tools/perf/scripts/python/powerpc-hcalls.py index 00e0e7476e55..8b78dc790adb 100644 --- a/tools/perf/scripts/python/powerpc-hcalls.py +++ b/tools/perf/scripts/python/powerpc-hcalls.py @@ -4,6 +4,8 @@  #  # Hypervisor call statisics +from __future__ import print_function +  import os  import sys @@ -149,7 +151,7 @@ hcall_table = {  }  def hcall_table_lookup(opcode): -	if (hcall_table.has_key(opcode)): +	if (opcode in hcall_table):  		return hcall_table[opcode]  	else:  		return opcode @@ -157,8 +159,8 @@ def hcall_table_lookup(opcode):  print_ptrn = '%-28s%10s%10s%10s%10s'  def trace_end(): -	print print_ptrn % ('hcall', 'count', 'min(ns)', 'max(ns)', 'avg(ns)') -	print '-' * 68 +	print(print_ptrn % ('hcall', 'count', 'min(ns)', 'max(ns)', 'avg(ns)')) +	print('-' * 68)  	for opcode in output:  		h_name = hcall_table_lookup(opcode)  		time = output[opcode]['time'] @@ -166,14 +168,14 @@ def trace_end():  		min_t = output[opcode]['min']  		max_t = output[opcode]['max'] -		print print_ptrn % (h_name, cnt, min_t, max_t, time/cnt) +		print(print_ptrn % (h_name, cnt, min_t, max_t, time//cnt))  def powerpc__hcall_exit(name, context, cpu, sec, nsec, pid, comm, callchain,  			opcode, retval): -	if (d_enter.has_key(cpu) and d_enter[cpu].has_key(opcode)): +	if (cpu in d_enter and opcode in d_enter[cpu]):  		diff = nsecs(sec, nsec) - d_enter[cpu][opcode] -		if (output.has_key(opcode)): +		if (opcode in output):  			output[opcode]['time'] += diff  			output[opcode]['cnt'] += 1  			if (output[opcode]['min'] > diff): @@ -190,11 +192,11 @@ def powerpc__hcall_exit(name, context, cpu, sec, nsec, pid, comm, callchain,  		del d_enter[cpu][opcode]  #	else: -#		print "Can't find matching hcall_enter event. Ignoring sample" +#		print("Can't find matching hcall_enter event. Ignoring sample")  def powerpc__hcall_entry(event_name, context, cpu, sec, nsec, pid, comm,  			 callchain, opcode): -		if (d_enter.has_key(cpu)): +		if (cpu in d_enter):  			d_enter[cpu][opcode] = nsecs(sec, nsec)  		else:  			d_enter[cpu] = {opcode: nsecs(sec, nsec)} diff --git a/tools/perf/scripts/python/sched-migration.py b/tools/perf/scripts/python/sched-migration.py index 3473e7f66081..3984bf51f3c5 100644 --- a/tools/perf/scripts/python/sched-migration.py +++ b/tools/perf/scripts/python/sched-migration.py @@ -1,5 +1,3 @@ -#!/usr/bin/python -#  # Cpu task migration overview toy  #  # Copyright (C) 2010 Frederic Weisbecker <[email protected]> diff --git a/tools/perf/scripts/python/sctop.py b/tools/perf/scripts/python/sctop.py index 61621b93affb..987ffae7c8ca 100644 --- a/tools/perf/scripts/python/sctop.py +++ b/tools/perf/scripts/python/sctop.py @@ -8,7 +8,14 @@  # will be refreshed every [interval] seconds.  The default interval is  # 3 seconds. -import os, sys, thread, time +from __future__ import print_function + +import os, sys, time + +try: +        import thread +except ImportError: +        import _thread as thread  sys.path.append(os.environ['PERF_EXEC_PATH'] + \  	'/scripts/python/Perf-Trace-Util/lib/Perf/Trace') @@ -62,18 +69,19 @@ def print_syscall_totals(interval):  	while 1:  		clear_term()  		if for_comm is not None: -			print "\nsyscall events for %s:\n\n" % (for_comm), +			print("\nsyscall events for %s:\n" % (for_comm))  		else: -			print "\nsyscall events:\n\n", +			print("\nsyscall events:\n") -		print "%-40s  %10s\n" % ("event", "count"), -		print "%-40s  %10s\n" % ("----------------------------------------", \ -						 "----------"), +		print("%-40s  %10s" % ("event", "count")) +		print("%-40s  %10s" % +                        ("----------------------------------------", +                        "----------")) -		for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \ +		for id, val in sorted(syscalls.items(), key = lambda kv: (kv[1], kv[0]), \  					      reverse = True):  			try: -				print "%-40s  %10d\n" % (syscall_name(id), val), +				print("%-40s  %10d" % (syscall_name(id), val))  			except TypeError:  				pass  		syscalls.clear() diff --git a/tools/perf/scripts/python/stackcollapse.py b/tools/perf/scripts/python/stackcollapse.py index 1697b5e18c96..5e703efaddcc 100755 --- a/tools/perf/scripts/python/stackcollapse.py +++ b/tools/perf/scripts/python/stackcollapse.py @@ -19,6 +19,8 @@  # Written by Paolo Bonzini <[email protected]>  # Based on Brendan Gregg's stackcollapse-perf.pl script. +from __future__ import print_function +  import os  import sys  from collections import defaultdict @@ -120,7 +122,6 @@ def process_event(param_dict):      lines[stack_string] = lines[stack_string] + 1  def trace_end(): -    list = lines.keys() -    list.sort() +    list = sorted(lines)      for stack in list: -        print "%s %d" % (stack, lines[stack]) +        print("%s %d" % (stack, lines[stack])) diff --git a/tools/perf/scripts/python/stat-cpi.py b/tools/perf/scripts/python/stat-cpi.py index 8410672efb8b..01fa933ff3cf 100644 --- a/tools/perf/scripts/python/stat-cpi.py +++ b/tools/perf/scripts/python/stat-cpi.py @@ -1,6 +1,7 @@ -#!/usr/bin/env python  # SPDX-License-Identifier: GPL-2.0 +from __future__ import print_function +  data    = {}  times   = []  threads = [] @@ -20,8 +21,8 @@ def store_key(time, cpu, thread):          threads.append(thread)  def store(time, event, cpu, thread, val, ena, run): -    #print "event %s cpu %d, thread %d, time %d, val %d, ena %d, run %d" % \ -    #      (event, cpu, thread, time, val, ena, run) +    #print("event %s cpu %d, thread %d, time %d, val %d, ena %d, run %d" % +    #      (event, cpu, thread, time, val, ena, run))      store_key(time, cpu, thread)      key = get_key(time, event, cpu, thread) @@ -59,7 +60,7 @@ def stat__interval(time):              if ins != 0:                  cpi = cyc/float(ins) -            print "%15f: cpu %d, thread %d -> cpi %f (%d/%d)" % (time/(float(1000000000)), cpu, thread, cpi, cyc, ins) +            print("%15f: cpu %d, thread %d -> cpi %f (%d/%d)" % (time/(float(1000000000)), cpu, thread, cpi, cyc, ins))  def trace_end():      pass @@ -75,4 +76,4 @@ def trace_end():  #                if ins != 0:  #                    cpi = cyc/float(ins)  # -#                print "time %.9f, cpu %d, thread %d -> cpi %f" % (time/(float(1000000000)), cpu, thread, cpi) +#                print("time %.9f, cpu %d, thread %d -> cpi %f" % (time/(float(1000000000)), cpu, thread, cpi)) diff --git a/tools/perf/scripts/python/syscall-counts-by-pid.py b/tools/perf/scripts/python/syscall-counts-by-pid.py index daf314cc5dd3..42782487b0e9 100644 --- a/tools/perf/scripts/python/syscall-counts-by-pid.py +++ b/tools/perf/scripts/python/syscall-counts-by-pid.py @@ -5,6 +5,8 @@  # Displays system-wide system call totals, broken down by syscall.  # If a [comm] arg is specified, only syscalls called by [comm] are displayed. +from __future__ import print_function +  import os, sys  sys.path.append(os.environ['PERF_EXEC_PATH'] + \ @@ -31,7 +33,7 @@ if len(sys.argv) > 1:  syscalls = autodict()  def trace_begin(): -	print "Press control+C to stop and show the summary" +	print("Press control+C to stop and show the summary")  def trace_end():  	print_syscall_totals() @@ -55,20 +57,20 @@ def syscalls__sys_enter(event_name, context, common_cpu,  def print_syscall_totals():      if for_comm is not None: -	    print "\nsyscall events for %s:\n\n" % (for_comm), +	    print("\nsyscall events for %s:\n" % (for_comm))      else: -	    print "\nsyscall events by comm/pid:\n\n", +	    print("\nsyscall events by comm/pid:\n") -    print "%-40s  %10s\n" % ("comm [pid]/syscalls", "count"), -    print "%-40s  %10s\n" % ("----------------------------------------", \ -                                 "----------"), +    print("%-40s  %10s" % ("comm [pid]/syscalls", "count")) +    print("%-40s  %10s" % ("----------------------------------------", +                            "----------"))      comm_keys = syscalls.keys()      for comm in comm_keys:  	    pid_keys = syscalls[comm].keys()  	    for pid in pid_keys: -		    print "\n%s [%d]\n" % (comm, pid), +		    print("\n%s [%d]" % (comm, pid))  		    id_keys = syscalls[comm][pid].keys() -		    for id, val in sorted(syscalls[comm][pid].iteritems(), \ -				  key = lambda(k, v): (v, k),  reverse = True): -			    print "  %-38s  %10d\n" % (syscall_name(id), val), +		    for id, val in sorted(syscalls[comm][pid].items(), \ +				  key = lambda kv: (kv[1], kv[0]),  reverse = True): +			    print("  %-38s  %10d" % (syscall_name(id), val)) diff --git a/tools/perf/scripts/python/syscall-counts.py b/tools/perf/scripts/python/syscall-counts.py index e66a7730aeb5..0ebd89cfd42c 100644 --- a/tools/perf/scripts/python/syscall-counts.py +++ b/tools/perf/scripts/python/syscall-counts.py @@ -5,6 +5,8 @@  # Displays system-wide system call totals, broken down by syscall.  # If a [comm] arg is specified, only syscalls called by [comm] are displayed. +from __future__ import print_function +  import os  import sys @@ -28,7 +30,7 @@ if len(sys.argv) > 1:  syscalls = autodict()  def trace_begin(): -	print "Press control+C to stop and show the summary" +	print("Press control+C to stop and show the summary")  def trace_end():  	print_syscall_totals() @@ -51,14 +53,14 @@ def syscalls__sys_enter(event_name, context, common_cpu,  def print_syscall_totals():      if for_comm is not None: -	    print "\nsyscall events for %s:\n\n" % (for_comm), +	    print("\nsyscall events for %s:\n" % (for_comm))      else: -	    print "\nsyscall events:\n\n", +	    print("\nsyscall events:\n") -    print "%-40s  %10s\n" % ("event", "count"), -    print "%-40s  %10s\n" % ("----------------------------------------", \ -                                 "-----------"), +    print("%-40s  %10s" % ("event", "count")) +    print("%-40s  %10s" % ("----------------------------------------", +                              "-----------")) -    for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \ +    for id, val in sorted(syscalls.items(), key = lambda kv: (kv[1], kv[0]), \  				  reverse = True): -	    print "%-40s  %10d\n" % (syscall_name(id), val), +	    print("%-40s  %10d" % (syscall_name(id), val)) |