summaryrefslogtreecommitdiff
path: root/tools/power
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-04-25 18:44:10 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2023-04-25 18:44:10 -0700
commit0cfd8703e7da687924371e9bc77a025bdeba9637 (patch)
treeb1cbcd250948e3cc9ea6a9f813535fc07c70efe6 /tools/power
parent793582ff47f8b73be8d3d925d750bf3ef79f33c7 (diff)
parentd3f2c402e44887e507b65d65f0d0515d46575bf5 (diff)
Merge tag 'pm-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael Wysocki: "These update several cpufreq drivers and the cpufreq core, add sysfs interface for exposing the time really spent in the platform low-power state during suspend-to-idle, update devfreq (core and drivers) and the pm-graph suite of tools and clean up code. Specifics: - Fix the frequency unit in cpufreq_verify_current_freq checks() Sanjay Chandrashekara) - Make mode_state_machine in amd-pstate static (Tom Rix) - Make the cpufreq core require drivers with target_index() to set freq_table (Viresh Kumar) - Fix typo in the ARM_BRCMSTB_AVS_CPUFREQ Kconfig entry (Jingyu Wang) - Use of_property_read_bool() for boolean properties in the pmac32 cpufreq driver (Rob Herring) - Make the cpufreq sysfs interface return proper error codes on obviously invalid input (qinyu) - Add guided autonomous mode support to the AMD P-state driver (Wyes Karny) - Make the Intel P-state driver enable HWP IO boost on all server platforms (Srinivas Pandruvada) - Add opp and bandwidth support to tegra194 cpufreq driver (Sumit Gupta) - Use of_property_present() for testing DT property presence (Rob Herring) - Remove MODULE_LICENSE in non-modules (Nick Alcock) - Add SM7225 to cpufreq-dt-platdev blocklist (Luca Weiss) - Optimizations and fixes for qcom-cpufreq-hw driver (Krzysztof Kozlowski, Konrad Dybcio, and Bjorn Andersson) - DT binding updates for qcom-cpufreq-hw driver (Konrad Dybcio and Bartosz Golaszewski) - Updates and fixes for mediatek driver (Jia-Wei Chang and AngeloGioacchino Del Regno) - Use of_property_present() for testing DT property presence in the cpuidle code (Rob Herring) - Drop unnecessary (void *) conversions from the PM core (Li zeming) - Add sysfs files to represent time spent in a platform sleep state during suspend-to-idle and make AMD and Intel PMC drivers use them Mario Limonciello) - Use of_property_present() for testing DT property presence (Rob Herring) - Add set_required_opps() callback to the 'struct opp_table', to make the code paths cleaner (Viresh Kumar) - Update the pm-graph siute of utilities to v5.11 with the following changes: * New script which allows users to install the latest pm-graph from the upstream github repo. * Update all the dmesg suspend/resume PM print formats to be able to process recent timelines using dmesg only. * Add ethtool output to the log for the system's ethernet device if ethtool exists. * Make the tool more robustly handle events where mangled dmesg or ftrace outputs do not include all the requisite data. - Make the sleepgraph utility recognize "CPU killed" messages (Xueqin Luo) - Remove unneeded SRCU selection in Kconfig because it's always set from devfreq core (Paul E. McKenney) - Drop of_match_ptr() macro from exynos-bus.c because this driver is always using the DT table for driver probe (Krzysztof Kozlowski) - Use the preferred of_property_present() instead of the low-level of_get_property() on exynos-bus.c (Rob Herring) - Use devm_platform_get_and_ioream_resource() in exyno-ppmu.c (Yang Li)" * tag 'pm-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (44 commits) platform/x86/intel/pmc: core: Report duration of time in HW sleep state platform/x86/intel/pmc: core: Always capture counters on suspend platform/x86/amd: pmc: Report duration of time in hw sleep state PM: Add sysfs files to represent time spent in hardware sleep state cpufreq: use correct unit when verify cur freq cpufreq: tegra194: add OPP support and set bandwidth cpufreq: amd-pstate: Make varaiable mode_state_machine static PM: core: Remove unnecessary (void *) conversions cpufreq: drivers with target_index() must set freq_table PM / devfreq: exynos-ppmu: Use devm_platform_get_and_ioremap_resource() OPP: Move required opps configuration to specialized callback OPP: Handle all genpd cases together in _set_required_opps() cpufreq: qcom-cpufreq-hw: Revert adding cpufreq qos dt-bindings: cpufreq: cpufreq-qcom-hw: Add QCM2290 dt-bindings: cpufreq: cpufreq-qcom-hw: Sanitize data per compatible dt-bindings: cpufreq: cpufreq-qcom-hw: Allow just 1 frequency domain cpufreq: Add SM7225 to cpufreq-dt-platdev blocklist cpufreq: qcom-cpufreq-hw: fix double IO unmap and resource release on exit cpufreq: mediatek: Raise proc and sram max voltage for MT7622/7623 cpufreq: mediatek: raise proc/sram max voltage for MT8516 ...
Diffstat (limited to 'tools/power')
-rw-r--r--tools/power/pm-graph/README2
-rwxr-xr-xtools/power/pm-graph/install_latest_from_github.sh38
-rwxr-xr-xtools/power/pm-graph/sleepgraph.py58
3 files changed, 79 insertions, 19 deletions
diff --git a/tools/power/pm-graph/README b/tools/power/pm-graph/README
index 3213dbe63b74..047ce1d76467 100644
--- a/tools/power/pm-graph/README
+++ b/tools/power/pm-graph/README
@@ -6,7 +6,7 @@
|_| |___/ |_|
pm-graph: suspend/resume/boot timing analysis tools
- Version: 5.10
+ Version: 5.11
Author: Todd Brandt <todd.e.brandt@intel.com>
Home Page: https://www.intel.com/content/www/us/en/developer/topic-technology/open/pm-graph/overview.html
diff --git a/tools/power/pm-graph/install_latest_from_github.sh b/tools/power/pm-graph/install_latest_from_github.sh
new file mode 100755
index 000000000000..eaa332399d36
--- /dev/null
+++ b/tools/power/pm-graph/install_latest_from_github.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Script which clones and installs the latest pm-graph
+# from http://github.com/intel/pm-graph.git
+
+OUT=`mktemp -d 2>/dev/null`
+if [ -z "$OUT" -o ! -e $OUT ]; then
+ echo "ERROR: mktemp failed to create folder"
+ exit
+fi
+
+cleanup() {
+ if [ -e "$OUT" ]; then
+ cd $OUT
+ rm -rf pm-graph
+ cd /tmp
+ rmdir $OUT
+ fi
+}
+
+git clone http://github.com/intel/pm-graph.git $OUT/pm-graph
+if [ ! -e "$OUT/pm-graph/sleepgraph.py" ]; then
+ echo "ERROR: pm-graph github repo failed to clone"
+ cleanup
+ exit
+fi
+
+cd $OUT/pm-graph
+echo "INSTALLING PM-GRAPH"
+sudo make install
+if [ $? -eq 0 ]; then
+ echo "INSTALL SUCCESS"
+ sleepgraph -v
+else
+ echo "INSTALL FAILED"
+fi
+cleanup
diff --git a/tools/power/pm-graph/sleepgraph.py b/tools/power/pm-graph/sleepgraph.py
index bf4ac24a1c7a..4a356a706785 100755
--- a/tools/power/pm-graph/sleepgraph.py
+++ b/tools/power/pm-graph/sleepgraph.py
@@ -86,7 +86,7 @@ def ascii(text):
# store system values and test parameters
class SystemValues:
title = 'SleepGraph'
- version = '5.10'
+ version = '5.11'
ansi = False
rs = 0
display = ''
@@ -300,6 +300,7 @@ class SystemValues:
[0, 'acpidevices', 'sh', '-c', 'ls -l /sys/bus/acpi/devices/*/physical_node'],
[0, 's0ix_require', 'cat', '/sys/kernel/debug/pmc_core/substate_requirements'],
[0, 's0ix_debug', 'cat', '/sys/kernel/debug/pmc_core/slp_s0_debug_status'],
+ [0, 'ethtool', 'ethtool', '{ethdev}'],
[1, 's0ix_residency', 'cat', '/sys/kernel/debug/pmc_core/slp_s0_residency_usec'],
[1, 'interrupts', 'cat', '/proc/interrupts'],
[1, 'wakeups', 'cat', '/sys/kernel/debug/wakeup_sources'],
@@ -1078,18 +1079,35 @@ class SystemValues:
else:
out[data[0].strip()] = data[1]
return out
+ def cmdinfovar(self, arg):
+ if arg == 'ethdev':
+ try:
+ cmd = [self.getExec('ip'), '-4', '-o', '-br', 'addr']
+ fp = Popen(cmd, stdout=PIPE, stderr=PIPE).stdout
+ info = ascii(fp.read()).strip()
+ fp.close()
+ except:
+ return 'iptoolcrash'
+ for line in info.split('\n'):
+ if line[0] == 'e' and 'UP' in line:
+ return line.split()[0]
+ return 'nodevicefound'
+ return 'unknown'
def cmdinfo(self, begin, debug=False):
out = []
if begin:
self.cmd1 = dict()
for cargs in self.infocmds:
- delta, name = cargs[0], cargs[1]
- cmdline, cmdpath = ' '.join(cargs[2:]), self.getExec(cargs[2])
+ delta, name, args = cargs[0], cargs[1], cargs[2:]
+ for i in range(len(args)):
+ if args[i][0] == '{' and args[i][-1] == '}':
+ args[i] = self.cmdinfovar(args[i][1:-1])
+ cmdline, cmdpath = ' '.join(args[0:]), self.getExec(args[0])
if not cmdpath or (begin and not delta):
continue
self.dlog('[%s]' % cmdline)
try:
- fp = Popen([cmdpath]+cargs[3:], stdout=PIPE, stderr=PIPE).stdout
+ fp = Popen([cmdpath]+args[1:], stdout=PIPE, stderr=PIPE).stdout
info = ascii(fp.read()).strip()
fp.close()
except:
@@ -1452,6 +1470,7 @@ class Data:
errlist = {
'HWERROR' : r'.*\[ *Hardware Error *\].*',
'FWBUG' : r'.*\[ *Firmware Bug *\].*',
+ 'TASKFAIL': r'.*Freezing .*after *.*',
'BUG' : r'(?i).*\bBUG\b.*',
'ERROR' : r'(?i).*\bERROR\b.*',
'WARNING' : r'(?i).*\bWARNING\b.*',
@@ -1462,7 +1481,6 @@ class Data:
'TIMEOUT' : r'(?i).*\bTIMEOUT\b.*',
'ABORT' : r'(?i).*\bABORT\b.*',
'IRQ' : r'.*\bgenirq: .*',
- 'TASKFAIL': r'.*Freezing .*after *.*',
'ACPI' : r'.*\bACPI *(?P<b>[A-Za-z]*) *Error[: ].*',
'DISKFULL': r'.*\bNo space left on device.*',
'USBERR' : r'.*usb .*device .*, error [0-9-]*',
@@ -1602,7 +1620,7 @@ class Data:
pend = self.dmesg[phase]['end']
if start <= pend:
return phase
- return 'resume_complete'
+ return 'resume_complete' if 'resume_complete' in self.dmesg else ''
def sourceDevice(self, phaselist, start, end, pid, type):
tgtdev = ''
for phase in phaselist:
@@ -1645,6 +1663,8 @@ class Data:
else:
threadname = '%s-%d' % (proc, pid)
tgtphase = self.sourcePhase(start)
+ if not tgtphase:
+ return False
self.newAction(tgtphase, threadname, pid, '', start, end, '', ' kth', '')
return self.addDeviceFunctionCall(displayname, kprobename, proc, pid, start, end, cdata, rdata)
# this should not happen
@@ -1835,9 +1855,9 @@ class Data:
hwr = self.hwend - timedelta(microseconds=rtime)
self.tLow.append('%.0f'%((hwr - hws).total_seconds() * 1000))
def getTimeValues(self):
- sktime = (self.tSuspended - self.tKernSus) * 1000
- rktime = (self.tKernRes - self.tResumed) * 1000
- return (sktime, rktime)
+ s = (self.tSuspended - self.tKernSus) * 1000
+ r = (self.tKernRes - self.tResumed) * 1000
+ return (max(s, 0), max(r, 0))
def setPhase(self, phase, ktime, isbegin, order=-1):
if(isbegin):
# phase start over current phase
@@ -3961,7 +3981,7 @@ def parseKernelLog(data):
'suspend_machine': ['PM: suspend-to-idle',
'PM: noirq suspend of devices complete after.*',
'PM: noirq freeze of devices complete after.*'],
- 'resume_machine': ['PM: Timekeeping suspended for.*',
+ 'resume_machine': ['[PM: ]*Timekeeping suspended for.*',
'ACPI: Low-level resume complete.*',
'ACPI: resume from mwait',
'Suspended for [0-9\.]* seconds'],
@@ -3979,14 +3999,14 @@ def parseKernelLog(data):
# action table (expected events that occur and show up in dmesg)
at = {
'sync_filesystems': {
- 'smsg': 'PM: Syncing filesystems.*',
- 'emsg': 'PM: Preparing system for mem sleep.*' },
+ 'smsg': '.*[Ff]+ilesystems.*',
+ 'emsg': 'PM: Preparing system for[a-z]* sleep.*' },
'freeze_user_processes': {
- 'smsg': 'Freezing user space processes .*',
+ 'smsg': 'Freezing user space processes.*',
'emsg': 'Freezing remaining freezable tasks.*' },
'freeze_tasks': {
'smsg': 'Freezing remaining freezable tasks.*',
- 'emsg': 'PM: Entering (?P<mode>[a-z,A-Z]*) sleep.*' },
+ 'emsg': 'PM: Suspending system.*' },
'ACPI prepare': {
'smsg': 'ACPI: Preparing to enter system sleep state.*',
'emsg': 'PM: Saving platform NVS memory.*' },
@@ -4120,10 +4140,9 @@ def parseKernelLog(data):
for a in sorted(at):
if(re.match(at[a]['smsg'], msg)):
if(a not in actions):
- actions[a] = []
- actions[a].append({'begin': ktime, 'end': ktime})
+ actions[a] = [{'begin': ktime, 'end': ktime}]
if(re.match(at[a]['emsg'], msg)):
- if(a in actions):
+ if(a in actions and actions[a][-1]['begin'] == actions[a][-1]['end']):
actions[a][-1]['end'] = ktime
# now look for CPU on/off events
if(re.match('Disabling non-boot CPUs .*', msg)):
@@ -4132,9 +4151,12 @@ def parseKernelLog(data):
elif(re.match('Enabling non-boot CPUs .*', msg)):
# start of first cpu resume
cpu_start = ktime
- elif(re.match('smpboot: CPU (?P<cpu>[0-9]*) is now offline', msg)):
+ elif(re.match('smpboot: CPU (?P<cpu>[0-9]*) is now offline', msg)) \
+ or re.match('psci: CPU(?P<cpu>[0-9]*) killed.*', msg)):
# end of a cpu suspend, start of the next
m = re.match('smpboot: CPU (?P<cpu>[0-9]*) is now offline', msg)
+ if(not m):
+ m = re.match('psci: CPU(?P<cpu>[0-9]*) killed.*', msg)
cpu = 'CPU'+m.group('cpu')
if(cpu not in actions):
actions[cpu] = []