Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pm-6.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management fixes from Rafael Wysocki:
"These make the intel_pstate driver work as expected on all hybrid
platforms to date (regardless of possible platform firmware issues),
fix hybrid sleep on systems using suspend-to-idle by default, make the
generic power domains code handle disabled idle states properly and
update pm-graph.

Specifics:

- Make intel_pstate use what is known about the hardware instead of
relying on information from the platform firmware (ACPI CPPC in
particular) to establish the relationship between the HWP CPU
performance levels and frequencies on all hybrid platforms
available to date (Rafael Wysocki)

- Allow hybrid sleep to use suspend-to-idle as a system suspend
method if it is the current suspend method of choice (Mario
Limonciello)

- Fix handling of unavailable/disabled idle states in the generic
power domains code (Sudeep Holla)

- Update the pm-graph suite of utilities to version 5.10 which is
fixes-mostly and does not add any new features (Todd Brandt)"

* tag 'pm-6.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
PM: domains: Fix handling of unavailable/disabled idle states
pm-graph v5.10
cpufreq: intel_pstate: hybrid: Use known scaling factor for P-cores
cpufreq: intel_pstate: Read all MSRs on the target CPU
PM: hibernate: Allow hybrid sleep to work with s2idle

+173 -212
+4
drivers/base/power/domain.c
··· 2952 2952 np = it.node; 2953 2953 if (!of_match_node(idle_state_match, np)) 2954 2954 continue; 2955 + 2956 + if (!of_device_is_available(np)) 2957 + continue; 2958 + 2955 2959 if (states) { 2956 2960 ret = genpd_parse_state(&states[i], np); 2957 2961 if (ret) {
+50 -89
drivers/cpufreq/intel_pstate.c
··· 27 27 #include <linux/pm_qos.h> 28 28 #include <trace/events/power.h> 29 29 30 + #include <asm/cpu.h> 30 31 #include <asm/div64.h> 31 32 #include <asm/msr.h> 32 33 #include <asm/cpu_device_id.h> ··· 281 280 * structure is used to store those callbacks. 282 281 */ 283 282 struct pstate_funcs { 284 - int (*get_max)(void); 285 - int (*get_max_physical)(void); 286 - int (*get_min)(void); 287 - int (*get_turbo)(void); 283 + int (*get_max)(int cpu); 284 + int (*get_max_physical)(int cpu); 285 + int (*get_min)(int cpu); 286 + int (*get_turbo)(int cpu); 288 287 int (*get_scaling)(void); 289 288 int (*get_cpu_scaling)(int cpu); 290 289 int (*get_aperf_mperf_shift)(void); ··· 398 397 return cppc_perf.guaranteed_perf; 399 398 400 399 return cppc_perf.nominal_perf; 401 - } 402 - 403 - static u32 intel_pstate_cppc_nominal(int cpu) 404 - { 405 - u64 nominal_perf; 406 - 407 - if (cppc_get_nominal_perf(cpu, &nominal_perf)) 408 - return 0; 409 - 410 - return nominal_perf; 411 400 } 412 401 #else /* CONFIG_ACPI_CPPC_LIB */ 413 402 static inline void intel_pstate_set_itmt_prio(int cpu) ··· 522 531 { 523 532 int perf_ctl_max_phys = cpu->pstate.max_pstate_physical; 524 533 int perf_ctl_scaling = cpu->pstate.perf_ctl_scaling; 525 - int perf_ctl_turbo = pstate_funcs.get_turbo(); 526 - int turbo_freq = perf_ctl_turbo * perf_ctl_scaling; 534 + int perf_ctl_turbo = pstate_funcs.get_turbo(cpu->cpu); 527 535 int scaling = cpu->pstate.scaling; 528 536 529 537 pr_debug("CPU%d: perf_ctl_max_phys = %d\n", cpu->cpu, perf_ctl_max_phys); 530 - pr_debug("CPU%d: perf_ctl_max = %d\n", cpu->cpu, pstate_funcs.get_max()); 531 538 pr_debug("CPU%d: perf_ctl_turbo = %d\n", cpu->cpu, perf_ctl_turbo); 532 539 pr_debug("CPU%d: perf_ctl_scaling = %d\n", cpu->cpu, perf_ctl_scaling); 533 540 pr_debug("CPU%d: HWP_CAP guaranteed = %d\n", cpu->cpu, cpu->pstate.max_pstate); 534 541 pr_debug("CPU%d: HWP_CAP highest = %d\n", cpu->cpu, cpu->pstate.turbo_pstate); 535 542 pr_debug("CPU%d: HWP-to-frequency scaling factor: %d\n", cpu->cpu, scaling); 536 543 537 - /* 538 - * If the product of the HWP performance scaling factor and the HWP_CAP 539 - * highest performance is greater than the maximum turbo frequency 540 - * corresponding to the pstate_funcs.get_turbo() return value, the 541 - * scaling factor is too high, so recompute it to make the HWP_CAP 542 - * highest performance correspond to the maximum turbo frequency. 543 - */ 544 - cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * scaling; 545 - if (turbo_freq < cpu->pstate.turbo_freq) { 546 - cpu->pstate.turbo_freq = turbo_freq; 547 - scaling = DIV_ROUND_UP(turbo_freq, cpu->pstate.turbo_pstate); 548 - cpu->pstate.scaling = scaling; 549 - 550 - pr_debug("CPU%d: refined HWP-to-frequency scaling factor: %d\n", 551 - cpu->cpu, scaling); 552 - } 553 - 544 + cpu->pstate.turbo_freq = rounddown(cpu->pstate.turbo_pstate * scaling, 545 + perf_ctl_scaling); 554 546 cpu->pstate.max_freq = rounddown(cpu->pstate.max_pstate * scaling, 555 547 perf_ctl_scaling); 556 548 ··· 1714 1740 intel_pstate_update_epp_defaults(cpudata); 1715 1741 } 1716 1742 1717 - static int atom_get_min_pstate(void) 1743 + static int atom_get_min_pstate(int not_used) 1718 1744 { 1719 1745 u64 value; 1720 1746 ··· 1722 1748 return (value >> 8) & 0x7F; 1723 1749 } 1724 1750 1725 - static int atom_get_max_pstate(void) 1751 + static int atom_get_max_pstate(int not_used) 1726 1752 { 1727 1753 u64 value; 1728 1754 ··· 1730 1756 return (value >> 16) & 0x7F; 1731 1757 } 1732 1758 1733 - static int atom_get_turbo_pstate(void) 1759 + static int atom_get_turbo_pstate(int not_used) 1734 1760 { 1735 1761 u64 value; 1736 1762 ··· 1808 1834 cpudata->vid.turbo = value & 0x7f; 1809 1835 } 1810 1836 1811 - static int core_get_min_pstate(void) 1837 + static int core_get_min_pstate(int cpu) 1812 1838 { 1813 1839 u64 value; 1814 1840 1815 - rdmsrl(MSR_PLATFORM_INFO, value); 1841 + rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &value); 1816 1842 return (value >> 40) & 0xFF; 1817 1843 } 1818 1844 1819 - static int core_get_max_pstate_physical(void) 1845 + static int core_get_max_pstate_physical(int cpu) 1820 1846 { 1821 1847 u64 value; 1822 1848 1823 - rdmsrl(MSR_PLATFORM_INFO, value); 1849 + rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &value); 1824 1850 return (value >> 8) & 0xFF; 1825 1851 } 1826 1852 1827 - static int core_get_tdp_ratio(u64 plat_info) 1853 + static int core_get_tdp_ratio(int cpu, u64 plat_info) 1828 1854 { 1829 1855 /* Check how many TDP levels present */ 1830 1856 if (plat_info & 0x600000000) { ··· 1834 1860 int err; 1835 1861 1836 1862 /* Get the TDP level (0, 1, 2) to get ratios */ 1837 - err = rdmsrl_safe(MSR_CONFIG_TDP_CONTROL, &tdp_ctrl); 1863 + err = rdmsrl_safe_on_cpu(cpu, MSR_CONFIG_TDP_CONTROL, &tdp_ctrl); 1838 1864 if (err) 1839 1865 return err; 1840 1866 1841 1867 /* TDP MSR are continuous starting at 0x648 */ 1842 1868 tdp_msr = MSR_CONFIG_TDP_NOMINAL + (tdp_ctrl & 0x03); 1843 - err = rdmsrl_safe(tdp_msr, &tdp_ratio); 1869 + err = rdmsrl_safe_on_cpu(cpu, tdp_msr, &tdp_ratio); 1844 1870 if (err) 1845 1871 return err; 1846 1872 ··· 1857 1883 return -ENXIO; 1858 1884 } 1859 1885 1860 - static int core_get_max_pstate(void) 1886 + static int core_get_max_pstate(int cpu) 1861 1887 { 1862 1888 u64 tar; 1863 1889 u64 plat_info; ··· 1865 1891 int tdp_ratio; 1866 1892 int err; 1867 1893 1868 - rdmsrl(MSR_PLATFORM_INFO, plat_info); 1894 + rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &plat_info); 1869 1895 max_pstate = (plat_info >> 8) & 0xFF; 1870 1896 1871 - tdp_ratio = core_get_tdp_ratio(plat_info); 1897 + tdp_ratio = core_get_tdp_ratio(cpu, plat_info); 1872 1898 if (tdp_ratio <= 0) 1873 1899 return max_pstate; 1874 1900 ··· 1877 1903 return tdp_ratio; 1878 1904 } 1879 1905 1880 - err = rdmsrl_safe(MSR_TURBO_ACTIVATION_RATIO, &tar); 1906 + err = rdmsrl_safe_on_cpu(cpu, MSR_TURBO_ACTIVATION_RATIO, &tar); 1881 1907 if (!err) { 1882 1908 int tar_levels; 1883 1909 ··· 1892 1918 return max_pstate; 1893 1919 } 1894 1920 1895 - static int core_get_turbo_pstate(void) 1921 + static int core_get_turbo_pstate(int cpu) 1896 1922 { 1897 1923 u64 value; 1898 1924 int nont, ret; 1899 1925 1900 - rdmsrl(MSR_TURBO_RATIO_LIMIT, value); 1901 - nont = core_get_max_pstate(); 1926 + rdmsrl_on_cpu(cpu, MSR_TURBO_RATIO_LIMIT, &value); 1927 + nont = core_get_max_pstate(cpu); 1902 1928 ret = (value) & 255; 1903 1929 if (ret <= nont) 1904 1930 ret = nont; ··· 1926 1952 return 10; 1927 1953 } 1928 1954 1929 - static int knl_get_turbo_pstate(void) 1955 + static int knl_get_turbo_pstate(int cpu) 1930 1956 { 1931 1957 u64 value; 1932 1958 int nont, ret; 1933 1959 1934 - rdmsrl(MSR_TURBO_RATIO_LIMIT, value); 1935 - nont = core_get_max_pstate(); 1960 + rdmsrl_on_cpu(cpu, MSR_TURBO_RATIO_LIMIT, &value); 1961 + nont = core_get_max_pstate(cpu); 1936 1962 ret = (((value) >> 8) & 0xFF); 1937 1963 if (ret <= nont) 1938 1964 ret = nont; 1939 1965 return ret; 1940 1966 } 1941 1967 1942 - #ifdef CONFIG_ACPI_CPPC_LIB 1943 - static u32 hybrid_ref_perf; 1968 + static void hybrid_get_type(void *data) 1969 + { 1970 + u8 *cpu_type = data; 1971 + 1972 + *cpu_type = get_this_hybrid_cpu_type(); 1973 + } 1944 1974 1945 1975 static int hybrid_get_cpu_scaling(int cpu) 1946 1976 { 1947 - return DIV_ROUND_UP(core_get_scaling() * hybrid_ref_perf, 1948 - intel_pstate_cppc_nominal(cpu)); 1977 + u8 cpu_type = 0; 1978 + 1979 + smp_call_function_single(cpu, hybrid_get_type, &cpu_type, 1); 1980 + /* P-cores have a smaller perf level-to-freqency scaling factor. */ 1981 + if (cpu_type == 0x40) 1982 + return 78741; 1983 + 1984 + return core_get_scaling(); 1949 1985 } 1950 - 1951 - static void intel_pstate_cppc_set_cpu_scaling(void) 1952 - { 1953 - u32 min_nominal_perf = U32_MAX; 1954 - int cpu; 1955 - 1956 - for_each_present_cpu(cpu) { 1957 - u32 nominal_perf = intel_pstate_cppc_nominal(cpu); 1958 - 1959 - if (nominal_perf && nominal_perf < min_nominal_perf) 1960 - min_nominal_perf = nominal_perf; 1961 - } 1962 - 1963 - if (min_nominal_perf < U32_MAX) { 1964 - hybrid_ref_perf = min_nominal_perf; 1965 - pstate_funcs.get_cpu_scaling = hybrid_get_cpu_scaling; 1966 - } 1967 - } 1968 - #else 1969 - static inline void intel_pstate_cppc_set_cpu_scaling(void) 1970 - { 1971 - } 1972 - #endif /* CONFIG_ACPI_CPPC_LIB */ 1973 1986 1974 1987 static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate) 1975 1988 { ··· 1986 2025 1987 2026 static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) 1988 2027 { 1989 - int perf_ctl_max_phys = pstate_funcs.get_max_physical(); 2028 + int perf_ctl_max_phys = pstate_funcs.get_max_physical(cpu->cpu); 1990 2029 int perf_ctl_scaling = pstate_funcs.get_scaling(); 1991 2030 1992 - cpu->pstate.min_pstate = pstate_funcs.get_min(); 2031 + cpu->pstate.min_pstate = pstate_funcs.get_min(cpu->cpu); 1993 2032 cpu->pstate.max_pstate_physical = perf_ctl_max_phys; 1994 2033 cpu->pstate.perf_ctl_scaling = perf_ctl_scaling; 1995 2034 ··· 2005 2044 } 2006 2045 } else { 2007 2046 cpu->pstate.scaling = perf_ctl_scaling; 2008 - cpu->pstate.max_pstate = pstate_funcs.get_max(); 2009 - cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(); 2047 + cpu->pstate.max_pstate = pstate_funcs.get_max(cpu->cpu); 2048 + cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(cpu->cpu); 2010 2049 } 2011 2050 2012 2051 if (cpu->pstate.scaling == perf_ctl_scaling) { ··· 3182 3221 3183 3222 static int __init intel_pstate_msrs_not_valid(void) 3184 3223 { 3185 - if (!pstate_funcs.get_max() || 3186 - !pstate_funcs.get_min() || 3187 - !pstate_funcs.get_turbo()) 3224 + if (!pstate_funcs.get_max(0) || 3225 + !pstate_funcs.get_min(0) || 3226 + !pstate_funcs.get_turbo(0)) 3188 3227 return -ENODEV; 3189 3228 3190 3229 return 0; ··· 3411 3450 default_driver = &intel_pstate; 3412 3451 3413 3452 if (boot_cpu_has(X86_FEATURE_HYBRID_CPU)) 3414 - intel_pstate_cppc_set_cpu_scaling(); 3453 + pstate_funcs.get_cpu_scaling = hybrid_get_cpu_scaling; 3415 3454 3416 3455 goto hwp_cpu_matched; 3417 3456 }
+1 -1
kernel/power/hibernate.c
··· 645 645 int error; 646 646 647 647 if (hibernation_mode == HIBERNATION_SUSPEND) { 648 - error = suspend_devices_and_enter(PM_SUSPEND_MEM); 648 + error = suspend_devices_and_enter(mem_sleep_current); 649 649 if (error) { 650 650 hibernation_mode = hibernation_ops ? 651 651 HIBERNATION_PLATFORM :
+6 -6
tools/power/pm-graph/README
··· 6 6 |_| |___/ |_| 7 7 8 8 pm-graph: suspend/resume/boot timing analysis tools 9 - Version: 5.9 9 + Version: 5.10 10 10 Author: Todd Brandt <todd.e.brandt@intel.com> 11 - Home Page: https://01.org/pm-graph 11 + Home Page: https://www.intel.com/content/www/us/en/developer/topic-technology/open/pm-graph/overview.html 12 12 13 13 Report bugs/issues at bugzilla.kernel.org Tools/pm-graph 14 14 - https://bugzilla.kernel.org/buglist.cgi?component=pm-graph&product=Tools 15 15 16 16 Full documentation available online & in man pages 17 17 - Getting Started: 18 - https://01.org/pm-graph/documentation/getting-started 18 + https://www.intel.com/content/www/us/en/developer/articles/technical/usage.html 19 19 20 - - Config File Format: 21 - https://01.org/pm-graph/documentation/3-config-file-format 20 + - Feature Summary: 21 + https://www.intel.com/content/www/us/en/developer/topic-technology/open/pm-graph/features.html 22 22 23 23 - upstream version in git: 24 - https://github.com/intel/pm-graph/ 24 + git clone https://github.com/intel/pm-graph/ 25 25 26 26 Table of Contents 27 27 - Overview
+3
tools/power/pm-graph/sleepgraph.8
··· 78 78 If a wifi connection is available, check that it reconnects after resume. Include 79 79 the reconnect time in the total resume time calculation and treat wifi timeouts 80 80 as resume failures. 81 + .TP 82 + \fB-wifitrace\fR 83 + Trace through the wifi reconnect time and include it in the timeline. 81 84 82 85 .SS "advanced" 83 86 .TP
+109 -116
tools/power/pm-graph/sleepgraph.py
··· 86 86 # store system values and test parameters 87 87 class SystemValues: 88 88 title = 'SleepGraph' 89 - version = '5.9' 89 + version = '5.10' 90 90 ansi = False 91 91 rs = 0 92 92 display = '' ··· 100 100 ftracelog = False 101 101 acpidebug = True 102 102 tstat = True 103 + wifitrace = False 103 104 mindevlen = 0.0001 104 105 mincglen = 0.0 105 106 cgphase = '' ··· 125 124 epath = '/sys/kernel/debug/tracing/events/power/' 126 125 pmdpath = '/sys/power/pm_debug_messages' 127 126 s0ixpath = '/sys/module/intel_pmc_core/parameters/warn_on_s0ix_failures' 127 + s0ixres = '/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us' 128 128 acpipath='/sys/module/acpi/parameters/debug_level' 129 129 traceevents = [ 130 130 'suspend_resume', ··· 182 180 tmstart = 'SUSPEND START %Y%m%d-%H:%M:%S.%f' 183 181 tmend = 'RESUME COMPLETE %Y%m%d-%H:%M:%S.%f' 184 182 tracefuncs = { 183 + 'async_synchronize_full': {}, 185 184 'sys_sync': {}, 186 185 'ksys_sync': {}, 187 186 '__pm_notifier_call_chain': {}, ··· 307 304 [2, 'suspendstats', 'sh', '-c', 'grep -v invalid /sys/power/suspend_stats/*'], 308 305 [2, 'cpuidle', 'sh', '-c', 'grep -v invalid /sys/devices/system/cpu/cpu*/cpuidle/state*/s2idle/*'], 309 306 [2, 'battery', 'sh', '-c', 'grep -v invalid /sys/class/power_supply/*/*'], 307 + [2, 'thermal', 'sh', '-c', 'grep . /sys/class/thermal/thermal_zone*/temp'], 310 308 ] 311 309 cgblacklist = [] 312 310 kprobes = dict() ··· 781 777 return 782 778 if not quiet: 783 779 sysvals.printSystemInfo(False) 784 - pprint('INITIALIZING FTRACE...') 780 + pprint('INITIALIZING FTRACE') 785 781 # turn trace off 786 782 self.fsetVal('0', 'tracing_on') 787 783 self.cleanupFtrace() ··· 845 841 for name in self.dev_tracefuncs: 846 842 self.defaultKprobe(name, self.dev_tracefuncs[name]) 847 843 if not quiet: 848 - pprint('INITIALIZING KPROBES...') 844 + pprint('INITIALIZING KPROBES') 849 845 self.addKprobes(self.verbose) 850 846 if(self.usetraceevents): 851 847 # turn trace events on ··· 1137 1133 self.cfgdef[file] = fp.read().strip() 1138 1134 fp.write(value) 1139 1135 fp.close() 1136 + def s0ixSupport(self): 1137 + if not os.path.exists(self.s0ixres) or not os.path.exists(self.mempowerfile): 1138 + return False 1139 + fp = open(sysvals.mempowerfile, 'r') 1140 + data = fp.read().strip() 1141 + fp.close() 1142 + if '[s2idle]' in data: 1143 + return True 1144 + return False 1140 1145 def haveTurbostat(self): 1141 1146 if not self.tstat: 1142 1147 return False ··· 1159 1146 self.vprint(out) 1160 1147 return True 1161 1148 return False 1162 - def turbostat(self): 1149 + def turbostat(self, s0ixready): 1163 1150 cmd = self.getExec('turbostat') 1164 1151 rawout = keyline = valline = '' 1165 1152 fullcmd = '%s -q -S echo freeze > %s' % (cmd, self.powerfile) ··· 1186 1173 for key in keyline: 1187 1174 idx = keyline.index(key) 1188 1175 val = valline[idx] 1176 + if key == 'SYS%LPI' and not s0ixready and re.match('^[0\.]*$', val): 1177 + continue 1189 1178 out.append('%s=%s' % (key, val)) 1190 1179 return '|'.join(out) 1191 1180 def netfixon(self, net='both'): ··· 1198 1183 out = ascii(fp.read()).strip() 1199 1184 fp.close() 1200 1185 return out 1201 - def wifiRepair(self): 1202 - out = self.netfixon('wifi') 1203 - if not out or 'error' in out.lower(): 1204 - return '' 1205 - m = re.match('WIFI \S* ONLINE (?P<action>\S*)', out) 1206 - if not m: 1207 - return 'dead' 1208 - return m.group('action') 1209 1186 def wifiDetails(self, dev): 1210 1187 try: 1211 1188 info = open('/sys/class/net/%s/device/uevent' % dev, 'r').read().strip() ··· 1227 1220 return '%s reconnected %.2f' % \ 1228 1221 (self.wifiDetails(dev), max(0, time.time() - start)) 1229 1222 time.sleep(0.01) 1230 - if self.netfix: 1231 - res = self.wifiRepair() 1232 - if res: 1233 - timeout = max(0, time.time() - start) 1234 - return '%s %s %d' % (self.wifiDetails(dev), res, timeout) 1235 1223 return '%s timeout %d' % (self.wifiDetails(dev), timeout) 1236 1224 def errorSummary(self, errinfo, msg): 1237 1225 found = False ··· 1348 1346 for i in self.rslist: 1349 1347 self.setVal(self.rstgt, i) 1350 1348 pprint('runtime suspend settings restored on %d devices' % len(self.rslist)) 1349 + def start(self, pm): 1350 + if self.useftrace: 1351 + self.dlog('start ftrace tracing') 1352 + self.fsetVal('1', 'tracing_on') 1353 + if self.useprocmon: 1354 + self.dlog('start the process monitor') 1355 + pm.start() 1356 + def stop(self, pm): 1357 + if self.useftrace: 1358 + if self.useprocmon: 1359 + self.dlog('stop the process monitor') 1360 + pm.stop() 1361 + self.dlog('stop ftrace tracing') 1362 + self.fsetVal('0', 'tracing_on') 1351 1363 1352 1364 sysvals = SystemValues() 1353 1365 switchvalues = ['enable', 'disable', 'on', 'off', 'true', 'false', '1', '0'] ··· 1659 1643 ubiquitous = False 1660 1644 if kprobename in dtf and 'ub' in dtf[kprobename]: 1661 1645 ubiquitous = True 1662 - title = cdata+' '+rdata 1663 - mstr = '\(.*\) *(?P<args>.*) *\((?P<caller>.*)\+.* arg1=(?P<ret>.*)' 1664 - m = re.match(mstr, title) 1665 - if m: 1666 - c = m.group('caller') 1667 - a = m.group('args').strip() 1668 - r = m.group('ret') 1646 + mc = re.match('\(.*\) *(?P<args>.*)', cdata) 1647 + mr = re.match('\((?P<caller>\S*).* arg1=(?P<ret>.*)', rdata) 1648 + if mc and mr: 1649 + c = mr.group('caller').split('+')[0] 1650 + a = mc.group('args').strip() 1651 + r = mr.group('ret') 1669 1652 if len(r) > 6: 1670 1653 r = '' 1671 1654 else: 1672 1655 r = 'ret=%s ' % r 1673 1656 if ubiquitous and c in dtf and 'ub' in dtf[c]: 1674 1657 return False 1658 + else: 1659 + return False 1675 1660 color = sysvals.kprobeColor(kprobename) 1676 1661 e = DevFunction(displayname, a, c, r, start, end, ubiquitous, proc, pid, color) 1677 1662 tgtdev['src'].append(e) ··· 1789 1772 e.time = self.trimTimeVal(e.time, t0, dT, left) 1790 1773 e.end = self.trimTimeVal(e.end, t0, dT, left) 1791 1774 e.length = e.end - e.time 1775 + if('cpuexec' in d): 1776 + cpuexec = dict() 1777 + for e in d['cpuexec']: 1778 + c0, cN = e 1779 + c0 = self.trimTimeVal(c0, t0, dT, left) 1780 + cN = self.trimTimeVal(cN, t0, dT, left) 1781 + cpuexec[(c0, cN)] = d['cpuexec'][e] 1782 + d['cpuexec'] = cpuexec 1792 1783 for dir in ['suspend', 'resume']: 1793 1784 list = [] 1794 1785 for e in self.errorinfo[dir]: ··· 2111 2086 return d 2112 2087 def addProcessUsageEvent(self, name, times): 2113 2088 # get the start and end times for this process 2114 - maxC = 0 2115 - tlast = 0 2116 - start = -1 2117 - end = -1 2089 + cpuexec = dict() 2090 + tlast = start = end = -1 2118 2091 for t in sorted(times): 2119 - if tlast == 0: 2092 + if tlast < 0: 2120 2093 tlast = t 2121 2094 continue 2122 - if name in self.pstl[t]: 2123 - if start == -1 or tlast < start: 2095 + if name in self.pstl[t] and self.pstl[t][name] > 0: 2096 + if start < 0: 2124 2097 start = tlast 2125 - if end == -1 or t > end: 2126 - end = t 2098 + end, key = t, (tlast, t) 2099 + maxj = (t - tlast) * 1024.0 2100 + cpuexec[key] = min(1.0, float(self.pstl[t][name]) / maxj) 2127 2101 tlast = t 2128 - if start == -1 or end == -1: 2129 - return 0 2102 + if start < 0 or end < 0: 2103 + return 2130 2104 # add a new action for this process and get the object 2131 2105 out = self.newActionGlobal(name, start, end, -3) 2132 - if not out: 2133 - return 0 2134 - phase, devname = out 2135 - dev = self.dmesg[phase]['list'][devname] 2136 - # get the cpu exec data 2137 - tlast = 0 2138 - clast = 0 2139 - cpuexec = dict() 2140 - for t in sorted(times): 2141 - if tlast == 0 or t <= start or t > end: 2142 - tlast = t 2143 - continue 2144 - list = self.pstl[t] 2145 - c = 0 2146 - if name in list: 2147 - c = list[name] 2148 - if c > maxC: 2149 - maxC = c 2150 - if c != clast: 2151 - key = (tlast, t) 2152 - cpuexec[key] = c 2153 - tlast = t 2154 - clast = c 2155 - dev['cpuexec'] = cpuexec 2156 - return maxC 2106 + if out: 2107 + phase, devname = out 2108 + dev = self.dmesg[phase]['list'][devname] 2109 + dev['cpuexec'] = cpuexec 2157 2110 def createProcessUsageEvents(self): 2158 - # get an array of process names 2159 - proclist = [] 2111 + # get an array of process names and times 2112 + proclist = {'sus': dict(), 'res': dict()} 2113 + tdata = {'sus': [], 'res': []} 2160 2114 for t in sorted(self.pstl): 2161 - pslist = self.pstl[t] 2162 - for ps in sorted(pslist): 2163 - if ps not in proclist: 2164 - proclist.append(ps) 2165 - # get a list of data points for suspend and resume 2166 - tsus = [] 2167 - tres = [] 2168 - for t in sorted(self.pstl): 2169 - if t < self.tSuspended: 2170 - tsus.append(t) 2171 - else: 2172 - tres.append(t) 2115 + dir = 'sus' if t < self.tSuspended else 'res' 2116 + for ps in sorted(self.pstl[t]): 2117 + if ps not in proclist[dir]: 2118 + proclist[dir][ps] = 0 2119 + tdata[dir].append(t) 2173 2120 # process the events for suspend and resume 2174 - if len(proclist) > 0: 2121 + if len(proclist['sus']) > 0 or len(proclist['res']) > 0: 2175 2122 sysvals.vprint('Process Execution:') 2176 - for ps in proclist: 2177 - c = self.addProcessUsageEvent(ps, tsus) 2178 - if c > 0: 2179 - sysvals.vprint('%25s (sus): %d' % (ps, c)) 2180 - c = self.addProcessUsageEvent(ps, tres) 2181 - if c > 0: 2182 - sysvals.vprint('%25s (res): %d' % (ps, c)) 2123 + for dir in ['sus', 'res']: 2124 + for ps in sorted(proclist[dir]): 2125 + self.addProcessUsageEvent(ps, tdata[dir]) 2183 2126 def handleEndMarker(self, time, msg=''): 2184 2127 dm = self.dmesg 2185 2128 self.setEnd(time, msg) ··· 3211 3218 # markers, and/or kprobes required for primary parsing. 3212 3219 def doesTraceLogHaveTraceEvents(): 3213 3220 kpcheck = ['_cal: (', '_ret: ('] 3214 - techeck = ['suspend_resume', 'device_pm_callback'] 3221 + techeck = ['suspend_resume', 'device_pm_callback', 'tracing_mark_write'] 3215 3222 tmcheck = ['SUSPEND START', 'RESUME COMPLETE'] 3216 3223 sysvals.usekprobes = False 3217 3224 fp = sysvals.openlog(sysvals.ftracefile, 'r') ··· 3234 3241 check.remove(i) 3235 3242 tmcheck = check 3236 3243 fp.close() 3237 - sysvals.usetraceevents = True if len(techeck) < 2 else False 3244 + sysvals.usetraceevents = True if len(techeck) < 3 else False 3238 3245 sysvals.usetracemarkers = True if len(tmcheck) == 0 else False 3239 3246 3240 3247 # Function: appendIncompleteTraceLog ··· 3449 3456 continue 3450 3457 # process cpu exec line 3451 3458 if t.type == 'tracing_mark_write': 3459 + if t.name == 'CMD COMPLETE' and data.tKernRes == 0: 3460 + data.tKernRes = t.time 3452 3461 m = re.match(tp.procexecfmt, t.name) 3453 3462 if(m): 3454 3463 parts, msg = 1, m.group('ps') ··· 3668 3673 continue 3669 3674 e = next((x for x in reversed(tp.ktemp[key]) if x['end'] < 0), 0) 3670 3675 if not e: 3676 + continue 3677 + if (t.time - e['begin']) * 1000 < sysvals.mindevlen: 3678 + tp.ktemp[key].pop() 3671 3679 continue 3672 3680 e['end'] = t.time 3673 3681 e['rdata'] = kprobedata ··· 4211 4213 fmt = '<n>(%.3f ms @ '+sv.timeformat+')</n>' 4212 4214 flen = fmt % (line.length*1000, line.time) 4213 4215 if line.isLeaf(): 4216 + if line.length * 1000 < sv.mincglen: 4217 + continue 4214 4218 hf.write(html_func_leaf.format(line.name, flen)) 4215 4219 elif line.freturn: 4216 4220 hf.write(html_func_end) ··· 4827 4827 if('cpuexec' in dev): 4828 4828 for t in sorted(dev['cpuexec']): 4829 4829 start, end = t 4830 - j = float(dev['cpuexec'][t]) / 5 4831 - if j > 1.0: 4832 - j = 1.0 4833 4830 height = '%.3f' % (rowheight/3) 4834 4831 top = '%.3f' % (rowtop + devtl.scaleH + 2*rowheight/3) 4835 4832 left = '%f' % (((start-m0)*100)/mTotal) 4836 4833 width = '%f' % ((end-start)*100/mTotal) 4837 - color = 'rgba(255, 0, 0, %f)' % j 4834 + color = 'rgba(255, 0, 0, %f)' % dev['cpuexec'][t] 4838 4835 devtl.html += \ 4839 4836 html_cpuexec.format(left, top, height, width, color) 4840 4837 if('src' not in dev): ··· 5450 5453 call('sync', shell=True) 5451 5454 sv.dlog('read dmesg') 5452 5455 sv.initdmesg() 5453 - # start ftrace 5454 - if sv.useftrace: 5455 - if not quiet: 5456 - pprint('START TRACING') 5457 - sv.dlog('start ftrace tracing') 5458 - sv.fsetVal('1', 'tracing_on') 5459 - if sv.useprocmon: 5460 - sv.dlog('start the process monitor') 5461 - pm.start() 5462 - sv.dlog('run the cmdinfo list before') 5456 + sv.dlog('cmdinfo before') 5463 5457 sv.cmdinfo(True) 5458 + sv.start(pm) 5464 5459 # execute however many s/r runs requested 5465 5460 for count in range(1,sv.execcount+1): 5466 5461 # x2delay in between test runs ··· 5489 5500 if res != 0: 5490 5501 tdata['error'] = 'cmd returned %d' % res 5491 5502 else: 5503 + s0ixready = sv.s0ixSupport() 5492 5504 mode = sv.suspendmode 5493 5505 if sv.memmode and os.path.exists(sv.mempowerfile): 5494 5506 mode = 'mem' ··· 5499 5509 sv.testVal(sv.diskpowerfile, 'radio', sv.diskmode) 5500 5510 if sv.acpidebug: 5501 5511 sv.testVal(sv.acpipath, 'acpi', '0xe') 5502 - if mode == 'freeze' and sv.haveTurbostat(): 5512 + if ((mode == 'freeze') or (sv.memmode == 's2idle')) \ 5513 + and sv.haveTurbostat(): 5503 5514 # execution will pause here 5504 - turbo = sv.turbostat() 5515 + turbo = sv.turbostat(s0ixready) 5505 5516 if turbo: 5506 5517 tdata['turbo'] = turbo 5507 5518 else: ··· 5513 5522 pf.close() 5514 5523 except Exception as e: 5515 5524 tdata['error'] = str(e) 5516 - sv.dlog('system returned from resume') 5525 + sv.fsetVal('CMD COMPLETE', 'trace_marker') 5526 + sv.dlog('system returned') 5517 5527 # reset everything 5518 5528 sv.testVal('restoreall') 5519 5529 if(sv.rtcwake): ··· 5527 5535 sv.fsetVal('WAIT END', 'trace_marker') 5528 5536 # return from suspend 5529 5537 pprint('RESUME COMPLETE') 5530 - sv.fsetVal(datetime.now().strftime(sv.tmend), 'trace_marker') 5538 + if(count < sv.execcount): 5539 + sv.fsetVal(datetime.now().strftime(sv.tmend), 'trace_marker') 5540 + elif(not sv.wifitrace): 5541 + sv.fsetVal(datetime.now().strftime(sv.tmend), 'trace_marker') 5542 + sv.stop(pm) 5531 5543 if sv.wifi and wifi: 5532 5544 tdata['wifi'] = sv.pollWifi(wifi) 5533 5545 sv.dlog('wifi check, %s' % tdata['wifi']) 5534 - if sv.netfix: 5535 - netfixout = sv.netfixon('wired') 5536 - elif sv.netfix: 5537 - netfixout = sv.netfixon() 5538 - if sv.netfix and netfixout: 5539 - tdata['netfix'] = netfixout 5546 + if(count == sv.execcount and sv.wifitrace): 5547 + sv.fsetVal(datetime.now().strftime(sv.tmend), 'trace_marker') 5548 + sv.stop(pm) 5549 + if sv.netfix: 5550 + tdata['netfix'] = sv.netfixon() 5540 5551 sv.dlog('netfix, %s' % tdata['netfix']) 5541 5552 if(sv.suspendmode == 'mem' or sv.suspendmode == 'command'): 5542 5553 sv.dlog('read the ACPI FPDT') 5543 5554 tdata['fw'] = getFPDT(False) 5544 5555 testdata.append(tdata) 5545 - sv.dlog('run the cmdinfo list after') 5556 + sv.dlog('cmdinfo after') 5546 5557 cmdafter = sv.cmdinfo(False) 5547 - # stop ftrace 5548 - if sv.useftrace: 5549 - if sv.useprocmon: 5550 - sv.dlog('stop the process monitor') 5551 - pm.stop() 5552 - sv.fsetVal('0', 'tracing_on') 5553 5558 # grab a copy of the dmesg output 5554 5559 if not quiet: 5555 5560 pprint('CAPTURING DMESG') 5556 - sysvals.dlog('EXECUTION TRACE END') 5557 5561 sv.getdmesg(testdata) 5558 5562 # grab a copy of the ftrace output 5559 5563 if sv.useftrace: ··· 6338 6350 if not m: 6339 6351 continue 6340 6352 name, time, phase = m.group('n'), m.group('t'), m.group('p') 6353 + if name == 'async_synchronize_full': 6354 + continue 6341 6355 if ' async' in name or ' sync' in name: 6342 6356 name = ' '.join(name.split(' ')[:-1]) 6343 6357 if phase.startswith('suspend'): ··· 6691 6701 ' -skiphtml Run the test and capture the trace logs, but skip the timeline (default: disabled)\n'\ 6692 6702 ' -result fn Export a results table to a text file for parsing.\n'\ 6693 6703 ' -wifi If a wifi connection is available, check that it reconnects after resume.\n'\ 6704 + ' -wifitrace Trace kernel execution through wifi reconnect.\n'\ 6694 6705 ' -netfix Use netfix to reset the network in the event it fails to resume.\n'\ 6695 6706 ' [testprep]\n'\ 6696 6707 ' -sync Sync the filesystems before starting the test\n'\ ··· 6819 6828 sysvals.sync = True 6820 6829 elif(arg == '-wifi'): 6821 6830 sysvals.wifi = True 6831 + elif(arg == '-wifitrace'): 6832 + sysvals.wifitrace = True 6822 6833 elif(arg == '-netfix'): 6823 6834 sysvals.netfix = True 6824 6835 elif(arg == '-gzip'):