diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/power/cpupower/Makefile | 14 | ||||
-rw-r--r-- | tools/power/cpupower/bench/cpufreq-bench_plot.sh | 2 | ||||
-rw-r--r-- | tools/power/cpupower/bench/cpufreq-bench_script.sh | 2 | ||||
-rw-r--r-- | tools/power/cpupower/po/de.po | 344 | ||||
-rw-r--r-- | tools/power/pm-graph/README | 6 | ||||
-rwxr-xr-x | tools/power/pm-graph/bootgraph.py | 59 | ||||
-rw-r--r-- | tools/power/pm-graph/sleepgraph.8 | 8 | ||||
-rwxr-xr-x | tools/power/pm-graph/sleepgraph.py | 618 |
8 files changed, 581 insertions, 472 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 # 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 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: <linux@dominikbrodowski.net>\n" +"PO-Revision-Date: 2019-06-02 15:23+0200\n" +"Last-Translator: Benjamin Weis <benjamin.weis@gmx.com>\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 <mon1>,[<mon2>] ] ] [-i " "interval_sec | -c command ...]\n" msgstr "" +"cpupower monitor: [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-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 <mon1>,[<mon2>] ] ] [-i " "interval_sec | -c command ...]\n" msgstr "" +"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-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" 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 <todd.e.brandt@intel.com> 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 <todd.e.brandt@linux.intel.com> # @@ -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..f7d1c1f62f86 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 <todd.e.brandt@linux.intel.com> # @@ -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): @@ -646,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, 0) - 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): @@ -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<drv>.*) (?P<d>.*), parent: *(?P<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<dev>\S*) .* ESSID:(?P<ess>\S*)', line) + m = re.match('(?P<dev>\S*) .* ESSID:(?P<ess>\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<ip>[0-9\.]*)', line) + m = re.match('.* inet (?P<ip>[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 = '<center><button id="zoomin">ZOOM IN +</button><button id="zoomout">ZOOM OUT -</button><button id="zoomdef">ZOOM 1:1</button></center>\n' @@ -2537,6 +2679,7 @@ class TestProps: cmdlinefmt = '^# command \| (?P<cmd>.*)' kparamsfmt = '^# kparams \| (?P<kp>.*)' devpropfmt = '# Device Properties: .*' + pinfofmt = '# platform-(?P<val>[a-z,A-Z,0-9]*): (?P<info>.*)' tracertypefmt = '# tracer: (?P<t>.*)' firmwarefmt = '# fwsuspend (?P<s>[0-9]*) fwresume (?P<r>[0-9]*)$' procexecfmt = 'ps - (?P<ps>.*)$' @@ -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<name>.*)\[(?P<val>[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<name>.*)\[.*', t.name) else: m = re.match('(?P<name>.*) .*', 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): '</tr>\n' headnone = '<tr class="head"><td>{0}</td><td>{1}</td><td colspan='+\ colspan+'></td></tr>\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)') + '</tr>\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<drv>.*) (?P<d>.*), parent: *(?P<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<m>.*)', line) + m = re.match('[\s]*Monitor is (?P<m>.*)', 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, '<div title="', '" class="traceevent"', False) return data -def genHtml(subdir): +def genHtml(subdir, force=False): for dirname, dirnames, filenames in os.walk(subdir): sysvals.dmesgfile = sysvals.ftracefile = sysvals.htmlfile = '' for filename in filenames: @@ -5986,7 +6054,7 @@ def genHtml(subdir): sysvals.ftracefile = os.path.join(dirname, filename) sysvals.setOutputFile() if sysvals.ftracefile and sysvals.htmlfile and \ - not os.path.exists(sysvals.htmlfile): + (force or not os.path.exists(sysvals.htmlfile)): pprint('FTRACE: %s' % sysvals.ftracefile) if sysvals.dmesgfile: pprint('DMESG : %s' % sysvals.dmesgfile) @@ -6042,7 +6110,7 @@ def checkArgBool(name, value): # Description: # Configure the script via the info in a config file def configFromFile(file): - Config = ConfigParser.ConfigParser() + Config = configparser.ConfigParser() Config.read(file) sections = Config.sections() @@ -6270,7 +6338,7 @@ def printHelp(): ' default: suspend-{date}-{time}\n'\ ' -rtcwake t Wakeup t seconds after suspend, set t to "off" to disable (default: 15)\n'\ ' -addlogs Add the dmesg and ftrace logs to the html output\n'\ - ' -turbostat Use turbostat to execute the command in freeze mode (default: disabled)\n'\ + ' -noturbostat Dont use turbostat in freeze mode (default: disabled)\n'\ ' -srgap Add a visible gap in the timeline between sus/res (default: disabled)\n'\ ' -skiphtml Run the test and capture the trace logs, but skip the timeline (default: disabled)\n'\ ' -result fn Export a results table to a text file for parsing.\n'\ @@ -6340,7 +6408,7 @@ if __name__ == '__main__': for arg in args: if(arg == '-m'): try: - val = args.next() + val = next(args) except: doError('No mode supplied', True) if val == 'command' and not sysvals.testcommand: @@ -6384,10 +6452,8 @@ if __name__ == '__main__': sysvals.dmesglog = True elif(arg == '-addlogftrace'): sysvals.ftracelog = True - elif(arg == '-turbostat'): - sysvals.tstat = True - if not sysvals.haveTurbostat(): - doError('Turbostat command not found') + elif(arg == '-noturbostat'): + sysvals.tstat = False elif(arg == '-verbose'): sysvals.verbose = True elif(arg == '-proc'): @@ -6400,7 +6466,7 @@ if __name__ == '__main__': sysvals.gzip = True elif(arg == '-rs'): try: - val = args.next() + val = next(args) except: doError('-rs requires "enable" or "disable"', True) if val.lower() in switchvalues: @@ -6412,7 +6478,7 @@ if __name__ == '__main__': doError('invalid option: %s, use "enable/disable" or "on/off"' % val, True) elif(arg == '-display'): try: - val = args.next() + val = next(args) except: doError('-display requires an mode value', True) disopt = ['on', 'off', 'standby', 'suspend'] @@ -6423,7 +6489,7 @@ if __name__ == '__main__': sysvals.max_graph_depth = getArgInt('-maxdepth', args, 0, 1000) elif(arg == '-rtcwake'): try: - val = args.next() + val = next(args) except: doError('No rtcwake time supplied', True) if val.lower() in switchoff: @@ -6443,7 +6509,7 @@ if __name__ == '__main__': sysvals.cgtest = getArgInt('-cgtest', args, 0, 1) elif(arg == '-cgphase'): try: - val = args.next() + val = next(args) except: doError('No phase name supplied', True) d = Data(0) @@ -6453,19 +6519,19 @@ if __name__ == '__main__': sysvals.cgphase = val elif(arg == '-cgfilter'): try: - val = args.next() + val = next(args) except: doError('No callgraph functions supplied', True) sysvals.setCallgraphFilter(val) elif(arg == '-skipkprobe'): try: - val = args.next() + val = next(args) except: doError('No kprobe functions supplied', True) sysvals.skipKprobes(val) elif(arg == '-cgskip'): try: - val = args.next() + val = next(args) except: doError('No file supplied', True) if val.lower() in switchoff: @@ -6480,7 +6546,7 @@ if __name__ == '__main__': sysvals.callloopmaxlen = getArgFloat('-callloop-maxlen', args, 0.0, 1.0) elif(arg == '-cmd'): try: - val = args.next() + val = next(args) except: doError('No command string supplied', True) sysvals.testcommand = val @@ -6495,13 +6561,13 @@ if __name__ == '__main__': sysvals.multitest['delay'] = getArgInt('-multi n d (delay between tests)', args, 0, 3600) elif(arg == '-o'): try: - val = args.next() + val = next(args) except: doError('No subdirectory name supplied', True) sysvals.outdir = sysvals.setOutputFolder(val) elif(arg == '-config'): try: - val = args.next() + val = next(args) except: doError('No text file supplied', True) file = sysvals.configFile(val) @@ -6510,7 +6576,7 @@ if __name__ == '__main__': configFromFile(file) elif(arg == '-fadd'): try: - val = args.next() + val = next(args) except: doError('No text file supplied', True) file = sysvals.configFile(val) @@ -6519,7 +6585,7 @@ if __name__ == '__main__': sysvals.addFtraceFilterFunctions(file) elif(arg == '-dmesg'): try: - val = args.next() + val = next(args) except: doError('No dmesg file supplied', True) sysvals.notestrun = True @@ -6528,7 +6594,7 @@ if __name__ == '__main__': doError('%s does not exist' % sysvals.dmesgfile) elif(arg == '-ftrace'): try: - val = args.next() + val = next(args) except: doError('No ftrace file supplied', True) sysvals.notestrun = True @@ -6537,7 +6603,7 @@ if __name__ == '__main__': doError('%s does not exist' % sysvals.ftracefile) elif(arg == '-summary'): try: - val = args.next() + val = next(args) except: doError('No directory supplied', True) cmd = 'summary' @@ -6547,13 +6613,13 @@ if __name__ == '__main__': doError('%s is not accesible' % val) elif(arg == '-filter'): try: - val = args.next() + val = next(args) except: doError('No devnames supplied', True) sysvals.setDeviceFilter(val) elif(arg == '-result'): try: - val = args.next() + val = next(args) except: doError('No result file supplied', True) sysvals.result = val |