aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/scripts/python
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2019-02-28 02:29:50 -0500
committerIngo Molnar <mingo@kernel.org>2019-02-28 02:29:50 -0500
commitc978b9460fe1d4a1e1effa0abd6bd69b18a098a8 (patch)
treeeecc4c6179dea191c55ac8ef50467573b29a0b06 /tools/perf/scripts/python
parent0a1571243d3f150fa99c6f41f1b8e17a307a2b8b (diff)
parentde667cce7f4f96b6e22da8fd9c065b961f355080 (diff)
Merge tag 'perf-core-for-mingo-5.1-20190225' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: perf annotate: Wei Li: - Fix getting source line failure perf script: Andi Kleen: - Handle missing fields with -F +... perf data: Jiri Olsa: - Prep work to support per-cpu files in a directory. Intel PT: Adrian Hunter: - Improve thread_stack__no_call_return() - Hide x86 retpolines in thread stacks. - exported SQL viewer refactorings, new 'top calls' report.. Alexander Shishkin: - Copy parent's address filter offsets on clone - Fix address filters for vmas with non-zero offset. Applies to ARM's CoreSight as well. python scripts: Tony Jones: - Python3 support for several 'perf script' python scripts. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/scripts/python')
-rwxr-xr-xtools/perf/scripts/python/exported-sql-viewer.py510
-rw-r--r--tools/perf/scripts/python/failed-syscalls-by-pid.py21
-rw-r--r--tools/perf/scripts/python/mem-phys-addr.py24
-rwxr-xr-xtools/perf/scripts/python/net_dropmonitor.py10
-rw-r--r--tools/perf/scripts/python/netdev-times.py82
-rw-r--r--tools/perf/scripts/python/powerpc-hcalls.py18
-rw-r--r--tools/perf/scripts/python/sctop.py24
-rwxr-xr-xtools/perf/scripts/python/stackcollapse.py7
-rw-r--r--tools/perf/scripts/python/stat-cpi.py10
-rw-r--r--tools/perf/scripts/python/syscall-counts-by-pid.py22
-rw-r--r--tools/perf/scripts/python/syscall-counts.py18
11 files changed, 482 insertions, 264 deletions
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index c3091401df91..09ce73b07d35 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -1,3 +1,4 @@
1#!/usr/bin/env python2
1# SPDX-License-Identifier: GPL-2.0 2# SPDX-License-Identifier: GPL-2.0
2# exported-sql-viewer.py: view data from sql database 3# exported-sql-viewer.py: view data from sql database
3# Copyright (c) 2014-2018, Intel Corporation. 4# Copyright (c) 2014-2018, Intel Corporation.
@@ -1397,18 +1398,28 @@ class BranchModel(TreeModel):
1397 def HasMoreRecords(self): 1398 def HasMoreRecords(self):
1398 return self.more 1399 return self.more
1399 1400
1401# Report Variables
1402
1403class ReportVars():
1404
1405 def __init__(self, name = "", where_clause = "", limit = ""):
1406 self.name = name
1407 self.where_clause = where_clause
1408 self.limit = limit
1409
1410 def UniqueId(self):
1411 return str(self.where_clause + ";" + self.limit)
1412
1400# Branch window 1413# Branch window
1401 1414
1402class BranchWindow(QMdiSubWindow): 1415class BranchWindow(QMdiSubWindow):
1403 1416
1404 def __init__(self, glb, event_id, name, where_clause, parent=None): 1417 def __init__(self, glb, event_id, report_vars, parent=None):
1405 super(BranchWindow, self).__init__(parent) 1418 super(BranchWindow, self).__init__(parent)
1406 1419
1407 model_name = "Branch Events " + str(event_id) 1420 model_name = "Branch Events " + str(event_id) + " " + report_vars.UniqueId()
1408 if len(where_clause):
1409 model_name = where_clause + " " + model_name
1410 1421
1411 self.model = LookupCreateModel(model_name, lambda: BranchModel(glb, event_id, where_clause)) 1422 self.model = LookupCreateModel(model_name, lambda: BranchModel(glb, event_id, report_vars.where_clause))
1412 1423
1413 self.view = QTreeView() 1424 self.view = QTreeView()
1414 self.view.setUniformRowHeights(True) 1425 self.view.setUniformRowHeights(True)
@@ -1426,7 +1437,7 @@ class BranchWindow(QMdiSubWindow):
1426 1437
1427 self.setWidget(self.vbox.Widget()) 1438 self.setWidget(self.vbox.Widget())
1428 1439
1429 AddSubWindow(glb.mainwindow.mdi_area, self, name + " Branch Events") 1440 AddSubWindow(glb.mainwindow.mdi_area, self, report_vars.name + " Branch Events")
1430 1441
1431 def ResizeColumnToContents(self, column, n): 1442 def ResizeColumnToContents(self, column, n):
1432 # Using the view's resizeColumnToContents() here is extrememly slow 1443 # Using the view's resizeColumnToContents() here is extrememly slow
@@ -1471,47 +1482,134 @@ class BranchWindow(QMdiSubWindow):
1471 else: 1482 else:
1472 self.find_bar.NotFound() 1483 self.find_bar.NotFound()
1473 1484
1474# Dialog data item converted and validated using a SQL table 1485# Line edit data item
1475 1486
1476class SQLTableDialogDataItem(): 1487class LineEditDataItem(object):
1477 1488
1478 def __init__(self, glb, label, placeholder_text, table_name, match_column, column_name1, column_name2, parent): 1489 def __init__(self, glb, label, placeholder_text, parent, id = "", default = ""):
1479 self.glb = glb 1490 self.glb = glb
1480 self.label = label 1491 self.label = label
1481 self.placeholder_text = placeholder_text 1492 self.placeholder_text = placeholder_text
1482 self.table_name = table_name
1483 self.match_column = match_column
1484 self.column_name1 = column_name1
1485 self.column_name2 = column_name2
1486 self.parent = parent 1493 self.parent = parent
1494 self.id = id
1487 1495
1488 self.value = "" 1496 self.value = default
1489 1497
1490 self.widget = QLineEdit() 1498 self.widget = QLineEdit(default)
1491 self.widget.editingFinished.connect(self.Validate) 1499 self.widget.editingFinished.connect(self.Validate)
1492 self.widget.textChanged.connect(self.Invalidate) 1500 self.widget.textChanged.connect(self.Invalidate)
1493 self.red = False 1501 self.red = False
1494 self.error = "" 1502 self.error = ""
1495 self.validated = True 1503 self.validated = True
1496 1504
1497 self.last_id = 0
1498 self.first_time = 0
1499 self.last_time = 2 ** 64
1500 if self.table_name == "<timeranges>":
1501 query = QSqlQuery(self.glb.db)
1502 QueryExec(query, "SELECT id, time FROM samples ORDER BY id DESC LIMIT 1")
1503 if query.next():
1504 self.last_id = int(query.value(0))
1505 self.last_time = int(query.value(1))
1506 QueryExec(query, "SELECT time FROM samples WHERE time != 0 ORDER BY id LIMIT 1")
1507 if query.next():
1508 self.first_time = int(query.value(0))
1509 if placeholder_text:
1510 placeholder_text += ", between " + str(self.first_time) + " and " + str(self.last_time)
1511
1512 if placeholder_text: 1505 if placeholder_text:
1513 self.widget.setPlaceholderText(placeholder_text) 1506 self.widget.setPlaceholderText(placeholder_text)
1514 1507
1508 def TurnTextRed(self):
1509 if not self.red:
1510 palette = QPalette()
1511 palette.setColor(QPalette.Text,Qt.red)
1512 self.widget.setPalette(palette)
1513 self.red = True
1514
1515 def TurnTextNormal(self):
1516 if self.red:
1517 palette = QPalette()
1518 self.widget.setPalette(palette)
1519 self.red = False
1520
1521 def InvalidValue(self, value):
1522 self.value = ""
1523 self.TurnTextRed()
1524 self.error = self.label + " invalid value '" + value + "'"
1525 self.parent.ShowMessage(self.error)
1526
1527 def Invalidate(self):
1528 self.validated = False
1529
1530 def DoValidate(self, input_string):
1531 self.value = input_string.strip()
1532
1533 def Validate(self):
1534 self.validated = True
1535 self.error = ""
1536 self.TurnTextNormal()
1537 self.parent.ClearMessage()
1538 input_string = self.widget.text()
1539 if not len(input_string.strip()):
1540 self.value = ""
1541 return
1542 self.DoValidate(input_string)
1543
1544 def IsValid(self):
1545 if not self.validated:
1546 self.Validate()
1547 if len(self.error):
1548 self.parent.ShowMessage(self.error)
1549 return False
1550 return True
1551
1552 def IsNumber(self, value):
1553 try:
1554 x = int(value)
1555 except:
1556 x = 0
1557 return str(x) == value
1558
1559# Non-negative integer ranges dialog data item
1560
1561class NonNegativeIntegerRangesDataItem(LineEditDataItem):
1562
1563 def __init__(self, glb, label, placeholder_text, column_name, parent):
1564 super(NonNegativeIntegerRangesDataItem, self).__init__(glb, label, placeholder_text, parent)
1565
1566 self.column_name = column_name
1567
1568 def DoValidate(self, input_string):
1569 singles = []
1570 ranges = []
1571 for value in [x.strip() for x in input_string.split(",")]:
1572 if "-" in value:
1573 vrange = value.split("-")
1574 if len(vrange) != 2 or not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]):
1575 return self.InvalidValue(value)
1576 ranges.append(vrange)
1577 else:
1578 if not self.IsNumber(value):
1579 return self.InvalidValue(value)
1580 singles.append(value)
1581 ranges = [("(" + self.column_name + " >= " + r[0] + " AND " + self.column_name + " <= " + r[1] + ")") for r in ranges]
1582 if len(singles):
1583 ranges.append(self.column_name + " IN (" + ",".join(singles) + ")")
1584 self.value = " OR ".join(ranges)
1585
1586# Positive integer dialog data item
1587
1588class PositiveIntegerDataItem(LineEditDataItem):
1589
1590 def __init__(self, glb, label, placeholder_text, parent, id = "", default = ""):
1591 super(PositiveIntegerDataItem, self).__init__(glb, label, placeholder_text, parent, id, default)
1592
1593 def DoValidate(self, input_string):
1594 if not self.IsNumber(input_string.strip()):
1595 return self.InvalidValue(input_string)
1596 value = int(input_string.strip())
1597 if value <= 0:
1598 return self.InvalidValue(input_string)
1599 self.value = str(value)
1600
1601# Dialog data item converted and validated using a SQL table
1602
1603class SQLTableDataItem(LineEditDataItem):
1604
1605 def __init__(self, glb, label, placeholder_text, table_name, match_column, column_name1, column_name2, parent):
1606 super(SQLTableDataItem, self).__init__(glb, label, placeholder_text, parent)
1607
1608 self.table_name = table_name
1609 self.match_column = match_column
1610 self.column_name1 = column_name1
1611 self.column_name2 = column_name2
1612
1515 def ValueToIds(self, value): 1613 def ValueToIds(self, value):
1516 ids = [] 1614 ids = []
1517 query = QSqlQuery(self.glb.db) 1615 query = QSqlQuery(self.glb.db)
@@ -1522,6 +1620,42 @@ class SQLTableDialogDataItem():
1522 ids.append(str(query.value(0))) 1620 ids.append(str(query.value(0)))
1523 return ids 1621 return ids
1524 1622
1623 def DoValidate(self, input_string):
1624 all_ids = []
1625 for value in [x.strip() for x in input_string.split(",")]:
1626 ids = self.ValueToIds(value)
1627 if len(ids):
1628 all_ids.extend(ids)
1629 else:
1630 return self.InvalidValue(value)
1631 self.value = self.column_name1 + " IN (" + ",".join(all_ids) + ")"
1632 if self.column_name2:
1633 self.value = "( " + self.value + " OR " + self.column_name2 + " IN (" + ",".join(all_ids) + ") )"
1634
1635# Sample time ranges dialog data item converted and validated using 'samples' SQL table
1636
1637class SampleTimeRangesDataItem(LineEditDataItem):
1638
1639 def __init__(self, glb, label, placeholder_text, column_name, parent):
1640 self.column_name = column_name
1641
1642 self.last_id = 0
1643 self.first_time = 0
1644 self.last_time = 2 ** 64
1645
1646 query = QSqlQuery(glb.db)
1647 QueryExec(query, "SELECT id, time FROM samples ORDER BY id DESC LIMIT 1")
1648 if query.next():
1649 self.last_id = int(query.value(0))
1650 self.last_time = int(query.value(1))
1651 QueryExec(query, "SELECT time FROM samples WHERE time != 0 ORDER BY id LIMIT 1")
1652 if query.next():
1653 self.first_time = int(query.value(0))
1654 if placeholder_text:
1655 placeholder_text += ", between " + str(self.first_time) + " and " + str(self.last_time)
1656
1657 super(SampleTimeRangesDataItem, self).__init__(glb, label, placeholder_text, parent)
1658
1525 def IdBetween(self, query, lower_id, higher_id, order): 1659 def IdBetween(self, query, lower_id, higher_id, order):
1526 QueryExec(query, "SELECT id FROM samples WHERE id > " + str(lower_id) + " AND id < " + str(higher_id) + " ORDER BY id " + order + " LIMIT 1") 1660 QueryExec(query, "SELECT id FROM samples WHERE id > " + str(lower_id) + " AND id < " + str(higher_id) + " ORDER BY id " + order + " LIMIT 1")
1527 if query.next(): 1661 if query.next():
@@ -1559,7 +1693,6 @@ class SQLTableDialogDataItem():
1559 return str(lower_id) 1693 return str(lower_id)
1560 1694
1561 def ConvertRelativeTime(self, val): 1695 def ConvertRelativeTime(self, val):
1562 print "val ", val
1563 mult = 1 1696 mult = 1
1564 suffix = val[-2:] 1697 suffix = val[-2:]
1565 if suffix == "ms": 1698 if suffix == "ms":
@@ -1581,29 +1714,23 @@ class SQLTableDialogDataItem():
1581 return str(val) 1714 return str(val)
1582 1715
1583 def ConvertTimeRange(self, vrange): 1716 def ConvertTimeRange(self, vrange):
1584 print "vrange ", vrange
1585 if vrange[0] == "": 1717 if vrange[0] == "":
1586 vrange[0] = str(self.first_time) 1718 vrange[0] = str(self.first_time)
1587 if vrange[1] == "": 1719 if vrange[1] == "":
1588 vrange[1] = str(self.last_time) 1720 vrange[1] = str(self.last_time)
1589 vrange[0] = self.ConvertRelativeTime(vrange[0]) 1721 vrange[0] = self.ConvertRelativeTime(vrange[0])
1590 vrange[1] = self.ConvertRelativeTime(vrange[1]) 1722 vrange[1] = self.ConvertRelativeTime(vrange[1])
1591 print "vrange2 ", vrange
1592 if not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]): 1723 if not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]):
1593 return False 1724 return False
1594 print "ok1"
1595 beg_range = max(int(vrange[0]), self.first_time) 1725 beg_range = max(int(vrange[0]), self.first_time)
1596 end_range = min(int(vrange[1]), self.last_time) 1726 end_range = min(int(vrange[1]), self.last_time)
1597 if beg_range > self.last_time or end_range < self.first_time: 1727 if beg_range > self.last_time or end_range < self.first_time:
1598 return False 1728 return False
1599 print "ok2"
1600 vrange[0] = self.BinarySearchTime(0, self.last_id, beg_range, True) 1729 vrange[0] = self.BinarySearchTime(0, self.last_id, beg_range, True)
1601 vrange[1] = self.BinarySearchTime(1, self.last_id + 1, end_range, False) 1730 vrange[1] = self.BinarySearchTime(1, self.last_id + 1, end_range, False)
1602 print "vrange3 ", vrange
1603 return True 1731 return True
1604 1732
1605 def AddTimeRange(self, value, ranges): 1733 def AddTimeRange(self, value, ranges):
1606 print "value ", value
1607 n = value.count("-") 1734 n = value.count("-")
1608 if n == 1: 1735 if n == 1:
1609 pass 1736 pass
@@ -1621,111 +1748,31 @@ class SQLTableDialogDataItem():
1621 return True 1748 return True
1622 return False 1749 return False
1623 1750
1624 def InvalidValue(self, value): 1751 def DoValidate(self, input_string):
1625 self.value = "" 1752 ranges = []
1626 palette = QPalette() 1753 for value in [x.strip() for x in input_string.split(",")]:
1627 palette.setColor(QPalette.Text,Qt.red) 1754 if not self.AddTimeRange(value, ranges):
1628 self.widget.setPalette(palette) 1755 return self.InvalidValue(value)
1629 self.red = True 1756 ranges = [("(" + self.column_name + " >= " + r[0] + " AND " + self.column_name + " <= " + r[1] + ")") for r in ranges]
1630 self.error = self.label + " invalid value '" + value + "'" 1757 self.value = " OR ".join(ranges)
1631 self.parent.ShowMessage(self.error)
1632 1758
1633 def IsNumber(self, value): 1759# Report Dialog Base
1634 try:
1635 x = int(value)
1636 except:
1637 x = 0
1638 return str(x) == value
1639 1760
1640 def Invalidate(self): 1761class ReportDialogBase(QDialog):
1641 self.validated = False
1642 1762
1643 def Validate(self): 1763 def __init__(self, glb, title, items, partial, parent=None):
1644 input_string = self.widget.text() 1764 super(ReportDialogBase, self).__init__(parent)
1645 self.validated = True
1646 if self.red:
1647 palette = QPalette()
1648 self.widget.setPalette(palette)
1649 self.red = False
1650 if not len(input_string.strip()):
1651 self.error = ""
1652 self.value = ""
1653 return
1654 if self.table_name == "<timeranges>":
1655 ranges = []
1656 for value in [x.strip() for x in input_string.split(",")]:
1657 if not self.AddTimeRange(value, ranges):
1658 return self.InvalidValue(value)
1659 ranges = [("(" + self.column_name1 + " >= " + r[0] + " AND " + self.column_name1 + " <= " + r[1] + ")") for r in ranges]
1660 self.value = " OR ".join(ranges)
1661 elif self.table_name == "<ranges>":
1662 singles = []
1663 ranges = []
1664 for value in [x.strip() for x in input_string.split(",")]:
1665 if "-" in value:
1666 vrange = value.split("-")
1667 if len(vrange) != 2 or not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]):
1668 return self.InvalidValue(value)
1669 ranges.append(vrange)
1670 else:
1671 if not self.IsNumber(value):
1672 return self.InvalidValue(value)
1673 singles.append(value)
1674 ranges = [("(" + self.column_name1 + " >= " + r[0] + " AND " + self.column_name1 + " <= " + r[1] + ")") for r in ranges]
1675 if len(singles):
1676 ranges.append(self.column_name1 + " IN (" + ",".join(singles) + ")")
1677 self.value = " OR ".join(ranges)
1678 elif self.table_name:
1679 all_ids = []
1680 for value in [x.strip() for x in input_string.split(",")]:
1681 ids = self.ValueToIds(value)
1682 if len(ids):
1683 all_ids.extend(ids)
1684 else:
1685 return self.InvalidValue(value)
1686 self.value = self.column_name1 + " IN (" + ",".join(all_ids) + ")"
1687 if self.column_name2:
1688 self.value = "( " + self.value + " OR " + self.column_name2 + " IN (" + ",".join(all_ids) + ") )"
1689 else:
1690 self.value = input_string.strip()
1691 self.error = ""
1692 self.parent.ClearMessage()
1693
1694 def IsValid(self):
1695 if not self.validated:
1696 self.Validate()
1697 if len(self.error):
1698 self.parent.ShowMessage(self.error)
1699 return False
1700 return True
1701
1702# Selected branch report creation dialog
1703
1704class SelectedBranchDialog(QDialog):
1705
1706 def __init__(self, glb, parent=None):
1707 super(SelectedBranchDialog, self).__init__(parent)
1708 1765
1709 self.glb = glb 1766 self.glb = glb
1710 1767
1711 self.name = "" 1768 self.report_vars = ReportVars()
1712 self.where_clause = ""
1713 1769
1714 self.setWindowTitle("Selected Branches") 1770 self.setWindowTitle(title)
1715 self.setMinimumWidth(600) 1771 self.setMinimumWidth(600)
1716 1772
1717 items = ( 1773 self.data_items = [x(glb, self) for x in items]
1718 ("Report name:", "Enter a name to appear in the window title bar", "", "", "", ""), 1774
1719 ("Time ranges:", "Enter time ranges", "<timeranges>", "", "samples.id", ""), 1775 self.partial = partial
1720 ("CPUs:", "Enter CPUs or ranges e.g. 0,5-6", "<ranges>", "", "cpu", ""),
1721 ("Commands:", "Only branches with these commands will be included", "comms", "comm", "comm_id", ""),
1722 ("PIDs:", "Only branches with these process IDs will be included", "threads", "pid", "thread_id", ""),
1723 ("TIDs:", "Only branches with these thread IDs will be included", "threads", "tid", "thread_id", ""),
1724 ("DSOs:", "Only branches with these DSOs will be included", "dsos", "short_name", "samples.dso_id", "to_dso_id"),
1725 ("Symbols:", "Only branches with these symbols will be included", "symbols", "name", "symbol_id", "to_symbol_id"),
1726 ("Raw SQL clause: ", "Enter a raw SQL WHERE clause", "", "", "", ""),
1727 )
1728 self.data_items = [SQLTableDialogDataItem(glb, *x, parent=self) for x in items]
1729 1776
1730 self.grid = QGridLayout() 1777 self.grid = QGridLayout()
1731 1778
@@ -1757,23 +1804,28 @@ class SelectedBranchDialog(QDialog):
1757 self.setLayout(self.vbox); 1804 self.setLayout(self.vbox);
1758 1805
1759 def Ok(self): 1806 def Ok(self):
1760 self.name = self.data_items[0].value 1807 vars = self.report_vars
1761 if not self.name: 1808 for d in self.data_items:
1809 if d.id == "REPORTNAME":
1810 vars.name = d.value
1811 if not vars.name:
1762 self.ShowMessage("Report name is required") 1812 self.ShowMessage("Report name is required")
1763 return 1813 return
1764 for d in self.data_items: 1814 for d in self.data_items:
1765 if not d.IsValid(): 1815 if not d.IsValid():
1766 return 1816 return
1767 for d in self.data_items[1:]: 1817 for d in self.data_items[1:]:
1768 if len(d.value): 1818 if d.id == "LIMIT":
1769 if len(self.where_clause): 1819 vars.limit = d.value
1770 self.where_clause += " AND " 1820 elif len(d.value):
1771 self.where_clause += d.value 1821 if len(vars.where_clause):
1772 if len(self.where_clause): 1822 vars.where_clause += " AND "
1773 self.where_clause = " AND ( " + self.where_clause + " ) " 1823 vars.where_clause += d.value
1774 else: 1824 if len(vars.where_clause):
1775 self.ShowMessage("No selection") 1825 if self.partial:
1776 return 1826 vars.where_clause = " AND ( " + vars.where_clause + " ) "
1827 else:
1828 vars.where_clause = " WHERE " + vars.where_clause + " "
1777 self.accept() 1829 self.accept()
1778 1830
1779 def ShowMessage(self, msg): 1831 def ShowMessage(self, msg):
@@ -1782,6 +1834,23 @@ class SelectedBranchDialog(QDialog):
1782 def ClearMessage(self): 1834 def ClearMessage(self):
1783 self.status.setText("") 1835 self.status.setText("")
1784 1836
1837# Selected branch report creation dialog
1838
1839class SelectedBranchDialog(ReportDialogBase):
1840
1841 def __init__(self, glb, parent=None):
1842 title = "Selected Branches"
1843 items = (lambda g, p: LineEditDataItem(g, "Report name:", "Enter a name to appear in the window title bar", p, "REPORTNAME"),
1844 lambda g, p: SampleTimeRangesDataItem(g, "Time ranges:", "Enter time ranges", "samples.id", p),
1845 lambda g, p: NonNegativeIntegerRangesDataItem(g, "CPUs:", "Enter CPUs or ranges e.g. 0,5-6", "cpu", p),
1846 lambda g, p: SQLTableDataItem(g, "Commands:", "Only branches with these commands will be included", "comms", "comm", "comm_id", "", p),
1847 lambda g, p: SQLTableDataItem(g, "PIDs:", "Only branches with these process IDs will be included", "threads", "pid", "thread_id", "", p),
1848 lambda g, p: SQLTableDataItem(g, "TIDs:", "Only branches with these thread IDs will be included", "threads", "tid", "thread_id", "", p),
1849 lambda g, p: SQLTableDataItem(g, "DSOs:", "Only branches with these DSOs will be included", "dsos", "short_name", "samples.dso_id", "to_dso_id", p),
1850 lambda g, p: SQLTableDataItem(g, "Symbols:", "Only branches with these symbols will be included", "symbols", "name", "symbol_id", "to_symbol_id", p),
1851 lambda g, p: LineEditDataItem(g, "Raw SQL clause: ", "Enter a raw SQL WHERE clause", p))
1852 super(SelectedBranchDialog, self).__init__(glb, title, items, True, parent)
1853
1785# Event list 1854# Event list
1786 1855
1787def GetEventList(db): 1856def GetEventList(db):
@@ -1792,6 +1861,16 @@ def GetEventList(db):
1792 events.append(query.value(0)) 1861 events.append(query.value(0))
1793 return events 1862 return events
1794 1863
1864# Is a table selectable
1865
1866def IsSelectable(db, table):
1867 query = QSqlQuery(db)
1868 try:
1869 QueryExec(query, "SELECT * FROM " + table + " LIMIT 1")
1870 except:
1871 return False
1872 return True
1873
1795# SQL data preparation 1874# SQL data preparation
1796 1875
1797def SQLTableDataPrep(query, count): 1876def SQLTableDataPrep(query, count):
@@ -1817,12 +1896,13 @@ class SQLTableModel(TableModel):
1817 1896
1818 progress = Signal(object) 1897 progress = Signal(object)
1819 1898
1820 def __init__(self, glb, sql, column_count, parent=None): 1899 def __init__(self, glb, sql, column_headers, parent=None):
1821 super(SQLTableModel, self).__init__(parent) 1900 super(SQLTableModel, self).__init__(parent)
1822 self.glb = glb 1901 self.glb = glb
1823 self.more = True 1902 self.more = True
1824 self.populated = 0 1903 self.populated = 0
1825 self.fetcher = SQLFetcher(glb, sql, lambda x, y=column_count: SQLTableDataPrep(x, y), self.AddSample) 1904 self.column_headers = column_headers
1905 self.fetcher = SQLFetcher(glb, sql, lambda x, y=len(column_headers): SQLTableDataPrep(x, y), self.AddSample)
1826 self.fetcher.done.connect(self.Update) 1906 self.fetcher.done.connect(self.Update)
1827 self.fetcher.Fetch(glb_chunk_sz) 1907 self.fetcher.Fetch(glb_chunk_sz)
1828 1908
@@ -1860,6 +1940,12 @@ class SQLTableModel(TableModel):
1860 def HasMoreRecords(self): 1940 def HasMoreRecords(self):
1861 return self.more 1941 return self.more
1862 1942
1943 def columnCount(self, parent=None):
1944 return len(self.column_headers)
1945
1946 def columnHeader(self, column):
1947 return self.column_headers[column]
1948
1863# SQL automatic table data model 1949# SQL automatic table data model
1864 1950
1865class SQLAutoTableModel(SQLTableModel): 1951class SQLAutoTableModel(SQLTableModel):
@@ -1869,12 +1955,12 @@ class SQLAutoTableModel(SQLTableModel):
1869 if table_name == "comm_threads_view": 1955 if table_name == "comm_threads_view":
1870 # For now, comm_threads_view has no id column 1956 # For now, comm_threads_view has no id column
1871 sql = "SELECT * FROM " + table_name + " WHERE comm_id > $$last_id$$ ORDER BY comm_id LIMIT " + str(glb_chunk_sz) 1957 sql = "SELECT * FROM " + table_name + " WHERE comm_id > $$last_id$$ ORDER BY comm_id LIMIT " + str(glb_chunk_sz)
1872 self.column_headers = [] 1958 column_headers = []
1873 query = QSqlQuery(glb.db) 1959 query = QSqlQuery(glb.db)
1874 if glb.dbref.is_sqlite3: 1960 if glb.dbref.is_sqlite3:
1875 QueryExec(query, "PRAGMA table_info(" + table_name + ")") 1961 QueryExec(query, "PRAGMA table_info(" + table_name + ")")
1876 while query.next(): 1962 while query.next():
1877 self.column_headers.append(query.value(1)) 1963 column_headers.append(query.value(1))
1878 if table_name == "sqlite_master": 1964 if table_name == "sqlite_master":
1879 sql = "SELECT * FROM " + table_name 1965 sql = "SELECT * FROM " + table_name
1880 else: 1966 else:
@@ -1887,14 +1973,8 @@ class SQLAutoTableModel(SQLTableModel):
1887 schema = "public" 1973 schema = "public"
1888 QueryExec(query, "SELECT column_name FROM information_schema.columns WHERE table_schema = '" + schema + "' and table_name = '" + select_table_name + "'") 1974 QueryExec(query, "SELECT column_name FROM information_schema.columns WHERE table_schema = '" + schema + "' and table_name = '" + select_table_name + "'")
1889 while query.next(): 1975 while query.next():
1890 self.column_headers.append(query.value(0)) 1976 column_headers.append(query.value(0))
1891 super(SQLAutoTableModel, self).__init__(glb, sql, len(self.column_headers), parent) 1977 super(SQLAutoTableModel, self).__init__(glb, sql, column_headers, parent)
1892
1893 def columnCount(self, parent=None):
1894 return len(self.column_headers)
1895
1896 def columnHeader(self, column):
1897 return self.column_headers[column]
1898 1978
1899# Base class for custom ResizeColumnsToContents 1979# Base class for custom ResizeColumnsToContents
1900 1980
@@ -1997,6 +2077,103 @@ def GetTableList(glb):
1997 tables.append("information_schema.columns") 2077 tables.append("information_schema.columns")
1998 return tables 2078 return tables
1999 2079
2080# Top Calls data model
2081
2082class TopCallsModel(SQLTableModel):
2083
2084 def __init__(self, glb, report_vars, parent=None):
2085 text = ""
2086 if not glb.dbref.is_sqlite3:
2087 text = "::text"
2088 limit = ""
2089 if len(report_vars.limit):
2090 limit = " LIMIT " + report_vars.limit
2091 sql = ("SELECT comm, pid, tid, name,"
2092 " CASE"
2093 " WHEN (short_name = '[kernel.kallsyms]') THEN '[kernel]'" + text +
2094 " ELSE short_name"
2095 " END AS dso,"
2096 " call_time, return_time, (return_time - call_time) AS elapsed_time, branch_count, "
2097 " CASE"
2098 " WHEN (calls.flags = 1) THEN 'no call'" + text +
2099 " WHEN (calls.flags = 2) THEN 'no return'" + text +
2100 " WHEN (calls.flags = 3) THEN 'no call/return'" + text +
2101 " ELSE ''" + text +
2102 " END AS flags"
2103 " FROM calls"
2104 " INNER JOIN call_paths ON calls.call_path_id = call_paths.id"
2105 " INNER JOIN symbols ON call_paths.symbol_id = symbols.id"
2106 " INNER JOIN dsos ON symbols.dso_id = dsos.id"
2107 " INNER JOIN comms ON calls.comm_id = comms.id"
2108 " INNER JOIN threads ON calls.thread_id = threads.id" +
2109 report_vars.where_clause +
2110 " ORDER BY elapsed_time DESC" +
2111 limit
2112 )
2113 column_headers = ("Command", "PID", "TID", "Symbol", "Object", "Call Time", "Return Time", "Elapsed Time (ns)", "Branch Count", "Flags")
2114 self.alignment = (Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignRight, Qt.AlignRight, Qt.AlignLeft)
2115 super(TopCallsModel, self).__init__(glb, sql, column_headers, parent)
2116
2117 def columnAlignment(self, column):
2118 return self.alignment[column]
2119
2120# Top Calls report creation dialog
2121
2122class TopCallsDialog(ReportDialogBase):
2123
2124 def __init__(self, glb, parent=None):
2125 title = "Top Calls by Elapsed Time"
2126 items = (lambda g, p: LineEditDataItem(g, "Report name:", "Enter a name to appear in the window title bar", p, "REPORTNAME"),
2127 lambda g, p: SQLTableDataItem(g, "Commands:", "Only calls with these commands will be included", "comms", "comm", "comm_id", "", p),
2128 lambda g, p: SQLTableDataItem(g, "PIDs:", "Only calls with these process IDs will be included", "threads", "pid", "thread_id", "", p),
2129 lambda g, p: SQLTableDataItem(g, "TIDs:", "Only calls with these thread IDs will be included", "threads", "tid", "thread_id", "", p),
2130 lambda g, p: SQLTableDataItem(g, "DSOs:", "Only calls with these DSOs will be included", "dsos", "short_name", "dso_id", "", p),
2131 lambda g, p: SQLTableDataItem(g, "Symbols:", "Only calls with these symbols will be included", "symbols", "name", "symbol_id", "", p),
2132 lambda g, p: LineEditDataItem(g, "Raw SQL clause: ", "Enter a raw SQL WHERE clause", p),
2133 lambda g, p: PositiveIntegerDataItem(g, "Record limit:", "Limit selection to this number of records", p, "LIMIT", "100"))
2134 super(TopCallsDialog, self).__init__(glb, title, items, False, parent)
2135
2136# Top Calls window
2137
2138class TopCallsWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
2139
2140 def __init__(self, glb, report_vars, parent=None):
2141 super(TopCallsWindow, self).__init__(parent)
2142
2143 self.data_model = LookupCreateModel("Top Calls " + report_vars.UniqueId(), lambda: TopCallsModel(glb, report_vars))
2144 self.model = self.data_model
2145
2146 self.view = QTableView()
2147 self.view.setModel(self.model)
2148 self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
2149 self.view.verticalHeader().setVisible(False)
2150
2151 self.ResizeColumnsToContents()
2152
2153 self.find_bar = FindBar(self, self, True)
2154
2155 self.finder = ChildDataItemFinder(self.model)
2156
2157 self.fetch_bar = FetchMoreRecordsBar(self.data_model, self)
2158
2159 self.vbox = VBox(self.view, self.find_bar.Widget(), self.fetch_bar.Widget())
2160
2161 self.setWidget(self.vbox.Widget())
2162
2163 AddSubWindow(glb.mainwindow.mdi_area, self, report_vars.name)
2164
2165 def Find(self, value, direction, pattern, context):
2166 self.view.setFocus()
2167 self.find_bar.Busy()
2168 self.finder.Find(value, direction, pattern, context, self.FindDone)
2169
2170 def FindDone(self, row):
2171 self.find_bar.Idle()
2172 if row >= 0:
2173 self.view.setCurrentIndex(self.model.index(row, 0, QModelIndex()))
2174 else:
2175 self.find_bar.NotFound()
2176
2000# Action Definition 2177# Action Definition
2001 2178
2002def CreateAction(label, tip, callback, parent=None, shortcut=None): 2179def CreateAction(label, tip, callback, parent=None, shortcut=None):
@@ -2100,6 +2277,7 @@ p.c2 {
2100<p class=c2><a href=#callgraph>1.1 Context-Sensitive Call Graph</a></p> 2277<p class=c2><a href=#callgraph>1.1 Context-Sensitive Call Graph</a></p>
2101<p class=c2><a href=#allbranches>1.2 All branches</a></p> 2278<p class=c2><a href=#allbranches>1.2 All branches</a></p>
2102<p class=c2><a href=#selectedbranches>1.3 Selected branches</a></p> 2279<p class=c2><a href=#selectedbranches>1.3 Selected branches</a></p>
2280<p class=c2><a href=#topcallsbyelapsedtime>1.4 Top calls by elapsed time</a></p>
2103<p class=c1><a href=#tables>2. Tables</a></p> 2281<p class=c1><a href=#tables>2. Tables</a></p>
2104<h1 id=reports>1. Reports</h1> 2282<h1 id=reports>1. Reports</h1>
2105<h2 id=callgraph>1.1 Context-Sensitive Call Graph</h2> 2283<h2 id=callgraph>1.1 Context-Sensitive Call Graph</h2>
@@ -2175,6 +2353,10 @@ ms, us or ns. Also, negative values are relative to the end of trace. Examples:
2175 -10ms- The last 10ms 2353 -10ms- The last 10ms
2176</pre> 2354</pre>
2177N.B. Due to the granularity of timestamps, there could be no branches in any given time range. 2355N.B. Due to the granularity of timestamps, there could be no branches in any given time range.
2356<h2 id=topcallsbyelapsedtime>1.4 Top calls by elapsed time</h2>
2357The Top calls by elapsed time report displays calls in descending order of time elapsed between when the function was called and when it returned.
2358The data is reduced by various selection criteria. A dialog box displays available criteria which are AND'ed together.
2359If not all data is fetched, a Fetch bar is provided. Ctrl-F displays a Find bar.
2178<h1 id=tables>2. Tables</h1> 2360<h1 id=tables>2. Tables</h1>
2179The Tables menu shows all tables and views in the database. Most tables have an associated view 2361The Tables menu shows all tables and views in the database. Most tables have an associated view
2180which displays the information in a more friendly way. Not all data for large tables is fetched 2362which displays the information in a more friendly way. Not all data for large tables is fetched
@@ -2304,10 +2486,14 @@ class MainWindow(QMainWindow):
2304 edit_menu.addAction(CreateAction("&Enlarge Font", "Make text bigger", self.EnlargeFont, self, [QKeySequence("Ctrl++")])) 2486 edit_menu.addAction(CreateAction("&Enlarge Font", "Make text bigger", self.EnlargeFont, self, [QKeySequence("Ctrl++")]))
2305 2487
2306 reports_menu = menu.addMenu("&Reports") 2488 reports_menu = menu.addMenu("&Reports")
2307 reports_menu.addAction(CreateAction("Context-Sensitive Call &Graph", "Create a new window containing a context-sensitive call graph", self.NewCallGraph, self)) 2489 if IsSelectable(glb.db, "calls"):
2490 reports_menu.addAction(CreateAction("Context-Sensitive Call &Graph", "Create a new window containing a context-sensitive call graph", self.NewCallGraph, self))
2308 2491
2309 self.EventMenu(GetEventList(glb.db), reports_menu) 2492 self.EventMenu(GetEventList(glb.db), reports_menu)
2310 2493
2494 if IsSelectable(glb.db, "calls"):
2495 reports_menu.addAction(CreateAction("&Top calls by elapsed time", "Create a new window displaying top calls by elapsed time", self.NewTopCalls, self))
2496
2311 self.TableMenu(GetTableList(glb), menu) 2497 self.TableMenu(GetTableList(glb), menu)
2312 2498
2313 self.window_menu = WindowMenu(self.mdi_area, menu) 2499 self.window_menu = WindowMenu(self.mdi_area, menu)
@@ -2363,14 +2549,20 @@ class MainWindow(QMainWindow):
2363 def NewCallGraph(self): 2549 def NewCallGraph(self):
2364 CallGraphWindow(self.glb, self) 2550 CallGraphWindow(self.glb, self)
2365 2551
2552 def NewTopCalls(self):
2553 dialog = TopCallsDialog(self.glb, self)
2554 ret = dialog.exec_()
2555 if ret:
2556 TopCallsWindow(self.glb, dialog.report_vars, self)
2557
2366 def NewBranchView(self, event_id): 2558 def NewBranchView(self, event_id):
2367 BranchWindow(self.glb, event_id, "", "", self) 2559 BranchWindow(self.glb, event_id, ReportVars(), self)
2368 2560
2369 def NewSelectedBranchView(self, event_id): 2561 def NewSelectedBranchView(self, event_id):
2370 dialog = SelectedBranchDialog(self.glb, self) 2562 dialog = SelectedBranchDialog(self.glb, self)
2371 ret = dialog.exec_() 2563 ret = dialog.exec_()
2372 if ret: 2564 if ret:
2373 BranchWindow(self.glb, event_id, dialog.name, dialog.where_clause, self) 2565 BranchWindow(self.glb, event_id, dialog.report_vars, self)
2374 2566
2375 def NewTableView(self, table_name): 2567 def NewTableView(self, table_name):
2376 TableWindow(self.glb, table_name, self) 2568 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 @@
5# Displays system-wide failed system call totals, broken down by pid. 5# Displays system-wide failed system call totals, broken down by pid.
6# If a [comm] arg is specified, only syscalls called by [comm] are displayed. 6# If a [comm] arg is specified, only syscalls called by [comm] are displayed.
7 7
8from __future__ import print_function
9
8import os 10import os
9import sys 11import sys
10 12
@@ -32,7 +34,7 @@ if len(sys.argv) > 1:
32syscalls = autodict() 34syscalls = autodict()
33 35
34def trace_begin(): 36def trace_begin():
35 print "Press control+C to stop and show the summary" 37 print("Press control+C to stop and show the summary")
36 38
37def trace_end(): 39def trace_end():
38 print_error_totals() 40 print_error_totals()
@@ -57,22 +59,21 @@ def syscalls__sys_exit(event_name, context, common_cpu,
57 59
58def print_error_totals(): 60def print_error_totals():
59 if for_comm is not None: 61 if for_comm is not None:
60 print "\nsyscall errors for %s:\n\n" % (for_comm), 62 print("\nsyscall errors for %s:\n" % (for_comm))
61 else: 63 else:
62 print "\nsyscall errors:\n\n", 64 print("\nsyscall errors:\n")
63 65
64 print "%-30s %10s\n" % ("comm [pid]", "count"), 66 print("%-30s %10s" % ("comm [pid]", "count"))
65 print "%-30s %10s\n" % ("------------------------------", \ 67 print("%-30s %10s" % ("------------------------------", "----------"))
66 "----------"),
67 68
68 comm_keys = syscalls.keys() 69 comm_keys = syscalls.keys()
69 for comm in comm_keys: 70 for comm in comm_keys:
70 pid_keys = syscalls[comm].keys() 71 pid_keys = syscalls[comm].keys()
71 for pid in pid_keys: 72 for pid in pid_keys:
72 print "\n%s [%d]\n" % (comm, pid), 73 print("\n%s [%d]" % (comm, pid))
73 id_keys = syscalls[comm][pid].keys() 74 id_keys = syscalls[comm][pid].keys()
74 for id in id_keys: 75 for id in id_keys:
75 print " syscall: %-16s\n" % syscall_name(id), 76 print(" syscall: %-16s" % syscall_name(id))
76 ret_keys = syscalls[comm][pid][id].keys() 77 ret_keys = syscalls[comm][pid][id].keys()
77 for ret, val in sorted(syscalls[comm][pid][id].iteritems(), key = lambda(k, v): (v, k), reverse = True): 78 for ret, val in sorted(syscalls[comm][pid][id].items(), key = lambda kv: (kv[1], kv[0]), reverse = True):
78 print " err = %-20s %10d\n" % (strerror(ret), val), 79 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 @@
4# Copyright (c) 2018, Intel Corporation. 4# Copyright (c) 2018, Intel Corporation.
5 5
6from __future__ import division 6from __future__ import division
7from __future__ import print_function
8
7import os 9import os
8import sys 10import sys
9import struct 11import struct
@@ -31,21 +33,23 @@ def parse_iomem():
31 for i, j in enumerate(f): 33 for i, j in enumerate(f):
32 m = re.split('-|:',j,2) 34 m = re.split('-|:',j,2)
33 if m[2].strip() == 'System RAM': 35 if m[2].strip() == 'System RAM':
34 system_ram.append(long(m[0], 16)) 36 system_ram.append(int(m[0], 16))
35 system_ram.append(long(m[1], 16)) 37 system_ram.append(int(m[1], 16))
36 if m[2].strip() == 'Persistent Memory': 38 if m[2].strip() == 'Persistent Memory':
37 pmem.append(long(m[0], 16)) 39 pmem.append(int(m[0], 16))
38 pmem.append(long(m[1], 16)) 40 pmem.append(int(m[1], 16))
39 41
40def print_memory_type(): 42def print_memory_type():
41 print "Event: %s" % (event_name) 43 print("Event: %s" % (event_name))
42 print "%-40s %10s %10s\n" % ("Memory type", "count", "percentage"), 44 print("%-40s %10s %10s\n" % ("Memory type", "count", "percentage"), end='')
43 print "%-40s %10s %10s\n" % ("----------------------------------------", \ 45 print("%-40s %10s %10s\n" % ("----------------------------------------",
44 "-----------", "-----------"), 46 "-----------", "-----------"),
47 end='');
45 total = sum(load_mem_type_cnt.values()) 48 total = sum(load_mem_type_cnt.values())
46 for mem_type, count in sorted(load_mem_type_cnt.most_common(), \ 49 for mem_type, count in sorted(load_mem_type_cnt.most_common(), \
47 key = lambda(k, v): (v, k), reverse = True): 50 key = lambda kv: (kv[1], kv[0]), reverse = True):
48 print "%-40s %10d %10.1f%%\n" % (mem_type, count, 100 * count / total), 51 print("%-40s %10d %10.1f%%\n" % (mem_type, count, 100 * count / total),
52 end='')
49 53
50def trace_begin(): 54def trace_begin():
51 parse_iomem() 55 parse_iomem()
@@ -80,7 +84,7 @@ def find_memory_type(phys_addr):
80 f.seek(0, 0) 84 f.seek(0, 0)
81 for j in f: 85 for j in f:
82 m = re.split('-|:',j,2) 86 m = re.split('-|:',j,2)
83 if long(m[0], 16) <= phys_addr <= long(m[1], 16): 87 if int(m[0], 16) <= phys_addr <= int(m[1], 16):
84 return m[2] 88 return m[2]
85 return "N/A" 89 return "N/A"
86 90
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 @@
1# Monitor the system for dropped packets and proudce a report of drop locations and counts 1# Monitor the system for dropped packets and proudce a report of drop locations and counts
2# SPDX-License-Identifier: GPL-2.0 2# SPDX-License-Identifier: GPL-2.0
3 3
4from __future__ import print_function
5
4import os 6import os
5import sys 7import sys
6 8
@@ -50,19 +52,19 @@ def get_sym(sloc):
50 return (None, 0) 52 return (None, 0)
51 53
52def print_drop_table(): 54def print_drop_table():
53 print "%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT") 55 print("%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT"))
54 for i in drop_log.keys(): 56 for i in drop_log.keys():
55 (sym, off) = get_sym(i) 57 (sym, off) = get_sym(i)
56 if sym == None: 58 if sym == None:
57 sym = i 59 sym = i
58 print "%25s %25s %25s" % (sym, off, drop_log[i]) 60 print("%25s %25s %25s" % (sym, off, drop_log[i]))
59 61
60 62
61def trace_begin(): 63def trace_begin():
62 print "Starting trace (Ctrl-C to dump results)" 64 print("Starting trace (Ctrl-C to dump results)")
63 65
64def trace_end(): 66def trace_end():
65 print "Gathering kallsyms data" 67 print("Gathering kallsyms data")
66 get_kallsyms_table() 68 get_kallsyms_table()
67 print_drop_table() 69 print_drop_table()
68 70
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 @@
8# dev=: show only thing related to specified device 8# dev=: show only thing related to specified device
9# debug: work with debug mode. It shows buffer status. 9# debug: work with debug mode. It shows buffer status.
10 10
11from __future__ import print_function
12
11import os 13import os
12import sys 14import sys
13 15
@@ -17,6 +19,7 @@ sys.path.append(os.environ['PERF_EXEC_PATH'] + \
17from perf_trace_context import * 19from perf_trace_context import *
18from Core import * 20from Core import *
19from Util import * 21from Util import *
22from functools import cmp_to_key
20 23
21all_event_list = []; # insert all tracepoint event related with this script 24all_event_list = []; # insert all tracepoint event related with this script
22irq_dic = {}; # key is cpu and value is a list which stacks irqs 25irq_dic = {}; # key is cpu and value is a list which stacks irqs
@@ -61,12 +64,12 @@ def diff_msec(src, dst):
61def print_transmit(hunk): 64def print_transmit(hunk):
62 if dev != 0 and hunk['dev'].find(dev) < 0: 65 if dev != 0 and hunk['dev'].find(dev) < 0:
63 return 66 return
64 print "%7s %5d %6d.%06dsec %12.3fmsec %12.3fmsec" % \ 67 print("%7s %5d %6d.%06dsec %12.3fmsec %12.3fmsec" %
65 (hunk['dev'], hunk['len'], 68 (hunk['dev'], hunk['len'],
66 nsecs_secs(hunk['queue_t']), 69 nsecs_secs(hunk['queue_t']),
67 nsecs_nsecs(hunk['queue_t'])/1000, 70 nsecs_nsecs(hunk['queue_t'])/1000,
68 diff_msec(hunk['queue_t'], hunk['xmit_t']), 71 diff_msec(hunk['queue_t'], hunk['xmit_t']),
69 diff_msec(hunk['xmit_t'], hunk['free_t'])) 72 diff_msec(hunk['xmit_t'], hunk['free_t'])))
70 73
71# Format for displaying rx packet processing 74# Format for displaying rx packet processing
72PF_IRQ_ENTRY= " irq_entry(+%.3fmsec irq=%d:%s)" 75PF_IRQ_ENTRY= " irq_entry(+%.3fmsec irq=%d:%s)"
@@ -98,55 +101,55 @@ def print_receive(hunk):
98 if show_hunk == 0: 101 if show_hunk == 0:
99 return 102 return
100 103
101 print "%d.%06dsec cpu=%d" % \ 104 print("%d.%06dsec cpu=%d" %
102 (nsecs_secs(base_t), nsecs_nsecs(base_t)/1000, cpu) 105 (nsecs_secs(base_t), nsecs_nsecs(base_t)/1000, cpu))
103 for i in range(len(irq_list)): 106 for i in range(len(irq_list)):
104 print PF_IRQ_ENTRY % \ 107 print(PF_IRQ_ENTRY %
105 (diff_msec(base_t, irq_list[i]['irq_ent_t']), 108 (diff_msec(base_t, irq_list[i]['irq_ent_t']),
106 irq_list[i]['irq'], irq_list[i]['name']) 109 irq_list[i]['irq'], irq_list[i]['name']))
107 print PF_JOINT 110 print(PF_JOINT)
108 irq_event_list = irq_list[i]['event_list'] 111 irq_event_list = irq_list[i]['event_list']
109 for j in range(len(irq_event_list)): 112 for j in range(len(irq_event_list)):
110 irq_event = irq_event_list[j] 113 irq_event = irq_event_list[j]
111 if irq_event['event'] == 'netif_rx': 114 if irq_event['event'] == 'netif_rx':
112 print PF_NET_RX % \ 115 print(PF_NET_RX %
113 (diff_msec(base_t, irq_event['time']), 116 (diff_msec(base_t, irq_event['time']),
114 irq_event['skbaddr']) 117 irq_event['skbaddr']))
115 print PF_JOINT 118 print(PF_JOINT)
116 print PF_SOFT_ENTRY % \ 119 print(PF_SOFT_ENTRY %
117 diff_msec(base_t, hunk['sirq_ent_t']) 120 diff_msec(base_t, hunk['sirq_ent_t']))
118 print PF_JOINT 121 print(PF_JOINT)
119 event_list = hunk['event_list'] 122 event_list = hunk['event_list']
120 for i in range(len(event_list)): 123 for i in range(len(event_list)):
121 event = event_list[i] 124 event = event_list[i]
122 if event['event_name'] == 'napi_poll': 125 if event['event_name'] == 'napi_poll':
123 print PF_NAPI_POLL % \ 126 print(PF_NAPI_POLL %
124 (diff_msec(base_t, event['event_t']), event['dev']) 127 (diff_msec(base_t, event['event_t']), event['dev']))
125 if i == len(event_list) - 1: 128 if i == len(event_list) - 1:
126 print "" 129 print("")
127 else: 130 else:
128 print PF_JOINT 131 print(PF_JOINT)
129 else: 132 else:
130 print PF_NET_RECV % \ 133 print(PF_NET_RECV %
131 (diff_msec(base_t, event['event_t']), event['skbaddr'], 134 (diff_msec(base_t, event['event_t']), event['skbaddr'],
132 event['len']) 135 event['len']))
133 if 'comm' in event.keys(): 136 if 'comm' in event.keys():
134 print PF_WJOINT 137 print(PF_WJOINT)
135 print PF_CPY_DGRAM % \ 138 print(PF_CPY_DGRAM %
136 (diff_msec(base_t, event['comm_t']), 139 (diff_msec(base_t, event['comm_t']),
137 event['pid'], event['comm']) 140 event['pid'], event['comm']))
138 elif 'handle' in event.keys(): 141 elif 'handle' in event.keys():
139 print PF_WJOINT 142 print(PF_WJOINT)
140 if event['handle'] == "kfree_skb": 143 if event['handle'] == "kfree_skb":
141 print PF_KFREE_SKB % \ 144 print(PF_KFREE_SKB %
142 (diff_msec(base_t, 145 (diff_msec(base_t,
143 event['comm_t']), 146 event['comm_t']),
144 event['location']) 147 event['location']))
145 elif event['handle'] == "consume_skb": 148 elif event['handle'] == "consume_skb":
146 print PF_CONS_SKB % \ 149 print(PF_CONS_SKB %
147 diff_msec(base_t, 150 diff_msec(base_t,
148 event['comm_t']) 151 event['comm_t']))
149 print PF_JOINT 152 print(PF_JOINT)
150 153
151def trace_begin(): 154def trace_begin():
152 global show_tx 155 global show_tx
@@ -172,8 +175,7 @@ def trace_begin():
172 175
173def trace_end(): 176def trace_end():
174 # order all events in time 177 # order all events in time
175 all_event_list.sort(lambda a,b :cmp(a[EINFO_IDX_TIME], 178 all_event_list.sort(key=cmp_to_key(lambda a,b :a[EINFO_IDX_TIME] < b[EINFO_IDX_TIME]))
176 b[EINFO_IDX_TIME]))
177 # process all events 179 # process all events
178 for i in range(len(all_event_list)): 180 for i in range(len(all_event_list)):
179 event_info = all_event_list[i] 181 event_info = all_event_list[i]
@@ -210,19 +212,19 @@ def trace_end():
210 print_receive(receive_hunk_list[i]) 212 print_receive(receive_hunk_list[i])
211 # display transmit hunks 213 # display transmit hunks
212 if show_tx: 214 if show_tx:
213 print " dev len Qdisc " \ 215 print(" dev len Qdisc "
214 " netdevice free" 216 " netdevice free")
215 for i in range(len(tx_free_list)): 217 for i in range(len(tx_free_list)):
216 print_transmit(tx_free_list[i]) 218 print_transmit(tx_free_list[i])
217 if debug: 219 if debug:
218 print "debug buffer status" 220 print("debug buffer status")
219 print "----------------------------" 221 print("----------------------------")
220 print "xmit Qdisc:remain:%d overflow:%d" % \ 222 print("xmit Qdisc:remain:%d overflow:%d" %
221 (len(tx_queue_list), of_count_tx_queue_list) 223 (len(tx_queue_list), of_count_tx_queue_list))
222 print "xmit netdevice:remain:%d overflow:%d" % \ 224 print("xmit netdevice:remain:%d overflow:%d" %
223 (len(tx_xmit_list), of_count_tx_xmit_list) 225 (len(tx_xmit_list), of_count_tx_xmit_list))
224 print "receive:remain:%d overflow:%d" % \ 226 print("receive:remain:%d overflow:%d" %
225 (len(rx_skb_list), of_count_rx_skb_list) 227 (len(rx_skb_list), of_count_rx_skb_list))
226 228
227# called from perf, when it finds a correspoinding event 229# called from perf, when it finds a correspoinding event
228def irq__softirq_entry(name, context, cpu, sec, nsec, pid, comm, callchain, vec): 230def 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 @@
4# 4#
5# Hypervisor call statisics 5# Hypervisor call statisics
6 6
7from __future__ import print_function
8
7import os 9import os
8import sys 10import sys
9 11
@@ -149,7 +151,7 @@ hcall_table = {
149} 151}
150 152
151def hcall_table_lookup(opcode): 153def hcall_table_lookup(opcode):
152 if (hcall_table.has_key(opcode)): 154 if (opcode in hcall_table):
153 return hcall_table[opcode] 155 return hcall_table[opcode]
154 else: 156 else:
155 return opcode 157 return opcode
@@ -157,8 +159,8 @@ def hcall_table_lookup(opcode):
157print_ptrn = '%-28s%10s%10s%10s%10s' 159print_ptrn = '%-28s%10s%10s%10s%10s'
158 160
159def trace_end(): 161def trace_end():
160 print print_ptrn % ('hcall', 'count', 'min(ns)', 'max(ns)', 'avg(ns)') 162 print(print_ptrn % ('hcall', 'count', 'min(ns)', 'max(ns)', 'avg(ns)'))
161 print '-' * 68 163 print('-' * 68)
162 for opcode in output: 164 for opcode in output:
163 h_name = hcall_table_lookup(opcode) 165 h_name = hcall_table_lookup(opcode)
164 time = output[opcode]['time'] 166 time = output[opcode]['time']
@@ -166,14 +168,14 @@ def trace_end():
166 min_t = output[opcode]['min'] 168 min_t = output[opcode]['min']
167 max_t = output[opcode]['max'] 169 max_t = output[opcode]['max']
168 170
169 print print_ptrn % (h_name, cnt, min_t, max_t, time/cnt) 171 print(print_ptrn % (h_name, cnt, min_t, max_t, time//cnt))
170 172
171def powerpc__hcall_exit(name, context, cpu, sec, nsec, pid, comm, callchain, 173def powerpc__hcall_exit(name, context, cpu, sec, nsec, pid, comm, callchain,
172 opcode, retval): 174 opcode, retval):
173 if (d_enter.has_key(cpu) and d_enter[cpu].has_key(opcode)): 175 if (cpu in d_enter and opcode in d_enter[cpu]):
174 diff = nsecs(sec, nsec) - d_enter[cpu][opcode] 176 diff = nsecs(sec, nsec) - d_enter[cpu][opcode]
175 177
176 if (output.has_key(opcode)): 178 if (opcode in output):
177 output[opcode]['time'] += diff 179 output[opcode]['time'] += diff
178 output[opcode]['cnt'] += 1 180 output[opcode]['cnt'] += 1
179 if (output[opcode]['min'] > diff): 181 if (output[opcode]['min'] > diff):
@@ -190,11 +192,11 @@ def powerpc__hcall_exit(name, context, cpu, sec, nsec, pid, comm, callchain,
190 192
191 del d_enter[cpu][opcode] 193 del d_enter[cpu][opcode]
192# else: 194# else:
193# print "Can't find matching hcall_enter event. Ignoring sample" 195# print("Can't find matching hcall_enter event. Ignoring sample")
194 196
195def powerpc__hcall_entry(event_name, context, cpu, sec, nsec, pid, comm, 197def powerpc__hcall_entry(event_name, context, cpu, sec, nsec, pid, comm,
196 callchain, opcode): 198 callchain, opcode):
197 if (d_enter.has_key(cpu)): 199 if (cpu in d_enter):
198 d_enter[cpu][opcode] = nsecs(sec, nsec) 200 d_enter[cpu][opcode] = nsecs(sec, nsec)
199 else: 201 else:
200 d_enter[cpu] = {opcode: nsecs(sec, nsec)} 202 d_enter[cpu] = {opcode: nsecs(sec, nsec)}
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 @@
8# will be refreshed every [interval] seconds. The default interval is 8# will be refreshed every [interval] seconds. The default interval is
9# 3 seconds. 9# 3 seconds.
10 10
11import os, sys, thread, time 11from __future__ import print_function
12
13import os, sys, time
14
15try:
16 import thread
17except ImportError:
18 import _thread as thread
12 19
13sys.path.append(os.environ['PERF_EXEC_PATH'] + \ 20sys.path.append(os.environ['PERF_EXEC_PATH'] + \
14 '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') 21 '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
@@ -62,18 +69,19 @@ def print_syscall_totals(interval):
62 while 1: 69 while 1:
63 clear_term() 70 clear_term()
64 if for_comm is not None: 71 if for_comm is not None:
65 print "\nsyscall events for %s:\n\n" % (for_comm), 72 print("\nsyscall events for %s:\n" % (for_comm))
66 else: 73 else:
67 print "\nsyscall events:\n\n", 74 print("\nsyscall events:\n")
68 75
69 print "%-40s %10s\n" % ("event", "count"), 76 print("%-40s %10s" % ("event", "count"))
70 print "%-40s %10s\n" % ("----------------------------------------", \ 77 print("%-40s %10s" %
71 "----------"), 78 ("----------------------------------------",
79 "----------"))
72 80
73 for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \ 81 for id, val in sorted(syscalls.items(), key = lambda kv: (kv[1], kv[0]), \
74 reverse = True): 82 reverse = True):
75 try: 83 try:
76 print "%-40s %10d\n" % (syscall_name(id), val), 84 print("%-40s %10d" % (syscall_name(id), val))
77 except TypeError: 85 except TypeError:
78 pass 86 pass
79 syscalls.clear() 87 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 @@
19# Written by Paolo Bonzini <pbonzini@redhat.com> 19# Written by Paolo Bonzini <pbonzini@redhat.com>
20# Based on Brendan Gregg's stackcollapse-perf.pl script. 20# Based on Brendan Gregg's stackcollapse-perf.pl script.
21 21
22from __future__ import print_function
23
22import os 24import os
23import sys 25import sys
24from collections import defaultdict 26from collections import defaultdict
@@ -120,7 +122,6 @@ def process_event(param_dict):
120 lines[stack_string] = lines[stack_string] + 1 122 lines[stack_string] = lines[stack_string] + 1
121 123
122def trace_end(): 124def trace_end():
123 list = lines.keys() 125 list = sorted(lines)
124 list.sort()
125 for stack in list: 126 for stack in list:
126 print "%s %d" % (stack, lines[stack]) 127 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 a81ad8835a74..01fa933ff3cf 100644
--- a/tools/perf/scripts/python/stat-cpi.py
+++ b/tools/perf/scripts/python/stat-cpi.py
@@ -1,5 +1,7 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2 2
3from __future__ import print_function
4
3data = {} 5data = {}
4times = [] 6times = []
5threads = [] 7threads = []
@@ -19,8 +21,8 @@ def store_key(time, cpu, thread):
19 threads.append(thread) 21 threads.append(thread)
20 22
21def store(time, event, cpu, thread, val, ena, run): 23def store(time, event, cpu, thread, val, ena, run):
22 #print "event %s cpu %d, thread %d, time %d, val %d, ena %d, run %d" % \ 24 #print("event %s cpu %d, thread %d, time %d, val %d, ena %d, run %d" %
23 # (event, cpu, thread, time, val, ena, run) 25 # (event, cpu, thread, time, val, ena, run))
24 26
25 store_key(time, cpu, thread) 27 store_key(time, cpu, thread)
26 key = get_key(time, event, cpu, thread) 28 key = get_key(time, event, cpu, thread)
@@ -58,7 +60,7 @@ def stat__interval(time):
58 if ins != 0: 60 if ins != 0:
59 cpi = cyc/float(ins) 61 cpi = cyc/float(ins)
60 62
61 print "%15f: cpu %d, thread %d -> cpi %f (%d/%d)" % (time/(float(1000000000)), cpu, thread, cpi, cyc, ins) 63 print("%15f: cpu %d, thread %d -> cpi %f (%d/%d)" % (time/(float(1000000000)), cpu, thread, cpi, cyc, ins))
62 64
63def trace_end(): 65def trace_end():
64 pass 66 pass
@@ -74,4 +76,4 @@ def trace_end():
74# if ins != 0: 76# if ins != 0:
75# cpi = cyc/float(ins) 77# cpi = cyc/float(ins)
76# 78#
77# print "time %.9f, cpu %d, thread %d -> cpi %f" % (time/(float(1000000000)), cpu, thread, cpi) 79# 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 @@
5# Displays system-wide system call totals, broken down by syscall. 5# Displays system-wide system call totals, broken down by syscall.
6# If a [comm] arg is specified, only syscalls called by [comm] are displayed. 6# If a [comm] arg is specified, only syscalls called by [comm] are displayed.
7 7
8from __future__ import print_function
9
8import os, sys 10import os, sys
9 11
10sys.path.append(os.environ['PERF_EXEC_PATH'] + \ 12sys.path.append(os.environ['PERF_EXEC_PATH'] + \
@@ -31,7 +33,7 @@ if len(sys.argv) > 1:
31syscalls = autodict() 33syscalls = autodict()
32 34
33def trace_begin(): 35def trace_begin():
34 print "Press control+C to stop and show the summary" 36 print("Press control+C to stop and show the summary")
35 37
36def trace_end(): 38def trace_end():
37 print_syscall_totals() 39 print_syscall_totals()
@@ -55,20 +57,20 @@ def syscalls__sys_enter(event_name, context, common_cpu,
55 57
56def print_syscall_totals(): 58def print_syscall_totals():
57 if for_comm is not None: 59 if for_comm is not None:
58 print "\nsyscall events for %s:\n\n" % (for_comm), 60 print("\nsyscall events for %s:\n" % (for_comm))
59 else: 61 else:
60 print "\nsyscall events by comm/pid:\n\n", 62 print("\nsyscall events by comm/pid:\n")
61 63
62 print "%-40s %10s\n" % ("comm [pid]/syscalls", "count"), 64 print("%-40s %10s" % ("comm [pid]/syscalls", "count"))
63 print "%-40s %10s\n" % ("----------------------------------------", \ 65 print("%-40s %10s" % ("----------------------------------------",
64 "----------"), 66 "----------"))
65 67
66 comm_keys = syscalls.keys() 68 comm_keys = syscalls.keys()
67 for comm in comm_keys: 69 for comm in comm_keys:
68 pid_keys = syscalls[comm].keys() 70 pid_keys = syscalls[comm].keys()
69 for pid in pid_keys: 71 for pid in pid_keys:
70 print "\n%s [%d]\n" % (comm, pid), 72 print("\n%s [%d]" % (comm, pid))
71 id_keys = syscalls[comm][pid].keys() 73 id_keys = syscalls[comm][pid].keys()
72 for id, val in sorted(syscalls[comm][pid].iteritems(), \ 74 for id, val in sorted(syscalls[comm][pid].items(), \
73 key = lambda(k, v): (v, k), reverse = True): 75 key = lambda kv: (kv[1], kv[0]), reverse = True):
74 print " %-38s %10d\n" % (syscall_name(id), val), 76 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 @@
5# Displays system-wide system call totals, broken down by syscall. 5# Displays system-wide system call totals, broken down by syscall.
6# If a [comm] arg is specified, only syscalls called by [comm] are displayed. 6# If a [comm] arg is specified, only syscalls called by [comm] are displayed.
7 7
8from __future__ import print_function
9
8import os 10import os
9import sys 11import sys
10 12
@@ -28,7 +30,7 @@ if len(sys.argv) > 1:
28syscalls = autodict() 30syscalls = autodict()
29 31
30def trace_begin(): 32def trace_begin():
31 print "Press control+C to stop and show the summary" 33 print("Press control+C to stop and show the summary")
32 34
33def trace_end(): 35def trace_end():
34 print_syscall_totals() 36 print_syscall_totals()
@@ -51,14 +53,14 @@ def syscalls__sys_enter(event_name, context, common_cpu,
51 53
52def print_syscall_totals(): 54def print_syscall_totals():
53 if for_comm is not None: 55 if for_comm is not None:
54 print "\nsyscall events for %s:\n\n" % (for_comm), 56 print("\nsyscall events for %s:\n" % (for_comm))
55 else: 57 else:
56 print "\nsyscall events:\n\n", 58 print("\nsyscall events:\n")
57 59
58 print "%-40s %10s\n" % ("event", "count"), 60 print("%-40s %10s" % ("event", "count"))
59 print "%-40s %10s\n" % ("----------------------------------------", \ 61 print("%-40s %10s" % ("----------------------------------------",
60 "-----------"), 62 "-----------"))
61 63
62 for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \ 64 for id, val in sorted(syscalls.items(), key = lambda kv: (kv[1], kv[0]), \
63 reverse = True): 65 reverse = True):
64 print "%-40s %10d\n" % (syscall_name(id), val), 66 print("%-40s %10d" % (syscall_name(id), val))