From 11e1a1648298656722fe206a53e555e2e98668ae Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 3 Jul 2019 15:03:14 +0530 Subject: [PATCH 01/15] opp: Don't decrement uninitialized list_kref The list_kref was added for static OPPs and to track their users. The kref is initialized while the static OPPs are added, but removed unconditionally even if the static OPPs were never added. This causes refcount mismatch warnings currently. Fix that by always initializing the kref when the OPP table is first initialized. The refcount is later incremented only for the second user onwards. Fixes: d0e8ae6c26da ("OPP: Create separate kref for static OPPs list") Reported-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- drivers/opp/core.c | 1 + drivers/opp/of.c | 21 ++++----------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 0ee8c0133d3e..9ff0538ee83a 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -988,6 +988,7 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index) BLOCKING_INIT_NOTIFIER_HEAD(&opp_table->head); INIT_LIST_HEAD(&opp_table->opp_list); kref_init(&opp_table->kref); + kref_init(&opp_table->list_kref); /* Secure the device table modification */ list_add(&opp_table->node, &opp_tables); diff --git a/drivers/opp/of.c b/drivers/opp/of.c index b313aca9894f..698a92c3c17b 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -662,8 +662,6 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table) return 0; } - kref_init(&opp_table->list_kref); - /* We have opp-table node now, iterate over it and add OPPs */ for_each_available_child_of_node(opp_table->np, np) { opp = _opp_add_static_v2(opp_table, dev, np); @@ -672,17 +670,15 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table) dev_err(dev, "%s: Failed to add OPP, %d\n", __func__, ret); of_node_put(np); - goto put_list_kref; + return ret; } else if (opp) { count++; } } /* There should be one of more OPP defined */ - if (WARN_ON(!count)) { - ret = -ENOENT; - goto put_list_kref; - } + if (WARN_ON(!count)) + return -ENOENT; list_for_each_entry(opp, &opp_table->opp_list, node) pstate_count += !!opp->pstate; @@ -691,8 +687,7 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table) if (pstate_count && pstate_count != count) { dev_err(dev, "Not all nodes have performance state set (%d: %d)\n", count, pstate_count); - ret = -ENOENT; - goto put_list_kref; + return -ENOENT; } if (pstate_count) @@ -701,11 +696,6 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table) opp_table->parsed_static_opps = true; return 0; - -put_list_kref: - _put_opp_list_kref(opp_table); - - return ret; } /* Initializes OPP tables based on old-deprecated bindings */ @@ -731,8 +721,6 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table) return -EINVAL; } - kref_init(&opp_table->list_kref); - val = prop->value; while (nr) { unsigned long freq = be32_to_cpup(val++) * 1000; @@ -742,7 +730,6 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table) if (ret) { dev_err(dev, "%s: Failed to add OPP %ld (%d)\n", __func__, freq, ret); - _put_opp_list_kref(opp_table); return ret; } nr -= 2; From 7f93ff73f7c8c8bfa6be33bcc16470b0b44682aa Mon Sep 17 00:00:00 2001 From: "k.konieczny@partner.samsung.com" Date: Fri, 19 Jul 2019 17:05:32 +0200 Subject: [PATCH 02/15] opp: core: add regulators enable and disable Add enable regulators to dev_pm_opp_set_regulators() and disable regulators to dev_pm_opp_put_regulators(). Even if bootloader leaves regulators enabled, they should be enabled in kernel in order to increase the reference count. Signed-off-by: Kamil Konieczny Signed-off-by: Viresh Kumar --- drivers/opp/core.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 9ff0538ee83a..3b7ffd0234e9 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -1626,6 +1626,12 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev, goto free_regulators; } + ret = regulator_enable(reg); + if (ret < 0) { + regulator_put(reg); + goto free_regulators; + } + opp_table->regulators[i] = reg; } @@ -1639,8 +1645,10 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev, return opp_table; free_regulators: - while (i != 0) - regulator_put(opp_table->regulators[--i]); + while (i--) { + regulator_disable(opp_table->regulators[i]); + regulator_put(opp_table->regulators[i]); + } kfree(opp_table->regulators); opp_table->regulators = NULL; @@ -1666,8 +1674,10 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table) /* Make sure there are no concurrent readers while updating opp_table */ WARN_ON(!list_empty(&opp_table->opp_list)); - for (i = opp_table->regulator_count - 1; i >= 0; i--) + for (i = opp_table->regulator_count - 1; i >= 0; i--) { + regulator_disable(opp_table->regulators[i]); regulator_put(opp_table->regulators[i]); + } _free_set_opp_data(opp_table); From 518c6880ffc965d59349bf064ff00153cf05f033 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Tue, 9 Jul 2019 16:00:12 +0800 Subject: [PATCH 03/15] dt-bindings: opp: Support multiple opp-suspend properties Update opp-suspend property's description to support multiple opp-suspend properties defined in DT, the OPP with highest opp-hz and with opp-suspend property present will be used as suspend opp. Signed-off-by: Anson Huang Reviewed-by: Rob Herring Signed-off-by: Viresh Kumar --- Documentation/devicetree/bindings/opp/opp.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/opp/opp.txt b/Documentation/devicetree/bindings/opp/opp.txt index 76b6c79604a5..68592271461f 100644 --- a/Documentation/devicetree/bindings/opp/opp.txt +++ b/Documentation/devicetree/bindings/opp/opp.txt @@ -140,8 +140,8 @@ Optional properties: frequency for a short duration of time limited by the device's power, current and thermal limits. -- opp-suspend: Marks the OPP to be used during device suspend. Only one OPP in - the table should have this. +- opp-suspend: Marks the OPP to be used during device suspend. If multiple OPPs + in the table have this, the OPP with highest opp-hz will be used. - opp-supported-hw: This enables us to select only a subset of OPPs from the larger OPP table, based on what version of the hardware we are running on. We From 4527551750e85f9be9296f2b30b19bb257f342e5 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Tue, 9 Jul 2019 16:00:13 +0800 Subject: [PATCH 04/15] opp: of: Support multiple suspend OPPs defined in DT With property "opp-supported-hw" introduced, the OPP table in DT could be a large OPP table and ONLY a subset of OPPs are available, based on the version of the hardware running on. That introduces restriction of using "opp-suspend" property to define the suspend OPP, as we are NOT sure if the OPP containing "opp-suspend" property is available for the hardware running on, and the of opp core does NOT allow multiple suspend OPPs defined in DT OPP table. To eliminate this restrition, make of opp core allow multiple suspend OPPs defined in DT, and pick the OPP with highest rate and with "opp-suspend" property present to be suspend OPP, it can speed up the suspend/resume process. Signed-off-by: Anson Huang Signed-off-by: Viresh Kumar --- drivers/opp/of.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 698a92c3c17b..1813f5ad5fa2 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -617,9 +617,12 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table, /* OPP to select on device suspend */ if (of_property_read_bool(np, "opp-suspend")) { if (opp_table->suspend_opp) { - dev_warn(dev, "%s: Multiple suspend OPPs found (%lu %lu)\n", - __func__, opp_table->suspend_opp->rate, - new_opp->rate); + /* Pick the OPP with higher rate as suspend OPP */ + if (new_opp->rate > opp_table->suspend_opp->rate) { + opp_table->suspend_opp->suspend = false; + new_opp->suspend = true; + opp_table->suspend_opp = new_opp; + } } else { new_opp->suspend = true; opp_table->suspend_opp = new_opp; From 27a84f76738cc4a9509ec9234a7021de34a88e58 Mon Sep 17 00:00:00 2001 From: Yue Hu Date: Fri, 26 Jul 2019 14:07:47 +0800 Subject: [PATCH 05/15] PM / OPP: Correct Documentation about library location OPP library is now located in drivers/opp/ directory. Signed-off-by: Yue Hu Signed-off-by: Viresh Kumar --- Documentation/power/opp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/power/opp.rst b/Documentation/power/opp.rst index b3cf1def9dee..209c7613f5a4 100644 --- a/Documentation/power/opp.rst +++ b/Documentation/power/opp.rst @@ -46,7 +46,7 @@ We can represent these as three OPPs as the following {Hz, uV} tuples: ---------------------------------------- OPP library provides a set of helper functions to organize and query the OPP -information. The library is located in drivers/base/power/opp.c and the header +information. The library is located in drivers/opp/ directory and the header is located in include/linux/pm_opp.h. OPP library can be enabled by enabling CONFIG_PM_OPP from power management menuconfig menu. OPP library depends on CONFIG_PM as certain SoCs such as Texas Instrument's OMAP framework allows to From 0d1e16c640ee67dcae65ae8e3c6f58e6d8101047 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 16 Jul 2019 11:43:20 +0200 Subject: [PATCH 06/15] PM / Domains: Align in-parameter names for some genpd functions Align in-parameter names for the declarations of pm_genpd_add| remove_subdomain() and of_genpd_add_subdomain() according to their implementations, as to improve consistency. Signed-off-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 91d9bf497071..baf02ff91a31 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -197,9 +197,9 @@ static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev) int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev); int pm_genpd_remove_device(struct device *dev); int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, - struct generic_pm_domain *new_subdomain); + struct generic_pm_domain *subdomain); int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, - struct generic_pm_domain *target); + struct generic_pm_domain *subdomain); int pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off); int pm_genpd_remove(struct generic_pm_domain *genpd); @@ -226,12 +226,12 @@ static inline int pm_genpd_remove_device(struct device *dev) return -ENOSYS; } static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, - struct generic_pm_domain *new_sd) + struct generic_pm_domain *subdomain) { return -ENOSYS; } static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, - struct generic_pm_domain *target) + struct generic_pm_domain *subdomain) { return -ENOSYS; } @@ -282,8 +282,8 @@ int of_genpd_add_provider_onecell(struct device_node *np, struct genpd_onecell_data *data); void of_genpd_del_provider(struct device_node *np); int of_genpd_add_device(struct of_phandle_args *args, struct device *dev); -int of_genpd_add_subdomain(struct of_phandle_args *parent, - struct of_phandle_args *new_subdomain); +int of_genpd_add_subdomain(struct of_phandle_args *parent_spec, + struct of_phandle_args *subdomain_spec); struct generic_pm_domain *of_genpd_remove_last(struct device_node *np); int of_genpd_parse_idle_states(struct device_node *dn, struct genpd_power_state **states, int *n); @@ -316,8 +316,8 @@ static inline int of_genpd_add_device(struct of_phandle_args *args, return -ENODEV; } -static inline int of_genpd_add_subdomain(struct of_phandle_args *parent, - struct of_phandle_args *new_subdomain) +static inline int of_genpd_add_subdomain(struct of_phandle_args *parent_spec, + struct of_phandle_args *subdomain_spec) { return -ENODEV; } From ee8193ee96c7802b5ba766243c4c950059a43323 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Aug 2019 12:26:02 +0200 Subject: [PATCH 07/15] ACPI: PM: Print debug messages on device power state changes Add an acpi_handle_debug() statement to acpi_device_set_power() to allow ACPI device power state changes to be tracked. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index f616b16c1f0b..4cb93d4f2ab6 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -166,6 +166,10 @@ int acpi_device_set_power(struct acpi_device *device, int state) || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) return -EINVAL; + acpi_handle_debug(device->handle, "Power state change: %s -> %s\n", + acpi_power_state_string(device->power.state), + acpi_power_state_string(state)); + /* Make sure this is a valid target state */ /* There is a special case for D0 addressed below. */ From 1446794a89c13816bd526dcbff4051cac9743db7 Mon Sep 17 00:00:00 2001 From: Todd Brandt Date: Mon, 12 Aug 2019 14:08:44 -0700 Subject: [PATCH 08/15] pm-graph v5.5 Upgrade bootgraph/sleepgraph to be able to run on python2 and python3. Both now simply require python, the system can choose which to use. bootgraph python3 update: - add floor function to handle integer arithmetic - change argument loop to use next() instead of args.next() - open dmesg log and popen in binary, use decode(ascii, ignore) - sort all html data to allow diff between python versions - change exception handler to use python3 as instead of comma sleepgraph python3 update: - import configparser not ConfigParser (p2 needs python-configparser) - add floor function to handle integer arithmetic - change argument loop to use next() instead of args.next() - handle popen output in binary, use decode(ascii, ignore) - sort all html/output data to allow diff between python versions - force gzip open to use text mode, same for file open - ensure no binary data is written to logs (ascii convert devprops info) - use codecs library to handle zlib encoding for mcelog data - remove all uses of python3.7 keyword "async" as members or vars - assume all FPDT and DMI data is in binary string form sleepgraph: - turbostat will be used by default if it's found & the mode is freeze - a new option "-noturbostat" will disable its use - fix bug where two callgraphs with the same start time overwrite. - fix s2idle processing where two suspend/resume_machines occur back2back - update getexec function to use which first (assuming PATH exists) - new platforminfo data in log with: lspci, gpe counts, /proc/interrupts - new data is zipped, b64 encoded, and tacked on the end of ftrace Signed-off-by: Todd Brandt Signed-off-by: Rafael J. Wysocki --- tools/power/pm-graph/README | 6 +- tools/power/pm-graph/bootgraph.py | 59 ++- tools/power/pm-graph/sleepgraph.8 | 8 +- tools/power/pm-graph/sleepgraph.py | 610 ++++++++++++++++------------- 4 files changed, 387 insertions(+), 296 deletions(-) diff --git a/tools/power/pm-graph/README b/tools/power/pm-graph/README index 58a5591e3951..96259f6e5715 100644 --- a/tools/power/pm-graph/README +++ b/tools/power/pm-graph/README @@ -1,7 +1,7 @@ p m - g r a p h pm-graph: suspend/resume/boot timing analysis tools - Version: 5.4 + Version: 5.5 Author: Todd Brandt Home Page: https://01.org/pm-graph @@ -18,6 +18,10 @@ - upstream version in git: https://github.com/intel/pm-graph/ + Requirements: + - runs with python2 or python3, choice is made by /usr/bin/python link + - python2 now requires python-configparser be installed + Table of Contents - Overview - Setup diff --git a/tools/power/pm-graph/bootgraph.py b/tools/power/pm-graph/bootgraph.py index 666bcbda648d..d3b99a1e92d6 100755 --- a/tools/power/pm-graph/bootgraph.py +++ b/tools/power/pm-graph/bootgraph.py @@ -1,9 +1,18 @@ -#!/usr/bin/python2 +#!/usr/bin/python # SPDX-License-Identifier: GPL-2.0-only # # Tool for analyzing boot timing # Copyright (c) 2013, Intel Corporation. # +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# # Authors: # Todd Brandt # @@ -81,7 +90,7 @@ class SystemValues(aslib.SystemValues): cmdline = 'initcall_debug log_buf_len=32M' if self.useftrace: if self.cpucount > 0: - bs = min(self.memtotal / 2, 2*1024*1024) / self.cpucount + bs = min(self.memtotal // 2, 2*1024*1024) // self.cpucount else: bs = 131072 cmdline += ' trace_buf_size=%dK trace_clock=global '\ @@ -137,13 +146,13 @@ class SystemValues(aslib.SystemValues): if arg in ['-h', '-v', '-cronjob', '-reboot', '-verbose']: continue elif arg in ['-o', '-dmesg', '-ftrace', '-func']: - args.next() + next(args) continue elif arg == '-result': - cmdline += ' %s "%s"' % (arg, os.path.abspath(args.next())) + cmdline += ' %s "%s"' % (arg, os.path.abspath(next(args))) continue elif arg == '-cgskip': - file = self.configFile(args.next()) + file = self.configFile(next(args)) cmdline += ' %s "%s"' % (arg, os.path.abspath(file)) continue cmdline += ' '+arg @@ -292,11 +301,11 @@ def parseKernelLog(): tp = aslib.TestProps() devtemp = dict() if(sysvals.dmesgfile): - lf = open(sysvals.dmesgfile, 'r') + lf = open(sysvals.dmesgfile, 'rb') else: lf = Popen('dmesg', stdout=PIPE).stdout for line in lf: - line = line.replace('\r\n', '') + line = aslib.ascii(line).replace('\r\n', '') # grab the stamp and sysinfo if re.match(tp.stampfmt, line): tp.stamp = line @@ -649,7 +658,7 @@ def createBootGraph(data): statinfo += '\t"%s": [\n\t\t"%s",\n' % (n, devstats[n]['info']) if 'fstat' in devstats[n]: funcs = devstats[n]['fstat'] - for f in sorted(funcs, key=funcs.get, reverse=True): + for f in sorted(funcs, key=lambda k:(funcs[k], k), reverse=True): if funcs[f][0] < 0.01 and len(funcs) > 10: break statinfo += '\t\t"%f|%s|%d",\n' % (funcs[f][0], f, funcs[f][1]) @@ -729,7 +738,7 @@ def updateCron(restore=False): op.write('@reboot python %s\n' % sysvals.cronjobCmdString()) op.close() res = call([cmd, cronfile]) - except Exception, e: + except Exception as e: pprint('Exception: %s' % str(e)) shutil.move(backfile, cronfile) res = -1 @@ -745,7 +754,7 @@ def updateGrub(restore=False): try: call(sysvals.blexec, stderr=PIPE, stdout=PIPE, env={'PATH': '.:/sbin:/usr/sbin:/usr/bin:/sbin:/bin'}) - except Exception, e: + except Exception as e: pprint('Exception: %s\n' % str(e)) return # extract the option and create a grub config without it @@ -792,7 +801,7 @@ def updateGrub(restore=False): op.close() res = call(sysvals.blexec) os.remove(grubfile) - except Exception, e: + except Exception as e: pprint('Exception: %s' % str(e)) res = -1 # cleanup @@ -866,6 +875,7 @@ def printHelp(): 'Other commands:\n'\ ' -flistall Print all functions capable of being captured in ftrace\n'\ ' -sysinfo Print out system info extracted from BIOS\n'\ + ' -which exec Print an executable path, should function even without PATH\n'\ ' [redo]\n'\ ' -dmesg file Create HTML output using dmesg input (used with -ftrace)\n'\ ' -ftrace file Create HTML output using ftrace input (used with -dmesg)\n'\ @@ -907,13 +917,13 @@ if __name__ == '__main__': sysvals.mincglen = aslib.getArgFloat('-mincg', args, 0.0, 10000.0) elif(arg == '-cgfilter'): try: - val = args.next() + val = next(args) except: doError('No callgraph functions supplied', True) sysvals.setCallgraphFilter(val) elif(arg == '-cgskip'): try: - val = args.next() + val = next(args) except: doError('No file supplied', True) if val.lower() in switchoff: @@ -924,7 +934,7 @@ if __name__ == '__main__': doError('%s does not exist' % cgskip) elif(arg == '-bl'): try: - val = args.next() + val = next(args) except: doError('No boot loader name supplied', True) if val.lower() not in ['grub']: @@ -937,7 +947,7 @@ if __name__ == '__main__': sysvals.max_graph_depth = aslib.getArgInt('-maxdepth', args, 0, 1000) elif(arg == '-func'): try: - val = args.next() + val = next(args) except: doError('No filter functions supplied', True) sysvals.useftrace = True @@ -946,7 +956,7 @@ if __name__ == '__main__': sysvals.setGraphFilter(val) elif(arg == '-ftrace'): try: - val = args.next() + val = next(args) except: doError('No ftrace file supplied', True) if(os.path.exists(val) == False): @@ -959,7 +969,7 @@ if __name__ == '__main__': sysvals.cgexp = True elif(arg == '-dmesg'): try: - val = args.next() + val = next(args) except: doError('No dmesg file supplied', True) if(os.path.exists(val) == False): @@ -968,13 +978,13 @@ if __name__ == '__main__': sysvals.dmesgfile = val elif(arg == '-o'): try: - val = args.next() + val = next(args) except: doError('No subdirectory name supplied', True) sysvals.testdir = sysvals.setOutputFolder(val) elif(arg == '-result'): try: - val = args.next() + val = next(args) except: doError('No result file supplied', True) sysvals.result = val @@ -986,6 +996,17 @@ if __name__ == '__main__': # remaining options are only for cron job use elif(arg == '-cronjob'): sysvals.iscronjob = True + elif(arg == '-which'): + try: + val = next(args) + except: + doError('No executable supplied', True) + out = sysvals.getExec(val) + if not out: + print('%s not found' % val) + sys.exit(1) + print(out) + sys.exit(0) else: doError('Invalid argument: '+arg, True) diff --git a/tools/power/pm-graph/sleepgraph.8 b/tools/power/pm-graph/sleepgraph.8 index 9648be644d5f..43aee64316df 100644 --- a/tools/power/pm-graph/sleepgraph.8 +++ b/tools/power/pm-graph/sleepgraph.8 @@ -53,10 +53,10 @@ disable rtcwake and require a user keypress to resume. Add the dmesg and ftrace logs to the html output. They will be viewable by clicking buttons in the timeline. .TP -\fB-turbostat\fR -Use turbostat to execute the command in freeze mode (default: disabled). This -will provide turbostat output in the log which will tell you which actual -power modes were entered. +\fB-noturbostat\fR +By default, if turbostat is found and the requested mode is freeze, sleepgraph +will execute the suspend via turbostat and collect data in the timeline log. +This option disables the use of turbostat. .TP \fB-result \fIfile\fR Export a results table to a text file for parsing. diff --git a/tools/power/pm-graph/sleepgraph.py b/tools/power/pm-graph/sleepgraph.py index 4f46a7a1feb6..1794c79a7d1b 100755 --- a/tools/power/pm-graph/sleepgraph.py +++ b/tools/power/pm-graph/sleepgraph.py @@ -1,9 +1,18 @@ -#!/usr/bin/python2 +#!/usr/bin/python # SPDX-License-Identifier: GPL-2.0-only # # Tool for analyzing suspend/resume timing # Copyright (c) 2013, Intel Corporation. # +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# # Authors: # Todd Brandt # @@ -48,9 +57,10 @@ import string import re import platform import signal +import codecs from datetime import datetime import struct -import ConfigParser +import configparser import gzip from threading import Thread from subprocess import call, Popen, PIPE @@ -60,6 +70,9 @@ def pprint(msg): print(msg) sys.stdout.flush() +def ascii(text): + return text.decode('ascii', 'ignore') + # ----------------- CLASSES -------------------- # Class: SystemValues @@ -68,7 +81,7 @@ def pprint(msg): # store system values and test parameters class SystemValues: title = 'SleepGraph' - version = '5.4' + version = '5.5' ansi = False rs = 0 display = '' @@ -78,7 +91,7 @@ class SystemValues: testlog = True dmesglog = True ftracelog = False - tstat = False + tstat = True mindevlen = 0.0 mincglen = 0.0 cgphase = '' @@ -147,6 +160,7 @@ class SystemValues: devdump = False mixedphaseheight = True devprops = dict() + platinfo = [] predelay = 0 postdelay = 0 pmdebug = '' @@ -323,13 +337,20 @@ class SystemValues: sys.exit(1) return False def getExec(self, cmd): - dirlist = ['/sbin', '/bin', '/usr/sbin', '/usr/bin', - '/usr/local/sbin', '/usr/local/bin'] - for path in dirlist: + try: + fp = Popen(['which', cmd], stdout=PIPE, stderr=PIPE).stdout + out = ascii(fp.read()).strip() + fp.close() + except: + out = '' + if out: + return out + for path in ['/sbin', '/bin', '/usr/sbin', '/usr/bin', + '/usr/local/sbin', '/usr/local/bin']: cmdfull = os.path.join(path, cmd) if os.path.exists(cmdfull): return cmdfull - return '' + return out def setPrecision(self, num): if num < 0 or num > 6: return @@ -455,7 +476,7 @@ class SystemValues: fp = Popen('dmesg', stdout=PIPE).stdout ktime = '0' for line in fp: - line = line.replace('\r\n', '') + line = ascii(line).replace('\r\n', '') idx = line.find('[') if idx > 1: line = line[idx:] @@ -469,7 +490,7 @@ class SystemValues: # store all new dmesg lines since initdmesg was called fp = Popen('dmesg', stdout=PIPE).stdout for line in fp: - line = line.replace('\r\n', '') + line = ascii(line).replace('\r\n', '') idx = line.find('[') if idx > 1: line = line[idx:] @@ -501,7 +522,7 @@ class SystemValues: call('cat '+self.tpath+'available_filter_functions', shell=True) return master = self.listFromFile(self.tpath+'available_filter_functions') - for i in self.tracefuncs: + for i in sorted(self.tracefuncs): if 'func' in self.tracefuncs[i]: i = self.tracefuncs[i]['func'] if i in master: @@ -628,7 +649,7 @@ class SystemValues: self.fsetVal(kprobeevents, 'kprobe_events') if output: check = self.fgetVal('kprobe_events') - linesack = (len(check.split('\n')) - 1) / 2 + linesack = (len(check.split('\n')) - 1) // 2 pprint(' kprobe functions enabled: %d/%d' % (linesack, linesout)) self.fsetVal('1', 'events/kprobes/enable') def testKprobe(self, kname, kprobe): @@ -650,7 +671,7 @@ class SystemValues: if not os.path.exists(file): return False try: - fp = open(file, mode, 0) + fp = open(file, mode) fp.write(val) fp.flush() fp.close() @@ -719,7 +740,7 @@ class SystemValues: tgtsize = min(self.memfree, bmax) else: tgtsize = 65536 - while not self.fsetVal('%d' % (tgtsize / cpus), 'buffer_size_kb'): + while not self.fsetVal('%d' % (tgtsize // cpus), 'buffer_size_kb'): # if the size failed to set, lower it and keep trying tgtsize -= 65536 if tgtsize < 65536: @@ -863,14 +884,23 @@ class SystemValues: isgz = self.gzip if mode == 'r': try: - with gzip.open(filename, mode+'b') as fp: + with gzip.open(filename, mode+'t') as fp: test = fp.read(64) isgz = True except: isgz = False if isgz: - return gzip.open(filename, mode+'b') + return gzip.open(filename, mode+'t') return open(filename, mode) + def b64unzip(self, data): + try: + out = codecs.decode(base64.b64decode(data), 'zlib').decode() + except: + out = data + return out + def b64zip(self, data): + out = base64.b64encode(codecs.encode(data.encode(), 'zlib')).decode() + return out def mcelog(self, clear=False): cmd = self.getExec('mcelog') if not cmd: @@ -878,12 +908,124 @@ class SystemValues: if clear: call(cmd+' > /dev/null 2>&1', shell=True) return '' - fp = Popen([cmd], stdout=PIPE, stderr=PIPE).stdout - out = fp.read().strip() - fp.close() + try: + fp = Popen([cmd], stdout=PIPE, stderr=PIPE).stdout + out = ascii(fp.read()).strip() + fp.close() + except: + return '' if not out: return '' - return base64.b64encode(out.encode('zlib')) + return self.b64zip(out) + def platforminfo(self): + # add platform info on to a completed ftrace file + if not os.path.exists(self.ftracefile): + return False + footer = '#\n' + + # add test command string line if need be + if self.suspendmode == 'command' and self.testcommand: + footer += '# platform-testcmd: %s\n' % (self.testcommand) + + # get a list of target devices from the ftrace file + props = dict() + tp = TestProps() + tf = self.openlog(self.ftracefile, 'r') + for line in tf: + # determine the trace data type (required for further parsing) + m = re.match(tp.tracertypefmt, line) + if(m): + tp.setTracerType(m.group('t')) + continue + # parse only valid lines, if this is not one move on + m = re.match(tp.ftrace_line_fmt, line) + if(not m or 'device_pm_callback_start' not in line): + continue + m = re.match('.*: (?P.*) (?P.*), parent: *(?P

.*), .*', m.group('msg')); + if(not m): + continue + dev = m.group('d') + if dev not in props: + props[dev] = DevProps() + tf.close() + + # now get the syspath for each target device + for dirname, dirnames, filenames in os.walk('/sys/devices'): + if(re.match('.*/power', dirname) and 'async' in filenames): + dev = dirname.split('/')[-2] + if dev in props and (not props[dev].syspath or len(dirname) < len(props[dev].syspath)): + props[dev].syspath = dirname[:-6] + + # now fill in the properties for our target devices + for dev in sorted(props): + dirname = props[dev].syspath + if not dirname or not os.path.exists(dirname): + continue + with open(dirname+'/power/async') as fp: + text = fp.read() + props[dev].isasync = False + if 'enabled' in text: + props[dev].isasync = True + fields = os.listdir(dirname) + if 'product' in fields: + with open(dirname+'/product', 'rb') as fp: + props[dev].altname = ascii(fp.read()) + elif 'name' in fields: + with open(dirname+'/name', 'rb') as fp: + props[dev].altname = ascii(fp.read()) + elif 'model' in fields: + with open(dirname+'/model', 'rb') as fp: + props[dev].altname = ascii(fp.read()) + elif 'description' in fields: + with open(dirname+'/description', 'rb') as fp: + props[dev].altname = ascii(fp.read()) + elif 'id' in fields: + with open(dirname+'/id', 'rb') as fp: + props[dev].altname = ascii(fp.read()) + elif 'idVendor' in fields and 'idProduct' in fields: + idv, idp = '', '' + with open(dirname+'/idVendor', 'rb') as fp: + idv = ascii(fp.read()).strip() + with open(dirname+'/idProduct', 'rb') as fp: + idp = ascii(fp.read()).strip() + props[dev].altname = '%s:%s' % (idv, idp) + if props[dev].altname: + out = props[dev].altname.strip().replace('\n', ' ')\ + .replace(',', ' ').replace(';', ' ') + props[dev].altname = out + + # add a devinfo line to the bottom of ftrace + out = '' + for dev in sorted(props): + out += props[dev].out(dev) + footer += '# platform-devinfo: %s\n' % self.b64zip(out) + + # add a line for each of these commands with their outputs + cmds = [ + ['pcidevices', 'lspci', '-tv'], + ['interrupts', 'cat', '/proc/interrupts'], + ['gpecounts', 'sh', '-c', 'grep -v invalid /sys/firmware/acpi/interrupts/gpe*'], + ] + for cargs in cmds: + name = cargs[0] + cmdline = ' '.join(cargs[1:]) + cmdpath = self.getExec(cargs[1]) + if not cmdpath: + continue + cmd = [cmdpath] + cargs[2:] + try: + fp = Popen(cmd, stdout=PIPE, stderr=PIPE).stdout + info = ascii(fp.read()).strip() + fp.close() + except: + continue + if not info: + continue + footer += '# platform-%s: %s | %s\n' % (name, cmdline, self.b64zip(info)) + + with self.openlog(self.ftracefile, 'a') as fp: + fp.write(footer) + return True def haveTurbostat(self): if not self.tstat: return False @@ -891,31 +1033,40 @@ class SystemValues: if not cmd: return False fp = Popen([cmd, '-v'], stdout=PIPE, stderr=PIPE).stderr - out = fp.read().strip() + out = ascii(fp.read()).strip() fp.close() - return re.match('turbostat version [0-9\.]* .*', out) + if re.match('turbostat version [0-9\.]* .*', out): + sysvals.vprint(out) + return True + return False def turbostat(self): cmd = self.getExec('turbostat') - if not cmd: - return 'missing turbostat executable' - text = [] + rawout = keyline = valline = '' fullcmd = '%s -q -S echo freeze > %s' % (cmd, self.powerfile) fp = Popen(['sh', '-c', fullcmd], stdout=PIPE, stderr=PIPE).stderr for line in fp: - if re.match('[0-9.]* sec', line): + line = ascii(line) + rawout += line + if keyline and valline: continue - text.append(line.split()) + if re.match('(?i)Avg_MHz.*', line): + keyline = line.strip().split() + elif keyline: + valline = line.strip().split() fp.close() - if len(text) < 2: - return 'turbostat output format error' + if not keyline or not valline or len(keyline) != len(valline): + errmsg = 'unrecognized turbostat output:\n'+rawout.strip() + sysvals.vprint(errmsg) + if not sysvals.verbose: + pprint(errmsg) + return '' + if sysvals.verbose: + pprint(rawout.strip()) out = [] - for key in text[0]: - values = [] - idx = text[0].index(key) - for line in text[1:]: - if len(line) > idx: - values.append(line[idx]) - out.append('%s=%s' % (key, ','.join(values))) + for key in keyline: + idx = keyline.index(key) + val = valline[idx] + out.append('%s=%s' % (key, val)) return '|'.join(out) def checkWifi(self): out = dict() @@ -924,7 +1075,7 @@ class SystemValues: return out fp = Popen(iwcmd, stdout=PIPE, stderr=PIPE).stdout for line in fp: - m = re.match('(?P\S*) .* ESSID:(?P\S*)', line) + m = re.match('(?P\S*) .* ESSID:(?P\S*)', ascii(line)) if not m: continue out['device'] = m.group('dev') @@ -935,7 +1086,7 @@ class SystemValues: if 'device' in out: fp = Popen([ifcmd, out['device']], stdout=PIPE, stderr=PIPE).stdout for line in fp: - m = re.match('.* inet (?P[0-9\.]*)', line) + m = re.match('.* inet (?P[0-9\.]*)', ascii(line)) if m: out['ip'] = m.group('ip') break @@ -990,13 +1141,13 @@ class DevProps: def __init__(self): self.syspath = '' self.altname = '' - self.async = True + self.isasync = True self.xtraclass = '' self.xtrainfo = '' def out(self, dev): - return '%s,%s,%d;' % (dev, self.altname, self.async) + return '%s,%s,%d;' % (dev, self.altname, self.isasync) def debug(self, dev): - pprint('%s:\n\taltname = %s\n\t async = %s' % (dev, self.altname, self.async)) + pprint('%s:\n\taltname = %s\n\t async = %s' % (dev, self.altname, self.isasync)) def altName(self, dev): if not self.altname or self.altname == dev: return dev @@ -1004,13 +1155,13 @@ class DevProps: def xtraClass(self): if self.xtraclass: return ' '+self.xtraclass - if not self.async: + if not self.isasync: return ' sync' return '' def xtraInfo(self): if self.xtraclass: return ' '+self.xtraclass - if self.async: + if self.isasync: return ' async_device' return ' sync_device' @@ -1108,7 +1259,7 @@ class Data: return sorted(self.dmesg, key=lambda k:self.dmesg[k]['order']) def initDevicegroups(self): # called when phases are all finished being added - for phase in self.dmesg.keys(): + for phase in sorted(self.dmesg.keys()): if '*' in phase: p = phase.split('*') pnew = '%s%d' % (p[0], len(p)) @@ -1430,16 +1581,7 @@ class Data: return phase def sortedDevices(self, phase): list = self.dmesg[phase]['list'] - slist = [] - tmp = dict() - for devname in list: - dev = list[devname] - if dev['length'] == 0: - continue - tmp[dev['start']] = devname - for t in sorted(tmp): - slist.append(tmp[t]) - return slist + return sorted(list, key=lambda k:list[k]['start']) def fixupInitcalls(self, phase): # if any calls never returned, clip them at system resume end phaselist = self.dmesg[phase]['list'] @@ -1576,7 +1718,7 @@ class Data: maxname = '%d' % self.maxDeviceNameSize(phase) fmt = '%3d) %'+maxname+'s - %f - %f' c = 1 - for name in devlist: + for name in sorted(devlist): s = devlist[name]['start'] e = devlist[name]['end'] sysvals.vprint(fmt % (c, name, s, e)) @@ -1588,7 +1730,7 @@ class Data: devlist = [] for phase in self.sortedPhases(): list = self.deviceChildren(devname, phase) - for dev in list: + for dev in sorted(list): if dev not in devlist: devlist.append(dev) return devlist @@ -1628,16 +1770,16 @@ class Data: def rootDeviceList(self): # list of devices graphed real = [] - for phase in self.dmesg: + for phase in self.sortedPhases(): list = self.dmesg[phase]['list'] - for dev in list: + for dev in sorted(list): if list[dev]['pid'] >= 0 and dev not in real: real.append(dev) # list of top-most root devices rootlist = [] - for phase in self.dmesg: + for phase in self.sortedPhases(): list = self.dmesg[phase]['list'] - for dev in list: + for dev in sorted(list): pdev = list[dev]['par'] pid = list[dev]['pid'] if(pid < 0 or re.match('[0-9]*-[0-9]*\.[0-9]*[\.0-9]*\:[\.0-9]*$', pdev)): @@ -1718,9 +1860,9 @@ class Data: def createProcessUsageEvents(self): # get an array of process names proclist = [] - for t in self.pstl: + for t in sorted(self.pstl): pslist = self.pstl[t] - for ps in pslist: + for ps in sorted(pslist): if ps not in proclist: proclist.append(ps) # get a list of data points for suspend and resume @@ -1765,7 +1907,7 @@ class Data: def debugPrint(self): for p in self.sortedPhases(): list = self.dmesg[p]['list'] - for devname in list: + for devname in sorted(list): dev = list[devname] if 'ftrace' in dev: dev['ftrace'].debugPrint(' [%s]' % devname) @@ -2466,7 +2608,7 @@ class Timeline: # if there is 1 line per row, draw them the standard way for t, p in standardphases: for i in sorted(self.rowheight[t][p]): - self.rowheight[t][p][i] = self.bodyH/len(self.rowlines[t][p]) + self.rowheight[t][p][i] = float(self.bodyH)/len(self.rowlines[t][p]) def createZoomBox(self, mode='command', testcount=1): # Create bounding box, add buttons html_zoombox = '

\n' @@ -2537,6 +2679,7 @@ class TestProps: cmdlinefmt = '^# command \| (?P.*)' kparamsfmt = '^# kparams \| (?P.*)' devpropfmt = '# Device Properties: .*' + pinfofmt = '# platform-(?P[a-z,A-Z,0-9]*): (?P.*)' tracertypefmt = '# tracer: (?P.*)' firmwarefmt = '# fwsuspend (?P[0-9]*) fwresume (?P[0-9]*)$' procexecfmt = 'ps - (?P.*)$' @@ -2571,12 +2714,6 @@ class TestProps: self.ftrace_line_fmt = self.ftrace_line_fmt_nop else: doError('Invalid tracer format: [%s]' % tracer) - def decode(self, data): - try: - out = base64.b64decode(data).decode('zlib') - except: - out = data - return out def stampInfo(self, line): if re.match(self.stampfmt, line): self.stamp = line @@ -2660,7 +2797,7 @@ class TestProps: if len(self.mcelog) > data.testnumber: m = re.match(self.mcelogfmt, self.mcelog[data.testnumber]) if m: - data.mcelog = self.decode(m.group('m')) + data.mcelog = sv.b64unzip(m.group('m')) # turbostat data if len(self.turbostat) > data.testnumber: m = re.match(self.tstatfmt, self.turbostat[data.testnumber]) @@ -2681,6 +2818,46 @@ class TestProps: m = re.match(self.testerrfmt, self.testerror[data.testnumber]) if m: data.enterfail = m.group('e') + def devprops(self, data): + props = dict() + devlist = data.split(';') + for dev in devlist: + f = dev.split(',') + if len(f) < 3: + continue + dev = f[0] + props[dev] = DevProps() + props[dev].altname = f[1] + if int(f[2]): + props[dev].isasync = True + else: + props[dev].isasync = False + return props + def parseDevprops(self, line, sv): + idx = line.index(': ') + 2 + if idx >= len(line): + return + props = self.devprops(line[idx:]) + if sv.suspendmode == 'command' and 'testcommandstring' in props: + sv.testcommand = props['testcommandstring'].altname + sv.devprops = props + def parsePlatformInfo(self, line, sv): + m = re.match(self.pinfofmt, line) + if not m: + return + name, info = m.group('val'), m.group('info') + if name == 'devinfo': + sv.devprops = self.devprops(sv.b64unzip(info)) + return + elif name == 'testcmd': + sv.testcommand = info + return + field = info.split('|') + if len(field) < 2: + return + cmdline = field[0].strip() + output = sv.b64unzip(field[1].strip()) + sv.platinfo.append([name, cmdline, output]) # Class: TestRun # Description: @@ -2701,7 +2878,7 @@ class ProcessMonitor: process = Popen(c, shell=True, stdout=PIPE) running = dict() for line in process.stdout: - data = line.split() + data = ascii(line).split() pid = data[0] name = re.sub('[()]', '', data[1]) user = int(data[13]) @@ -2805,7 +2982,11 @@ def appendIncompleteTraceLog(testruns): continue # device properties line if(re.match(tp.devpropfmt, line)): - devProps(line) + tp.parseDevprops(line, sysvals) + continue + # platform info line + if(re.match(tp.pinfofmt, line)): + tp.parsePlatformInfo(line, sysvals) continue # parse only valid lines, if this is not one move on m = re.match(tp.ftrace_line_fmt, line) @@ -2902,7 +3083,7 @@ def parseTraceLog(live=False): sysvals.setupAllKprobes() ksuscalls = ['pm_prepare_console'] krescalls = ['pm_restore_console'] - tracewatch = [] + tracewatch = ['irq_wakeup'] if sysvals.usekprobes: tracewatch += ['sync_filesystems', 'freeze_processes', 'syscore_suspend', 'syscore_resume', 'resume_console', 'thaw_processes', 'CPU_ON', @@ -2928,7 +3109,11 @@ def parseTraceLog(live=False): continue # device properties line if(re.match(tp.devpropfmt, line)): - devProps(line) + tp.parseDevprops(line, sysvals) + continue + # platform info line + if(re.match(tp.pinfofmt, line)): + tp.parsePlatformInfo(line, sysvals) continue # ignore all other commented lines if line[0] == '#': @@ -3001,16 +3186,11 @@ def parseTraceLog(live=False): isbegin = False else: continue - m = re.match('(?P.*)\[(?P[0-9]*)\] .*', t.name) - if(m): - val = m.group('val') - if val == '0': - name = m.group('name') - else: - name = m.group('name')+'['+val+']' + if '[' in t.name: + m = re.match('(?P.*)\[.*', t.name) else: m = re.match('(?P.*) .*', t.name) - name = m.group('name') + name = m.group('name') # ignore these events if(name.split('[')[0] in tracewatch): continue @@ -3045,6 +3225,8 @@ def parseTraceLog(live=False): elif(re.match('machine_suspend\[.*', t.name)): if(isbegin): lp = data.lastPhase() + if lp == 'resume_machine': + data.dmesg[lp]['end'] = t.time phase = data.setPhase('suspend_machine', data.dmesg[lp]['end'], True) data.setPhase(phase, t.time, False) if data.tSuspended == 0: @@ -3213,11 +3395,11 @@ def parseTraceLog(live=False): # add the traceevent data to the device hierarchy if(sysvals.usetraceevents): # add actual trace funcs - for name in test.ttemp: + for name in sorted(test.ttemp): for event in test.ttemp[name]: data.newActionGlobal(name, event['begin'], event['end'], event['pid']) # add the kprobe based virtual tracefuncs as actual devices - for key in tp.ktemp: + for key in sorted(tp.ktemp): name, pid = key if name not in sysvals.tracefuncs: continue @@ -3231,7 +3413,7 @@ def parseTraceLog(live=False): data.newActionGlobal(e['name'], kb, ke, pid, color) # add config base kprobes and dev kprobes if sysvals.usedevsrc: - for key in tp.ktemp: + for key in sorted(tp.ktemp): name, pid = key if name in sysvals.tracefuncs or name not in sysvals.dev_tracefuncs: continue @@ -3244,7 +3426,7 @@ def parseTraceLog(live=False): if sysvals.usecallgraph: # add the callgraph data to the device hierarchy sortlist = dict() - for key in test.ftemp: + for key in sorted(test.ftemp): proc, pid = key for cg in test.ftemp[key]: if len(cg.list) < 1 or cg.invalid or (cg.end - cg.start == 0): @@ -3582,7 +3764,7 @@ def parseKernelLog(data): # if trace events are not available, these are better than nothing if(not sysvals.usetraceevents): # look for known actions - for a in at: + for a in sorted(at): if(re.match(at[a]['smsg'], msg)): if(a not in actions): actions[a] = [] @@ -3641,7 +3823,7 @@ def parseKernelLog(data): data.tResumed = data.tSuspended # fill in any actions we've found - for name in actions: + for name in sorted(actions): for event in actions[name]: data.newActionGlobal(name, event['begin'], event['end']) @@ -3761,7 +3943,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title): if lastmode and lastmode != mode and num > 0: for i in range(2): s = sorted(tMed[i]) - list[lastmode]['med'][i] = s[int(len(s)/2)] + list[lastmode]['med'][i] = s[int(len(s)//2)] iMed[i] = tMed[i][list[lastmode]['med'][i]] list[lastmode]['avg'] = [tAvg[0] / num, tAvg[1] / num] list[lastmode]['min'] = tMin @@ -3803,7 +3985,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title): if lastmode and num > 0: for i in range(2): s = sorted(tMed[i]) - list[lastmode]['med'][i] = s[int(len(s)/2)] + list[lastmode]['med'][i] = s[int(len(s)//2)] iMed[i] = tMed[i][list[lastmode]['med'][i]] list[lastmode]['avg'] = [tAvg[0] / num, tAvg[1] / num] list[lastmode]['min'] = tMin @@ -3845,7 +4027,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title): '\n' headnone = '{0}{1}\n' - for mode in list: + for mode in sorted(list): # header line for each suspend mode num = 0 tAvg, tMin, tMax, tMed = list[mode]['avg'], list[mode]['min'],\ @@ -3944,7 +4126,8 @@ def createHTMLDeviceSummary(testruns, htmlfile, title): th.format('Average Time') + th.format('Count') +\ th.format('Worst Time') + th.format('Host (worst time)') +\ th.format('Link (worst time)') + '\n' - for name in sorted(devlist, key=lambda k:devlist[k]['worst'], reverse=True): + for name in sorted(devlist, key=lambda k:(devlist[k]['worst'], \ + devlist[k]['total'], devlist[k]['name']), reverse=True): data = devall[type][name] data['average'] = data['total'] / data['count'] if data['average'] < limit: @@ -4085,7 +4268,7 @@ def createHTML(testruns, testfail): if(tTotal == 0): doError('No timeline data') if(len(data.tLow) > 0): - low_time = '|'.join(data.tLow) + low_time = '+'.join(data.tLow) if sysvals.suspendmode == 'command': run_time = '%.0f'%((data.end-data.start)*1000) if sysvals.testcommand: @@ -4151,7 +4334,7 @@ def createHTML(testruns, testfail): for group in data.devicegroups: devlist = [] for phase in group: - for devname in data.tdevlist[phase]: + for devname in sorted(data.tdevlist[phase]): d = DevItem(data.testnumber, phase, data.dmesg[phase]['list'][devname]) devlist.append(d) if d.isa('kth'): @@ -4230,7 +4413,7 @@ def createHTML(testruns, testfail): for b in phases[dir]: # draw the devices for this phase phaselist = data.dmesg[b]['list'] - for d in data.tdevlist[b]: + for d in sorted(data.tdevlist[b]): name = d drv = '' dev = phaselist[d] @@ -4971,13 +5154,9 @@ def executeSuspend(): if mode == 'freeze' and sysvals.haveTurbostat(): # execution will pause here turbo = sysvals.turbostat() - if '|' in turbo: + if turbo: tdata['turbo'] = turbo - else: - tdata['error'] = turbo else: - if sysvals.haveTurbostat(): - sysvals.vprint('WARNING: ignoring turbostat in mode "%s"' % mode) pf = open(sysvals.powerfile, 'w') pf.write(mode) # execution will pause here @@ -5024,7 +5203,7 @@ def executeSuspend(): op.write(line) op.close() sysvals.fsetVal('', 'trace') - devProps() + sysvals.platforminfo() return testdata def readFile(file): @@ -5040,9 +5219,9 @@ def readFile(file): # The time string, e.g. "1901m16s" def ms2nice(val): val = int(val) - h = val / 3600000 - m = (val / 60000) % 60 - s = (val / 1000) % 60 + h = val // 3600000 + m = (val // 60000) % 60 + s = (val // 1000) % 60 if h > 0: return '%d:%02d:%02d' % (h, m, s) if m > 0: @@ -5115,127 +5294,6 @@ def deviceInfo(output=''): print(lines[i]) return res -# Function: devProps -# Description: -# Retrieve a list of properties for all devices in the trace log -def devProps(data=0): - props = dict() - - if data: - idx = data.index(': ') + 2 - if idx >= len(data): - return - devlist = data[idx:].split(';') - for dev in devlist: - f = dev.split(',') - if len(f) < 3: - continue - dev = f[0] - props[dev] = DevProps() - props[dev].altname = f[1] - if int(f[2]): - props[dev].async = True - else: - props[dev].async = False - sysvals.devprops = props - if sysvals.suspendmode == 'command' and 'testcommandstring' in props: - sysvals.testcommand = props['testcommandstring'].altname - return - - if(os.path.exists(sysvals.ftracefile) == False): - doError('%s does not exist' % sysvals.ftracefile) - - # first get the list of devices we need properties for - msghead = 'Additional data added by AnalyzeSuspend' - alreadystamped = False - tp = TestProps() - tf = sysvals.openlog(sysvals.ftracefile, 'r') - for line in tf: - if msghead in line: - alreadystamped = True - continue - # determine the trace data type (required for further parsing) - m = re.match(tp.tracertypefmt, line) - if(m): - tp.setTracerType(m.group('t')) - continue - # parse only valid lines, if this is not one move on - m = re.match(tp.ftrace_line_fmt, line) - if(not m or 'device_pm_callback_start' not in line): - continue - m = re.match('.*: (?P.*) (?P.*), parent: *(?P

.*), .*', m.group('msg')); - if(not m): - continue - dev = m.group('d') - if dev not in props: - props[dev] = DevProps() - tf.close() - - if not alreadystamped and sysvals.suspendmode == 'command': - out = '#\n# '+msghead+'\n# Device Properties: ' - out += 'testcommandstring,%s,0;' % (sysvals.testcommand) - with sysvals.openlog(sysvals.ftracefile, 'a') as fp: - fp.write(out+'\n') - sysvals.devprops = props - return - - # now get the syspath for each of our target devices - for dirname, dirnames, filenames in os.walk('/sys/devices'): - if(re.match('.*/power', dirname) and 'async' in filenames): - dev = dirname.split('/')[-2] - if dev in props and (not props[dev].syspath or len(dirname) < len(props[dev].syspath)): - props[dev].syspath = dirname[:-6] - - # now fill in the properties for our target devices - for dev in props: - dirname = props[dev].syspath - if not dirname or not os.path.exists(dirname): - continue - with open(dirname+'/power/async') as fp: - text = fp.read() - props[dev].async = False - if 'enabled' in text: - props[dev].async = True - fields = os.listdir(dirname) - if 'product' in fields: - with open(dirname+'/product') as fp: - props[dev].altname = fp.read() - elif 'name' in fields: - with open(dirname+'/name') as fp: - props[dev].altname = fp.read() - elif 'model' in fields: - with open(dirname+'/model') as fp: - props[dev].altname = fp.read() - elif 'description' in fields: - with open(dirname+'/description') as fp: - props[dev].altname = fp.read() - elif 'id' in fields: - with open(dirname+'/id') as fp: - props[dev].altname = fp.read() - elif 'idVendor' in fields and 'idProduct' in fields: - idv, idp = '', '' - with open(dirname+'/idVendor') as fp: - idv = fp.read().strip() - with open(dirname+'/idProduct') as fp: - idp = fp.read().strip() - props[dev].altname = '%s:%s' % (idv, idp) - - if props[dev].altname: - out = props[dev].altname.strip().replace('\n', ' ') - out = out.replace(',', ' ') - out = out.replace(';', ' ') - props[dev].altname = out - - # and now write the data to the ftrace file - if not alreadystamped: - out = '#\n# '+msghead+'\n# Device Properties: ' - for dev in sorted(props): - out += props[dev].out(dev) - with sysvals.openlog(sysvals.ftracefile, 'a') as fp: - fp.write(out+'\n') - - sysvals.devprops = props - # Function: getModes # Description: # Determine the supported power modes on this system @@ -5339,11 +5397,11 @@ def dmidecode(mempath, fatal=False): # search for either an SM table or DMI table i = base = length = num = 0 while(i < memsize): - if buf[i:i+4] == '_SM_' and i < memsize - 16: + if buf[i:i+4] == b'_SM_' and i < memsize - 16: length = struct.unpack('H', buf[i+22:i+24])[0] base, num = struct.unpack('IH', buf[i+24:i+30]) break - elif buf[i:i+5] == '_DMI_': + elif buf[i:i+5] == b'_DMI_': length = struct.unpack('H', buf[i+6:i+8])[0] base, num = struct.unpack('IH', buf[i+8:i+14]) break @@ -5376,15 +5434,15 @@ def dmidecode(mempath, fatal=False): if 0 == struct.unpack('H', buf[n:n+2])[0]: break n += 1 - data = buf[i+size:n+2].split('\0') + data = buf[i+size:n+2].split(b'\0') for name in info: itype, idxadr = info[name] if itype == type: - idx = struct.unpack('B', buf[i+idxadr])[0] + idx = struct.unpack('B', buf[i+idxadr:i+idxadr+1])[0] if idx > 0 and idx < len(data) - 1: - s = data[idx-1].strip() - if s and s.lower() != 'to be filled by o.e.m.': - out[name] = data[idx-1] + s = data[idx-1].decode('utf-8') + if s.strip() and s.strip().lower() != 'to be filled by o.e.m.': + out[name] = s i = n + 2 count += 1 return out @@ -5409,7 +5467,7 @@ def getBattery(): return (ac, charge) def displayControl(cmd): - xset, ret = 'xset -d :0.0 {0}', 0 + xset, ret = 'timeout 10 xset -d :0.0 {0}', 0 if sysvals.sudouser: xset = 'sudo -u %s %s' % (sysvals.sudouser, xset) if cmd == 'init': @@ -5433,7 +5491,7 @@ def displayControl(cmd): fp = Popen(xset.format('q').split(' '), stdout=PIPE).stdout ret = 'unknown' for line in fp: - m = re.match('[\s]*Monitor is (?P.*)', line) + m = re.match('[\s]*Monitor is (?P.*)', ascii(line)) if(m and len(m.group('m')) >= 2): out = m.group('m').lower() ret = out[3:] if out[0:2] == 'in' else out @@ -5495,10 +5553,11 @@ def getFPDT(output): ' OEM Revision : %u\n'\ ' Creator ID : %s\n'\ ' Creator Revision : 0x%x\n'\ - '' % (table[0], table[0], table[1], table[2], table[3], - table[4], table[5], table[6], table[7], table[8])) + '' % (ascii(table[0]), ascii(table[0]), table[1], table[2], + table[3], ascii(table[4]), ascii(table[5]), table[6], + ascii(table[7]), table[8])) - if(table[0] != 'FPDT'): + if(table[0] != b'FPDT'): if(output): doError('Invalid FPDT table') return False @@ -5530,8 +5589,8 @@ def getFPDT(output): return [0, 0] rechead = struct.unpack('4sI', first) recdata = fp.read(rechead[1]-8) - if(rechead[0] == 'FBPT'): - record = struct.unpack('HBBIQQQQQ', recdata) + if(rechead[0] == b'FBPT'): + record = struct.unpack('HBBIQQQQQ', recdata[:48]) if(output): pprint('%s (%s)\n'\ ' Reset END : %u ns\n'\ @@ -5539,11 +5598,11 @@ def getFPDT(output): ' OS Loader StartImage Start : %u ns\n'\ ' ExitBootServices Entry : %u ns\n'\ ' ExitBootServices Exit : %u ns'\ - '' % (rectype[header[0]], rechead[0], record[4], record[5], + '' % (rectype[header[0]], ascii(rechead[0]), record[4], record[5], record[6], record[7], record[8])) - elif(rechead[0] == 'S3PT'): + elif(rechead[0] == b'S3PT'): if(output): - pprint('%s (%s)' % (rectype[header[0]], rechead[0])) + pprint('%s (%s)' % (rectype[header[0]], ascii(rechead[0]))) j = 0 while(j < len(recdata)): prechead = struct.unpack('HBB', recdata[j:j+4]) @@ -5689,7 +5748,7 @@ def doError(msg, help=False): def getArgInt(name, args, min, max, main=True): if main: try: - arg = args.next() + arg = next(args) except: doError(name+': no argument supplied', True) else: @@ -5708,7 +5767,7 @@ def getArgInt(name, args, min, max, main=True): def getArgFloat(name, args, min, max, main=True): if main: try: - arg = args.next() + arg = next(args) except: doError(name+': no argument supplied', True) else: @@ -5737,9 +5796,12 @@ def processData(live=False): parseKernelLog(data) if(sysvals.ftracefile and (sysvals.usecallgraph or sysvals.usetraceevents)): appendIncompleteTraceLog(testruns) + shown = ['bios', 'biosdate', 'cpu', 'host', 'kernel', 'man', 'memfr', + 'memsz', 'mode', 'numcpu', 'plat', 'time'] sysvals.vprint('System Info:') for key in sorted(sysvals.stamp): - sysvals.vprint(' %-8s : %s' % (key.upper(), sysvals.stamp[key])) + if key in shown: + sysvals.vprint(' %-8s : %s' % (key.upper(), sysvals.stamp[key])) if sysvals.kparams: sysvals.vprint('Kparams:\n %s' % sysvals.kparams) sysvals.vprint('Command:\n %s' % sysvals.cmdline) @@ -5768,6 +5830,12 @@ def processData(live=False): (w[0], w[1]) sysvals.vprint(s) data.printDetails() + if len(sysvals.platinfo) > 0: + sysvals.vprint('\nPlatform Info:') + for info in sysvals.platinfo: + sysvals.vprint(info[0]+' - '+info[1]) + sysvals.vprint(info[2]) + sysvals.vprint('') if sysvals.cgdump: for data in testruns: data.debugPrint() @@ -5951,7 +6019,7 @@ def data_from_html(file, outpath, issues, fulldetail=False): worst[d] = {'name':'', 'time': 0.0} dev = devices[d] if d in devices else 0 if dev and len(dev.keys()) > 0: - n = sorted(dev, key=dev.get, reverse=True)[0] + n = sorted(dev, key=lambda k:(dev[k], k), reverse=True)[0] worst[d]['name'], worst[d]['time'] = n, dev[n] data = { 'mode': stmp[2], @@ -5976,7 +6044,7 @@ def data_from_html(file, outpath, issues, fulldetail=False): data['funclist'] = find_in_html(html, '

Date: Thu, 11 Jul 2019 19:51:25 +0530 Subject: [PATCH 09/15] PM: QoS: Get rid of unused flags The network_latency and network_throughput flags for PM-QoS have not found much use in drivers or in userspace since they were introduced. Commit 4a733ef1bea7 ("mac80211: remove PM-QoS listener") removed the only user PM_QOS_NETWORK_LATENCY in the kernel a while ago and there don't seem to be any userspace tools using the character device files either. PM_QOS_MEMORY_BANDWIDTH was never even added to the trace events. Remove all the flags except cpu_dma_latency. Signed-off-by: Amit Kucheria Acked-by: Pavel Machek Signed-off-by: Rafael J. Wysocki --- Documentation/power/pm_qos_interface.rst | 5 +-- include/linux/pm_qos.h | 6 --- include/trace/events/power.h | 8 +--- kernel/power/qos.c | 48 ------------------------ 4 files changed, 4 insertions(+), 63 deletions(-) diff --git a/Documentation/power/pm_qos_interface.rst b/Documentation/power/pm_qos_interface.rst index 69921f072ce1..3097694fba69 100644 --- a/Documentation/power/pm_qos_interface.rst +++ b/Documentation/power/pm_qos_interface.rst @@ -7,8 +7,7 @@ performance expectations by drivers, subsystems and user space applications on one of the parameters. Two different PM QoS frameworks are available: -1. PM QoS classes for cpu_dma_latency, network_latency, network_throughput, -memory_bandwidth. +1. PM QoS classes for cpu_dma_latency 2. the per-device PM QoS framework provides the API to manage the per-device latency constraints and PM QoS flags. @@ -79,7 +78,7 @@ cleanup of a process, the interface requires the process to register its parameter requests in the following way: To register the default pm_qos target for the specific parameter, the process -must open one of /dev/[cpu_dma_latency, network_latency, network_throughput] +must open /dev/cpu_dma_latency As long as the device node is held open that process has a registered request on the parameter. diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 2aebbc5b9950..222c3e01397c 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -13,9 +13,6 @@ enum { PM_QOS_RESERVED = 0, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_NETWORK_LATENCY, - PM_QOS_NETWORK_THROUGHPUT, - PM_QOS_MEMORY_BANDWIDTH, /* insert new class ID */ PM_QOS_NUM_CLASSES, @@ -33,9 +30,6 @@ enum pm_qos_flags_status { #define PM_QOS_LATENCY_ANY_NS ((s64)PM_QOS_LATENCY_ANY * NSEC_PER_USEC) #define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) -#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) -#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0 -#define PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE 0 #define PM_QOS_RESUME_LATENCY_DEFAULT_VALUE PM_QOS_LATENCY_ANY #define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT PM_QOS_LATENCY_ANY #define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS PM_QOS_LATENCY_ANY_NS diff --git a/include/trace/events/power.h b/include/trace/events/power.h index f7aece721aed..7457e238e1b7 100644 --- a/include/trace/events/power.h +++ b/include/trace/events/power.h @@ -379,9 +379,7 @@ DECLARE_EVENT_CLASS(pm_qos_request, TP_printk("pm_qos_class=%s value=%d", __print_symbolic(__entry->pm_qos_class, - { PM_QOS_CPU_DMA_LATENCY, "CPU_DMA_LATENCY" }, - { PM_QOS_NETWORK_LATENCY, "NETWORK_LATENCY" }, - { PM_QOS_NETWORK_THROUGHPUT, "NETWORK_THROUGHPUT" }), + { PM_QOS_CPU_DMA_LATENCY, "CPU_DMA_LATENCY" }), __entry->value) ); @@ -426,9 +424,7 @@ TRACE_EVENT(pm_qos_update_request_timeout, TP_printk("pm_qos_class=%s value=%d, timeout_us=%ld", __print_symbolic(__entry->pm_qos_class, - { PM_QOS_CPU_DMA_LATENCY, "CPU_DMA_LATENCY" }, - { PM_QOS_NETWORK_LATENCY, "NETWORK_LATENCY" }, - { PM_QOS_NETWORK_THROUGHPUT, "NETWORK_THROUGHPUT" }), + { PM_QOS_CPU_DMA_LATENCY, "CPU_DMA_LATENCY" }), __entry->value, __entry->timeout_us) ); diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 33e3febaba53..9568a2fe7c11 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -78,57 +78,9 @@ static struct pm_qos_object cpu_dma_pm_qos = { .name = "cpu_dma_latency", }; -static BLOCKING_NOTIFIER_HEAD(network_lat_notifier); -static struct pm_qos_constraints network_lat_constraints = { - .list = PLIST_HEAD_INIT(network_lat_constraints.list), - .target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, - .default_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, - .no_constraint_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, - .type = PM_QOS_MIN, - .notifiers = &network_lat_notifier, -}; -static struct pm_qos_object network_lat_pm_qos = { - .constraints = &network_lat_constraints, - .name = "network_latency", -}; - - -static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier); -static struct pm_qos_constraints network_tput_constraints = { - .list = PLIST_HEAD_INIT(network_tput_constraints.list), - .target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, - .default_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, - .no_constraint_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, - .type = PM_QOS_MAX, - .notifiers = &network_throughput_notifier, -}; -static struct pm_qos_object network_throughput_pm_qos = { - .constraints = &network_tput_constraints, - .name = "network_throughput", -}; - - -static BLOCKING_NOTIFIER_HEAD(memory_bandwidth_notifier); -static struct pm_qos_constraints memory_bw_constraints = { - .list = PLIST_HEAD_INIT(memory_bw_constraints.list), - .target_value = PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE, - .default_value = PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE, - .no_constraint_value = PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE, - .type = PM_QOS_SUM, - .notifiers = &memory_bandwidth_notifier, -}; -static struct pm_qos_object memory_bandwidth_pm_qos = { - .constraints = &memory_bw_constraints, - .name = "memory_bandwidth", -}; - - static struct pm_qos_object *pm_qos_array[] = { &null_pm_qos, &cpu_dma_pm_qos, - &network_lat_pm_qos, - &network_throughput_pm_qos, - &memory_bandwidth_pm_qos, }; static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf, From 828f369d76d16bffa97133f6f63a64c13a401953 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 17 Jun 2019 16:51:15 +0200 Subject: [PATCH 10/15] cpupower: Add missing newline at end of file "git diff" says: \ No newline at end of file after modifying the files. Signed-off-by: Geert Uytterhoeven Signed-off-by: Shuah Khan --- tools/power/cpupower/bench/cpufreq-bench_plot.sh | 2 +- tools/power/cpupower/bench/cpufreq-bench_script.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/power/cpupower/bench/cpufreq-bench_plot.sh b/tools/power/cpupower/bench/cpufreq-bench_plot.sh index 9061b4f1244e..f5f8b3c8f062 100644 --- a/tools/power/cpupower/bench/cpufreq-bench_plot.sh +++ b/tools/power/cpupower/bench/cpufreq-bench_plot.sh @@ -88,4 +88,4 @@ done echo >> $dir/plot_script.gpl gnuplot $dir/plot_script.gpl -rm -r $dir \ No newline at end of file +rm -r $dir diff --git a/tools/power/cpupower/bench/cpufreq-bench_script.sh b/tools/power/cpupower/bench/cpufreq-bench_script.sh index 4e9714b876d2..785a3679c704 100644 --- a/tools/power/cpupower/bench/cpufreq-bench_script.sh +++ b/tools/power/cpupower/bench/cpufreq-bench_script.sh @@ -85,4 +85,4 @@ function create_plots() } measure -create_plots \ No newline at end of file +create_plots From a73f6e2fbe8077811ea9546e0d44a7533111f0ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Szymanski?= Date: Fri, 7 Jun 2019 17:02:55 +0200 Subject: [PATCH 11/15] tools/power/cpupower: fix 64bit detection when cross-compiling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When cross-compiling cpupower, 64bit detection is done with the host compiler instead of the cross-compiler and libcpupower.so.0 ends up in /usr/lib64 instead of /usr/lib for 32bit target. Fix this by moving 64bit detection after CC is defined. Signed-off-by: Sébastien Szymanski Signed-off-by: Shuah Khan --- tools/power/cpupower/Makefile | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile index 9063fca480b3..c8622497ef23 100644 --- a/tools/power/cpupower/Makefile +++ b/tools/power/cpupower/Makefile @@ -18,7 +18,6 @@ OUTDIR := $(shell cd $(OUTPUT) && pwd) $(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist)) endif -include ../../scripts/Makefile.arch # --- CONFIGURATION BEGIN --- @@ -69,11 +68,6 @@ bindir ?= /usr/bin sbindir ?= /usr/sbin mandir ?= /usr/man includedir ?= /usr/include -ifeq ($(IS_64_BIT), 1) -libdir ?= /usr/lib64 -else -libdir ?= /usr/lib -endif localedir ?= /usr/share/locale docdir ?= /usr/share/doc/packages/cpupower confdir ?= /etc/ @@ -100,6 +94,14 @@ RANLIB = $(CROSS)ranlib HOSTCC = gcc MKDIR = mkdir +# 64bit library detection +include ../../scripts/Makefile.arch + +ifeq ($(IS_64_BIT), 1) +libdir ?= /usr/lib64 +else +libdir ?= /usr/lib +endif # Now we set up the build system # From 87ce243206944a57383309dcbcdcc5750e6c905b Mon Sep 17 00:00:00 2001 From: Benjamin Weis Date: Mon, 24 Jun 2019 15:31:50 +0200 Subject: [PATCH 12/15] cpupower: update German translation Update the German translation of cpupower, and change the encoding to UTF-8. [skhan@linuxfoundation.org: fix merge conflicts] Signed-off-by: Benjamin Weis Acked-by: Dominik Brodowski Signed-off-by: Shuah Khan --- tools/power/cpupower/po/de.po | 344 ++++++++++++++++++---------------- 1 file changed, 180 insertions(+), 164 deletions(-) diff --git a/tools/power/cpupower/po/de.po b/tools/power/cpupower/po/de.po index 70887bb8ba95..9780a447bb55 100644 --- a/tools/power/cpupower/po/de.po +++ b/tools/power/cpupower/po/de.po @@ -8,66 +8,66 @@ msgstr "" "Project-Id-Version: cpufrequtils 006\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-03-08 17:03+0100\n" -"PO-Revision-Date: 2009-08-08 17:18+0100\n" -"Last-Translator: \n" +"PO-Revision-Date: 2019-06-02 15:23+0200\n" +"Last-Translator: Benjamin Weis \n" "Language-Team: NONE\n" "Language: \n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=ISO-8859-1\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: utils/idle_monitor/nhm_idle.c:36 msgid "Processor Core C3" -msgstr "" +msgstr "Prozessorkern C3" #: utils/idle_monitor/nhm_idle.c:43 msgid "Processor Core C6" -msgstr "" +msgstr "Prozessorkern C6" #: utils/idle_monitor/nhm_idle.c:51 msgid "Processor Package C3" -msgstr "" +msgstr "Prozessorpaket C3" #: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70 msgid "Processor Package C6" -msgstr "" +msgstr "Prozessorpaket C6" #: utils/idle_monitor/snb_idle.c:33 msgid "Processor Core C7" -msgstr "" +msgstr "Prozessorkern C7" #: utils/idle_monitor/snb_idle.c:40 msgid "Processor Package C2" -msgstr "" +msgstr "Prozessorpaket C2" #: utils/idle_monitor/snb_idle.c:47 msgid "Processor Package C7" -msgstr "" +msgstr "Prozessorpaket C7" #: utils/idle_monitor/amd_fam14h_idle.c:56 msgid "Package in sleep state (PC1 or deeper)" -msgstr "" +msgstr "Paket in Schlafzustand (PC1 oder tiefer)" #: utils/idle_monitor/amd_fam14h_idle.c:63 msgid "Processor Package C1" -msgstr "" +msgstr "Prozessorpaket C1" #: utils/idle_monitor/amd_fam14h_idle.c:77 msgid "North Bridge P1 boolean counter (returns 0 or 1)" -msgstr "" +msgstr "North Bridge P1 boolescher Zähler (gibt 0 oder 1 zurück)" #: utils/idle_monitor/mperf_monitor.c:35 msgid "Processor Core not idle" -msgstr "" +msgstr "Prozessorkern ist nicht im Leerlauf" #: utils/idle_monitor/mperf_monitor.c:42 msgid "Processor Core in an idle state" -msgstr "" +msgstr "Prozessorkern ist in einem Ruhezustand" #: utils/idle_monitor/mperf_monitor.c:50 msgid "Average Frequency (including boost) in MHz" -msgstr "" +msgstr "Durchschnittliche Frequenz (einschließlich Boost) in MHz" #: utils/idle_monitor/cpupower-monitor.c:66 #, c-format @@ -75,6 +75,8 @@ msgid "" "cpupower monitor: [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " "interval_sec | -c command ...]\n" msgstr "" +"cpupower monitor: [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c Befehl ...]\n" #: utils/idle_monitor/cpupower-monitor.c:69 #, c-format @@ -82,36 +84,40 @@ msgid "" "cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " "interval_sec | -c command ...]\n" msgstr "" +"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c Befehl ...]\n" #: utils/idle_monitor/cpupower-monitor.c:71 #, c-format msgid "\t -v: be more verbose\n" -msgstr "" +msgstr "\t -v: ausführlicher\n" #: utils/idle_monitor/cpupower-monitor.c:73 #, c-format msgid "\t -h: print this help\n" -msgstr "" +msgstr "\t -h: diese Hilfe ausgeben\n" #: utils/idle_monitor/cpupower-monitor.c:74 #, c-format msgid "\t -i: time interval to measure for in seconds (default 1)\n" -msgstr "" +msgstr "\t -i: Zeitintervall für die Messung in Sekunden (Standard 1)\n" #: utils/idle_monitor/cpupower-monitor.c:75 #, c-format msgid "\t -t: show CPU topology/hierarchy\n" -msgstr "" +msgstr "\t -t: CPU-Topologie/Hierarchie anzeigen\n" #: utils/idle_monitor/cpupower-monitor.c:76 #, c-format msgid "\t -l: list available CPU sleep monitors (for use with -m)\n" msgstr "" +"\t -l: verfügbare CPU-Schlafwächter auflisten (für Verwendung mit -m)\n" #: utils/idle_monitor/cpupower-monitor.c:77 #, c-format msgid "\t -m: show specific CPU sleep monitors only (in same order)\n" msgstr "" +"\t -m: spezifische CPU-Schlafwächter anzeigen (in gleicher Reihenfolge)\n" #: utils/idle_monitor/cpupower-monitor.c:79 #, c-format @@ -119,71 +125,73 @@ msgid "" "only one of: -t, -l, -m are allowed\n" "If none of them is passed," msgstr "" +"nur einer von: -t, -l, -m ist erlaubt\n" +"Wenn keiner von ihnen übergeben wird," #: utils/idle_monitor/cpupower-monitor.c:80 #, c-format msgid " all supported monitors are shown\n" -msgstr "" +msgstr " werden alle unterstützten Wächter angezeigt\n" #: utils/idle_monitor/cpupower-monitor.c:197 #, c-format msgid "Monitor %s, Counter %s has no count function. Implementation error\n" -msgstr "" +msgstr "Wächter %s, Zähler %s hat keine Zählfunktion. Implementierungsfehler\n" #: utils/idle_monitor/cpupower-monitor.c:207 #, c-format msgid " *is offline\n" -msgstr "" +msgstr " *ist offline\n" #: utils/idle_monitor/cpupower-monitor.c:236 #, c-format msgid "%s: max monitor name length (%d) exceeded\n" -msgstr "" +msgstr "%s: max. Wächternamenslänge (%d) überschritten\n" #: utils/idle_monitor/cpupower-monitor.c:250 #, c-format msgid "No matching monitor found in %s, try -l option\n" -msgstr "" +msgstr "Kein passender Wächter in %s gefunden, versuchen Sie die Option -l\n" #: utils/idle_monitor/cpupower-monitor.c:266 #, c-format msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n" -msgstr "" +msgstr "Wächter \"%s\" (%d Zustände) - Könnte nach %u s überlaufen\n" #: utils/idle_monitor/cpupower-monitor.c:319 #, c-format msgid "%s took %.5f seconds and exited with status %d\n" -msgstr "" +msgstr "%s hat %.5f Sekunden gedauert und hat sich mit Status %d beendet\n" #: utils/idle_monitor/cpupower-monitor.c:406 #, c-format msgid "Cannot read number of available processors\n" -msgstr "" +msgstr "Anzahl der verfügbaren Prozessoren kann nicht gelesen werden\n" #: utils/idle_monitor/cpupower-monitor.c:417 #, c-format msgid "Available monitor %s needs root access\n" -msgstr "" +msgstr "Verfügbarer Wächter %s benötigt root-Zugriff\n" #: utils/idle_monitor/cpupower-monitor.c:428 #, c-format msgid "No HW Cstate monitors found\n" -msgstr "" +msgstr "Keine HW C-Zustandswächter gefunden\n" #: utils/cpupower.c:78 #, c-format msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n" -msgstr "" +msgstr "cpupower [ -c cpulist ] Unterbefehl [ARGS]\n" #: utils/cpupower.c:79 #, c-format msgid "cpupower --version\n" -msgstr "" +msgstr "cpupower --version\n" #: utils/cpupower.c:80 #, c-format msgid "Supported subcommands are:\n" -msgstr "" +msgstr "Unterstützte Unterbefehle sind:\n" #: utils/cpupower.c:83 #, c-format @@ -191,11 +199,15 @@ msgid "" "\n" "Some subcommands can make use of the -c cpulist option.\n" msgstr "" +"\n" +"Einige Unterbefehle können die Option -c cpulist verwenden.\n" #: utils/cpupower.c:84 #, c-format msgid "Look at the general cpupower manpage how to use it\n" msgstr "" +"Schauen Sie sich die allgemeine cpupower manpage an, um zu erfahren, wie man " +"es benutzt\n" #: utils/cpupower.c:85 #, c-format @@ -217,30 +229,31 @@ msgstr "Bitte melden Sie Fehler an %s.\n" #: utils/cpupower.c:114 #, c-format msgid "Error parsing cpu list\n" -msgstr "" +msgstr "Fehler beim Parsen der CPU-Liste\n" #: utils/cpupower.c:172 #, c-format msgid "Subcommand %s needs root privileges\n" -msgstr "" +msgstr "Unterbefehl %s benötigt root-Rechte\n" #: utils/cpufreq-info.c:31 #, c-format msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n" msgstr "" -"Konnte nicht die Anzahl der CPUs herausfinden (%s : %s), nehme daher 1 an.\n" +"Anzahl der CPUs konnte nicht herausgefinden werden (%s: %s), es wird daher 1 " +"angenommen\n" #: utils/cpufreq-info.c:63 #, c-format msgid "" " minimum CPU frequency - maximum CPU frequency - governor\n" -msgstr "" -" minimale CPU-Taktfreq. - maximale CPU-Taktfreq. - Regler \n" +msgstr " minimale CPU-Frequenz - maximale CPU-Frequenz - Regler\n" #: utils/cpufreq-info.c:151 #, c-format msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n" msgstr "" +"Fehler beim Evaluieren der Boost-Fähigkeiten bei CPU %d -- sind Sie root?\n" #. P state changes via MSR are identified via cpuid 80000007 #. on Intel and AMD, but we assume boost capable machines can do that @@ -250,50 +263,50 @@ msgstr "" #: utils/cpufreq-info.c:161 #, c-format msgid " boost state support: \n" -msgstr "" +msgstr " Boost-Zustand-Unterstützung: \n" #: utils/cpufreq-info.c:163 #, c-format msgid " Supported: %s\n" -msgstr "" +msgstr " Unterstützt: %s\n" #: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164 msgid "yes" -msgstr "" +msgstr "ja" #: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164 msgid "no" -msgstr "" +msgstr "nein" #: utils/cpufreq-info.c:164 -#, fuzzy, c-format +#, c-format msgid " Active: %s\n" -msgstr " Treiber: %s\n" +msgstr " Aktiv: %s\n" #: utils/cpufreq-info.c:177 #, c-format msgid " Boost States: %d\n" -msgstr "" +msgstr " Boost-Zustände: %d\n" #: utils/cpufreq-info.c:178 #, c-format msgid " Total States: %d\n" -msgstr "" +msgstr " Gesamtzustände: %d\n" #: utils/cpufreq-info.c:181 #, c-format msgid " Pstate-Pb%d: %luMHz (boost state)\n" -msgstr "" +msgstr " Pstate-Pb%d: %luMHz (Boost-Zustand)\n" #: utils/cpufreq-info.c:184 #, c-format msgid " Pstate-P%d: %luMHz\n" -msgstr "" +msgstr " Pstate-P%d: %luMHz\n" #: utils/cpufreq-info.c:211 #, c-format msgid " no or unknown cpufreq driver is active on this CPU\n" -msgstr " kein oder nicht bestimmbarer cpufreq-Treiber aktiv\n" +msgstr " kein oder ein unbekannter cpufreq-Treiber ist auf dieser CPU aktiv\n" #: utils/cpufreq-info.c:213 #, c-format @@ -303,12 +316,12 @@ msgstr " Treiber: %s\n" #: utils/cpufreq-info.c:219 #, c-format msgid " CPUs which run at the same hardware frequency: " -msgstr " Folgende CPUs laufen mit der gleichen Hardware-Taktfrequenz: " +msgstr " CPUs, die mit der gleichen Hardwarefrequenz laufen: " #: utils/cpufreq-info.c:230 #, c-format msgid " CPUs which need to have their frequency coordinated by software: " -msgstr " Die Taktfrequenz folgender CPUs werden per Software koordiniert: " +msgstr " CPUs, die ihre Frequenz mit Software koordinieren müssen: " #: utils/cpufreq-info.c:241 #, c-format @@ -318,22 +331,22 @@ msgstr " Maximale Dauer eines Taktfrequenzwechsels: " #: utils/cpufreq-info.c:247 #, c-format msgid " hardware limits: " -msgstr " Hardwarebedingte Grenzen der Taktfrequenz: " +msgstr " Hardwarebegrenzungen: " #: utils/cpufreq-info.c:256 #, c-format msgid " available frequency steps: " -msgstr " mögliche Taktfrequenzen: " +msgstr " verfügbare Frequenzschritte: " #: utils/cpufreq-info.c:269 #, c-format msgid " available cpufreq governors: " -msgstr " mögliche Regler: " +msgstr " verfügbare cpufreq-Regler: " #: utils/cpufreq-info.c:280 #, c-format msgid " current policy: frequency should be within " -msgstr " momentane Taktik: die Frequenz soll innerhalb " +msgstr " momentane Richtlinie: Frequenz sollte innerhalb " #: utils/cpufreq-info.c:282 #, c-format @@ -346,29 +359,28 @@ msgid "" "The governor \"%s\" may decide which speed to use\n" " within this range.\n" msgstr "" -" liegen. Der Regler \"%s\" kann frei entscheiden,\n" -" welche Taktfrequenz innerhalb dieser Grenze verwendet " -"wird.\n" +" sein. Der Regler \"%s\" kann frei entscheiden,\n" +" welche Geschwindigkeit er in diesem Bereich verwendet.\n" #: utils/cpufreq-info.c:293 #, c-format msgid " current CPU frequency is " -msgstr " momentane Taktfrequenz ist " +msgstr " momentane CPU-Frequenz ist " #: utils/cpufreq-info.c:296 #, c-format msgid " (asserted by call to hardware)" -msgstr " (verifiziert durch Nachfrage bei der Hardware)" +msgstr " (durch Aufruf der Hardware sichergestellt)" #: utils/cpufreq-info.c:304 #, c-format msgid " cpufreq stats: " -msgstr " Statistik:" +msgstr " cpufreq-Statistiken: " #: utils/cpufreq-info.c:472 -#, fuzzy, c-format +#, c-format msgid "Usage: cpupower freqinfo [options]\n" -msgstr "Aufruf: cpufreq-info [Optionen]\n" +msgstr "Aufruf: cpupower freqinfo [Optionen]\n" #: utils/cpufreq-info.c:473 utils/cpufreq-set.c:26 utils/cpupower-set.c:23 #: utils/cpupower-info.c:22 utils/cpuidle-info.c:148 @@ -377,11 +389,9 @@ msgid "Options:\n" msgstr "Optionen:\n" #: utils/cpufreq-info.c:474 -#, fuzzy, c-format +#, c-format msgid " -e, --debug Prints out debug information [default]\n" -msgstr "" -" -e, --debug Erzeugt detaillierte Informationen, hilfreich\n" -" zum Aufspüren von Fehlern\n" +msgstr " -e, --debug Gibt Debug-Informationen aus [Standard]\n" #: utils/cpufreq-info.c:475 #, c-format @@ -424,7 +434,7 @@ msgstr " -p, --policy Findet die momentane Taktik heraus *\n" #: utils/cpufreq-info.c:482 #, c-format msgid " -g, --governors Determines available cpufreq governors *\n" -msgstr " -g, --governors Erzeugt eine Liste mit verfügbaren Reglern *\n" +msgstr " -g, --governors Ermittelt verfügbare cpufreq-Regler *\n" #: utils/cpufreq-info.c:483 #, c-format @@ -449,8 +459,7 @@ msgstr "" #: utils/cpufreq-info.c:486 #, c-format msgid " -s, --stats Shows cpufreq statistics if available\n" -msgstr "" -" -s, --stats Zeigt, sofern möglich, Statistiken über cpufreq an.\n" +msgstr " -s, --stats Zeigt cpufreq-Statistiken an, falls vorhanden\n" #: utils/cpufreq-info.c:487 #, c-format @@ -464,13 +473,13 @@ msgstr "" #: utils/cpufreq-info.c:488 #, c-format msgid " -b, --boost Checks for turbo or boost modes *\n" -msgstr "" +msgstr " -b, --boost Prüft auf Turbo- oder Boost-Modi *\n" #: utils/cpufreq-info.c:489 #, c-format msgid "" -" -o, --proc Prints out information like provided by the /proc/" -"cpufreq\n" +" -o, --proc Prints out information like provided by the " +"/proc/cpufreq\n" " interface in 2.4. and early 2.6. kernels\n" msgstr "" " -o, --proc Erzeugt Informationen in einem ähnlichem Format zu " @@ -509,8 +518,8 @@ msgid "" "For the arguments marked with *, omitting the -c or --cpu argument is\n" "equivalent to setting it to zero\n" msgstr "" -"Bei den mit * markierten Parametern wird '--cpu 0' angenommen, soweit nicht\n" -"mittels -c oder --cpu etwas anderes angegeben wird\n" +"Für die mit * markierten Argumente ist das Weglassen des Arguments\n" +"-c oder --cpu gleichbedeutend mit der Einstellung auf Null\n" #: utils/cpufreq-info.c:580 #, c-format @@ -525,8 +534,8 @@ msgid "" "You can't specify more than one --cpu parameter and/or\n" "more than one output-specific argument\n" msgstr "" -"Man kann nicht mehr als einen --cpu-Parameter und/oder mehr als einen\n" -"informationsspezifischen Parameter gleichzeitig angeben\n" +"Sie können nicht mehr als einen Parameter --cpu und/oder\n" +"mehr als ein ausgabespezifisches Argument angeben\n" #: utils/cpufreq-info.c:600 utils/cpufreq-set.c:82 utils/cpupower-set.c:42 #: utils/cpupower-info.c:42 utils/cpuidle-info.c:213 @@ -538,17 +547,17 @@ msgstr "unbekannter oder falscher Parameter\n" #, c-format msgid "couldn't analyze CPU %d as it doesn't seem to be present\n" msgstr "" -"Konnte nicht die CPU %d analysieren, da sie (scheinbar?) nicht existiert.\n" +"CPU %d konnte nicht analysiert werden, da sie scheinbar nicht existiert\n" #: utils/cpufreq-info.c:620 utils/cpupower-info.c:142 #, c-format msgid "analyzing CPU %d:\n" -msgstr "analysiere CPU %d:\n" +msgstr "CPU %d wird analysiert:\n" #: utils/cpufreq-set.c:25 -#, fuzzy, c-format +#, c-format msgid "Usage: cpupower frequency-set [options]\n" -msgstr "Aufruf: cpufreq-set [Optionen]\n" +msgstr "Aufruf: cpupower frequency-set [Optionen]\n" #: utils/cpufreq-set.c:27 #, c-format @@ -556,7 +565,7 @@ msgid "" " -d FREQ, --min FREQ new minimum CPU frequency the governor may " "select\n" msgstr "" -" -d FREQ, --min FREQ neue minimale Taktfrequenz, die der Regler\n" +" -d FREQ, --min FREQ neue minimale CPU-Frequenz, die der Regler\n" " auswählen darf\n" #: utils/cpufreq-set.c:28 @@ -571,7 +580,7 @@ msgstr "" #: utils/cpufreq-set.c:29 #, c-format msgid " -g GOV, --governor GOV new cpufreq governor\n" -msgstr " -g GOV, --governors GOV wechsle zu Regler GOV\n" +msgstr " -g GOV, --governors GOV neuer cpufreq-Regler\n" #: utils/cpufreq-set.c:30 #, c-format @@ -579,29 +588,29 @@ msgid "" " -f FREQ, --freq FREQ specific frequency to be set. Requires userspace\n" " governor to be available and loaded\n" msgstr "" -" -f FREQ, --freq FREQ setze exakte Taktfrequenz. Benötigt den Regler\n" -" 'userspace'.\n" +" -f FREQ, --freq FREQ bestimmte Frequenz, die eingestellt werden soll.\n" +" Erfordert einen verfügbaren und geladenen " +"userspace-Regler\n" #: utils/cpufreq-set.c:32 #, c-format msgid " -r, --related Switches all hardware-related CPUs\n" -msgstr "" -" -r, --related Setze Werte für alle CPUs, deren Taktfrequenz\n" -" hardwarebedingt identisch ist.\n" +msgstr " -r, --related Schaltet alle hardwarebezogenen CPUs um\n" #: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27 #, c-format msgid " -h, --help Prints out this screen\n" -msgstr " -h, --help Gibt diese Kurzübersicht aus\n" +msgstr " -h, --help Gibt diesen Bildschirm aus\n" #: utils/cpufreq-set.c:35 -#, fuzzy, c-format +#, c-format msgid "" "Notes:\n" "1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n" msgstr "" -"Bei den mit * markierten Parametern wird '--cpu 0' angenommen, soweit nicht\n" -"mittels -c oder --cpu etwas anderes angegeben wird\n" +"Hinweis:\n" +"1. Das Weglassen des Arguments -c oder --cpu ist gleichbedeutend mit der " +"Einstellung auf \"all\"\n" #: utils/cpufreq-set.c:37 #, fuzzy, c-format @@ -636,17 +645,21 @@ msgid "" "frequency\n" " or because the userspace governor isn't loaded?\n" msgstr "" -"Beim Einstellen ist ein Fehler aufgetreten. Typische Fehlerquellen sind:\n" -"- nicht ausreichende Rechte (Administrator)\n" -"- der Regler ist nicht verfügbar bzw. nicht geladen\n" -"- die angegebene Taktik ist inkorrekt\n" -"- eine spezifische Frequenz wurde angegeben, aber der Regler 'userspace'\n" -" kann entweder hardwarebedingt nicht genutzt werden oder ist nicht geladen\n" +"Fehler beim Festlegen neuer Werte. Häufige Fehler:\n" +"- Verfügen Sie über die erforderlichen Administrationsrechte? (Superuser?)\n" +"- Ist der von Ihnen gewünschte Regler verfügbar und mittels modprobe " +"geladen?\n" +"- Versuchen Sie eine ungültige Richtlinie festzulegen?\n" +"- Versuchen Sie eine bestimmte Frequenz festzulegen, aber der " +"userspace-Regler ist nicht verfügbar,\n" +" z.B. wegen Hardware, die nicht auf eine bestimmte Frequenz eingestellt " +"werden kann\n" +" oder weil der userspace-Regler nicht geladen ist?\n" #: utils/cpufreq-set.c:170 #, c-format msgid "wrong, unknown or unhandled CPU?\n" -msgstr "unbekannte oder nicht regelbare CPU\n" +msgstr "falsche, unbekannte oder nicht regelbare CPU?\n" #: utils/cpufreq-set.c:302 #, c-format @@ -654,8 +667,8 @@ msgid "" "the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n" "-g/--governor parameters\n" msgstr "" -"Der -f bzw. --freq-Parameter kann nicht mit den Parametern -d/--min, -u/--" -"max\n" +"Der -f bzw. --freq-Parameter kann nicht mit den Parametern -d/--min, " +"-u/--max\n" "oder -g/--governor kombiniert werden\n" #: utils/cpufreq-set.c:308 @@ -664,18 +677,18 @@ msgid "" "At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n" "-g/--governor must be passed\n" msgstr "" -"Es muss mindestens ein Parameter aus -f/--freq, -d/--min, -u/--max oder\n" -"-g/--governor angegeben werden.\n" +"Mindestens ein Parameter aus -f/--freq, -d/--min, -u/--max und\n" +"-g/--governor muss übergeben werden\n" #: utils/cpufreq-set.c:347 #, c-format msgid "Setting cpu: %d\n" -msgstr "" +msgstr "CPU einstellen: %d\n" #: utils/cpupower-set.c:22 #, c-format msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n" -msgstr "" +msgstr "Aufruf: cpupower set [ -b val ] [ -m val ] [ -s val ]\n" #: utils/cpupower-set.c:24 #, c-format @@ -689,6 +702,8 @@ msgstr "" msgid "" " -m, --sched-mc [VAL] Sets the kernel's multi core scheduler policy.\n" msgstr "" +" -m, --sched-mc [VAL] Legt die Mehrkern-Scheduler-Richtlinie des " +"Kernels fest.\n" #: utils/cpupower-set.c:27 #, c-format @@ -700,37 +715,37 @@ msgstr "" #: utils/cpupower-set.c:80 #, c-format msgid "--perf-bias param out of range [0-%d]\n" -msgstr "" +msgstr "--perf-bias-Parameter außerhalb des Bereichs [0-%d]\n" #: utils/cpupower-set.c:91 #, c-format msgid "--sched-mc param out of range [0-%d]\n" -msgstr "" +msgstr "Parameter --sched-mc außerhalb des Bereichs [0-%d]\n" #: utils/cpupower-set.c:102 #, c-format msgid "--sched-smt param out of range [0-%d]\n" -msgstr "" +msgstr "Parameter --sched-smt außerhalb des Bereichs [0-%d]\n" #: utils/cpupower-set.c:121 #, c-format msgid "Error setting sched-mc %s\n" -msgstr "" +msgstr "Fehler beim Einstellen von sched-mc %s\n" #: utils/cpupower-set.c:127 #, c-format msgid "Error setting sched-smt %s\n" -msgstr "" +msgstr "Fehler beim Einstellen von sched-smt %s\n" #: utils/cpupower-set.c:146 #, c-format msgid "Error setting perf-bias value on CPU %d\n" -msgstr "" +msgstr "Fehler beim Einstellen des perf-bias-Wertes auf der CPU %d\n" #: utils/cpupower-info.c:21 #, c-format msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n" -msgstr "" +msgstr "Aufruf: cpupower info [ -b ] [ -m ] [ -s ]\n" #: utils/cpupower-info.c:23 #, c-format @@ -740,9 +755,10 @@ msgid "" msgstr "" #: utils/cpupower-info.c:25 -#, fuzzy, c-format +#, c-format msgid " -m, --sched-mc Gets the kernel's multi core scheduler policy.\n" -msgstr " -p, --policy Findet die momentane Taktik heraus *\n" +msgstr "" +" -m, --sched-mc Ruft die Mehrkern-Scheduler-Richtlinie des Kernels ab.\n" #: utils/cpupower-info.c:26 #, c-format @@ -756,17 +772,20 @@ msgid "" "\n" "Passing no option will show all info, by default only on core 0\n" msgstr "" +"\n" +"Wenn Sie keine Option übergeben, werden alle Informationen angezeigt, " +"standardmäßig nur auf Kern 0\n" #: utils/cpupower-info.c:102 #, c-format msgid "System's multi core scheduler setting: " -msgstr "" +msgstr "Mehrkern-Scheduler-Einstellung des Systems: " #. if sysfs file is missing it's: errno == ENOENT #: utils/cpupower-info.c:105 utils/cpupower-info.c:114 #, c-format msgid "not supported\n" -msgstr "" +msgstr "nicht unterstützt\n" #: utils/cpupower-info.c:111 #, c-format @@ -786,164 +805,161 @@ msgstr "" #: utils/cpupower-info.c:147 #, c-format msgid "Could not read perf-bias value\n" -msgstr "" +msgstr "perf-bias-Wert konnte nicht gelesen werden\n" #: utils/cpupower-info.c:150 #, c-format msgid "perf-bias: %d\n" -msgstr "" +msgstr "perf-bias: %d\n" #: utils/cpuidle-info.c:28 -#, fuzzy, c-format +#, c-format msgid "Analyzing CPU %d:\n" -msgstr "analysiere CPU %d:\n" +msgstr "CPU %d wird analysiert:\n" #: utils/cpuidle-info.c:32 #, c-format msgid "CPU %u: No idle states\n" -msgstr "" +msgstr "CPU %u: Keine Ruhezustände\n" #: utils/cpuidle-info.c:36 #, c-format msgid "CPU %u: Can't read idle state info\n" -msgstr "" +msgstr "CPU %u: Ruhezustands-Informationen können nicht gelesen werden\n" #: utils/cpuidle-info.c:41 #, c-format msgid "Could not determine max idle state %u\n" -msgstr "" +msgstr "Max. Ruhezustand %u konnte nicht bestimmt werden\n" #: utils/cpuidle-info.c:46 #, c-format msgid "Number of idle states: %d\n" -msgstr "" +msgstr "Anzahl der Ruhezustände: %d\n" #: utils/cpuidle-info.c:48 -#, fuzzy, c-format +#, c-format msgid "Available idle states:" -msgstr " mögliche Taktfrequenzen: " +msgstr "Verfügbare Ruhezustände:" #: utils/cpuidle-info.c:71 #, c-format msgid "Flags/Description: %s\n" -msgstr "" +msgstr "Merker/Beschreibung: %s\n" #: utils/cpuidle-info.c:74 #, c-format msgid "Latency: %lu\n" -msgstr "" +msgstr "Latenz: %lu\n" #: utils/cpuidle-info.c:76 #, c-format msgid "Usage: %lu\n" -msgstr "" +msgstr "Aufruf: %lu\n" #: utils/cpuidle-info.c:78 #, c-format msgid "Duration: %llu\n" -msgstr "" +msgstr "Dauer: %llu\n" #: utils/cpuidle-info.c:90 #, c-format msgid "Could not determine cpuidle driver\n" -msgstr "" +msgstr "cpuidle-Treiber konnte nicht bestimmt werden\n" #: utils/cpuidle-info.c:94 -#, fuzzy, c-format +#, c-format msgid "CPUidle driver: %s\n" -msgstr " Treiber: %s\n" +msgstr "CPUidle-Treiber: %s\n" #: utils/cpuidle-info.c:99 #, c-format msgid "Could not determine cpuidle governor\n" -msgstr "" +msgstr "cpuidle-Regler konnte nicht bestimmt werden\n" #: utils/cpuidle-info.c:103 #, c-format msgid "CPUidle governor: %s\n" -msgstr "" +msgstr "CPUidle-Regler: %s\n" #: utils/cpuidle-info.c:122 #, c-format msgid "CPU %u: Can't read C-state info\n" -msgstr "" +msgstr "CPU %u: C-Zustands-Informationen können nicht gelesen werden\n" #. printf("Cstates: %d\n", cstates); #: utils/cpuidle-info.c:127 #, c-format msgid "active state: C0\n" -msgstr "" +msgstr "aktiver Zustand: C0\n" #: utils/cpuidle-info.c:128 #, c-format msgid "max_cstate: C%u\n" -msgstr "" +msgstr "max_cstate: C%u\n" #: utils/cpuidle-info.c:129 -#, fuzzy, c-format +#, c-format msgid "maximum allowed latency: %lu usec\n" -msgstr " Maximale Dauer eines Taktfrequenzwechsels: " +msgstr "maximal erlaubte Latenz: %lu usec\n" #: utils/cpuidle-info.c:130 #, c-format msgid "states:\t\n" -msgstr "" +msgstr "Zustände:\t\n" #: utils/cpuidle-info.c:132 #, c-format msgid " C%d: type[C%d] " -msgstr "" +msgstr " C%d: Typ[C%d] " #: utils/cpuidle-info.c:134 #, c-format msgid "promotion[--] demotion[--] " -msgstr "" +msgstr "promotion[--] demotion[--] " #: utils/cpuidle-info.c:135 #, c-format msgid "latency[%03lu] " -msgstr "" +msgstr "Latenz[%03lu] " #: utils/cpuidle-info.c:137 #, c-format msgid "usage[%08lu] " -msgstr "" +msgstr "Aufruf[%08lu] " #: utils/cpuidle-info.c:139 #, c-format msgid "duration[%020Lu] \n" -msgstr "" +msgstr "Dauer[%020Lu] \n" #: utils/cpuidle-info.c:147 -#, fuzzy, c-format +#, c-format msgid "Usage: cpupower idleinfo [options]\n" -msgstr "Aufruf: cpufreq-info [Optionen]\n" +msgstr "Aufruf: cpupower idleinfo [Optionen]\n" #: utils/cpuidle-info.c:149 -#, fuzzy, c-format +#, c-format msgid " -s, --silent Only show general C-state information\n" msgstr "" -" -e, --debug Erzeugt detaillierte Informationen, hilfreich\n" -" zum Aufspüren von Fehlern\n" +" -s, --silent Nur allgemeine C-Zustands-Informationen anzeigen\n" #: utils/cpuidle-info.c:150 -#, fuzzy, c-format +#, c-format msgid "" -" -o, --proc Prints out information like provided by the /proc/" -"acpi/processor/*/power\n" +" -o, --proc Prints out information like provided by the " +"/proc/acpi/processor/*/power\n" " interface in older kernels\n" msgstr "" -" -o, --proc Erzeugt Informationen in einem ähnlichem Format zu " -"dem\n" -" der /proc/cpufreq-Datei in 2.4. und frühen 2.6.\n" -" Kernel-Versionen\n" +" -o, --proc Gibt Informationen so aus, wie sie von der " +"Schnittstelle\n" +" /proc/acpi/processor/*/power in älteren Kerneln " +"bereitgestellt werden\n" #: utils/cpuidle-info.c:209 -#, fuzzy, c-format +#, c-format msgid "You can't specify more than one output-specific argument\n" -msgstr "" -"Man kann nicht mehr als einen --cpu-Parameter und/oder mehr als einen\n" -"informationsspezifischen Parameter gleichzeitig angeben\n" +msgstr "Sie können nicht mehr als ein ausgabenspezifisches Argument angeben\n" #~ msgid "" #~ " -c CPU, --cpu CPU CPU number which information shall be determined " @@ -956,6 +972,6 @@ msgstr "" #~ " -c CPU, --cpu CPU number of CPU where cpufreq settings shall be " #~ "modified\n" #~ msgstr "" -#~ " -c CPU, --cpu CPU Nummer der CPU, deren Taktfrequenz-" -#~ "Einstellung\n" +#~ " -c CPU, --cpu CPU Nummer der CPU, deren " +#~ "Taktfrequenz-Einstellung\n" #~ " werden soll\n" From b3ad17c09899d491cf9815a6db44d3f9b3f244e7 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 29 Aug 2019 16:48:05 +0200 Subject: [PATCH 13/15] PM / Domains: Simplify genpd_lookup_dev() genpd_lookup_dev(), is a bit unnecessary heavy, as it walks the gpd_list to try to find a valid PM domain corresponding to the device's attached genpd. Instead of walking the gpd_list, let's use the fact that a genpd always has the ->runtime_suspend() callback assigned to the genpd_runtime_suspend() function. While changing this, let's take the opportunity to also rename genpd_lookup_dev(), into dev_to_genpd_safe() to better reflect its purpose. Signed-off-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index b063bc41b0a9..59d6f183d0bb 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -149,29 +149,24 @@ static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev, return ret; } +static int genpd_runtime_suspend(struct device *dev); + /* * Get the generic PM domain for a particular struct device. * This validates the struct device pointer, the PM domain pointer, * and checks that the PM domain pointer is a real generic PM domain. * Any failure results in NULL being returned. */ -static struct generic_pm_domain *genpd_lookup_dev(struct device *dev) +static struct generic_pm_domain *dev_to_genpd_safe(struct device *dev) { - struct generic_pm_domain *genpd = NULL, *gpd; - if (IS_ERR_OR_NULL(dev) || IS_ERR_OR_NULL(dev->pm_domain)) return NULL; - mutex_lock(&gpd_list_lock); - list_for_each_entry(gpd, &gpd_list, gpd_list_node) { - if (&gpd->domain == dev->pm_domain) { - genpd = gpd; - break; - } - } - mutex_unlock(&gpd_list_lock); + /* A genpd's always have its ->runtime_suspend() callback assigned. */ + if (dev->pm_domain->ops.runtime_suspend == genpd_runtime_suspend) + return pd_to_genpd(dev->pm_domain); - return genpd; + return NULL; } /* @@ -1610,7 +1605,7 @@ static int genpd_remove_device(struct generic_pm_domain *genpd, */ int pm_genpd_remove_device(struct device *dev) { - struct generic_pm_domain *genpd = genpd_lookup_dev(dev); + struct generic_pm_domain *genpd = dev_to_genpd_safe(dev); if (!genpd) return -EINVAL; From 3ea4ca9267cf5d02149f7d8a11d8b4c82723a668 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 29 Aug 2019 16:48:15 +0200 Subject: [PATCH 14/15] PM / Domains: Verify PM domain type in dev_pm_genpd_set_performance_state() The dev_pm_genpd_set_performance_state() could in principle be called for a device that has a different PM domain type attached than a genpd. This would lead to a problem as dev_to_genpd() uses the container_of macro. Address this problem by using dev_to_genpd_safe() instead. Signed-off-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 59d6f183d0bb..cc85e87eaf05 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -380,8 +380,8 @@ int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state) unsigned int prev; int ret; - genpd = dev_to_genpd(dev); - if (IS_ERR(genpd)) + genpd = dev_to_genpd_safe(dev); + if (!genpd) return -ENODEV; if (unlikely(!genpd->set_performance_state)) From 4216148337211be7ad2bfe38a0dffc3ce479c283 Mon Sep 17 00:00:00 2001 From: Todd Brandt Date: Wed, 4 Sep 2019 14:04:52 -0700 Subject: [PATCH 15/15] pm-graph: make setVal unbuffered again for python2 and python3 sleepgraph: - kprobe_events won't set correctly if the data is buffered - force sysvals.setVal to be unbuffered and use binary mode - tested in both python2 and python3 Link: https://bugzilla.kernel.org/show_bug.cgi?id=204773 Signed-off-by: Todd Brandt [ rjw: Subject ] Signed-off-by: Rafael J. Wysocki --- tools/power/pm-graph/sleepgraph.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/power/pm-graph/sleepgraph.py b/tools/power/pm-graph/sleepgraph.py index 1794c79a7d1b..f7d1c1f62f86 100755 --- a/tools/power/pm-graph/sleepgraph.py +++ b/tools/power/pm-graph/sleepgraph.py @@ -667,19 +667,19 @@ class SystemValues: if linesack < linesout: return False return True - def setVal(self, val, file, mode='w'): + def setVal(self, val, file): if not os.path.exists(file): return False try: - fp = open(file, mode) - fp.write(val) + fp = open(file, 'wb', 0) + fp.write(val.encode()) fp.flush() fp.close() except: return False return True - def fsetVal(self, val, path, mode='w'): - return self.setVal(val, self.tpath+path, mode) + def fsetVal(self, val, path): + return self.setVal(val, self.tpath+path) def getVal(self, file): res = '' if not os.path.exists(file):