aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-annotate.txt6
-rw-r--r--tools/perf/Documentation/perf-probe.txt6
-rw-r--r--tools/perf/Documentation/perf-report.txt21
-rw-r--r--tools/perf/Documentation/perf-script.txt18
-rw-r--r--tools/perf/Makefile7
-rw-r--r--tools/perf/builtin-annotate.c15
-rw-r--r--tools/perf/builtin-probe.c3
-rw-r--r--tools/perf/builtin-record.c2
-rw-r--r--tools/perf/builtin-report.c57
-rw-r--r--tools/perf/builtin-script.c121
-rw-r--r--tools/perf/builtin-stat.c20
-rw-r--r--tools/perf/builtin-test.c249
-rw-r--r--tools/perf/builtin-top.c2
-rw-r--r--tools/perf/util/callchain.h6
-rw-r--r--tools/perf/util/dwarf-aux.c663
-rw-r--r--tools/perf/util/dwarf-aux.h100
-rw-r--r--tools/perf/util/evsel.c1
-rw-r--r--tools/perf/util/evsel.h1
-rw-r--r--tools/perf/util/header.c5
-rw-r--r--tools/perf/util/hist.c6
-rw-r--r--tools/perf/util/parse-events.c39
-rw-r--r--tools/perf/util/parse-events.h6
-rw-r--r--tools/perf/util/probe-event.c165
-rw-r--r--tools/perf/util/probe-event.h1
-rw-r--r--tools/perf/util/probe-finder.c752
-rw-r--r--tools/perf/util/probe-finder.h43
-rw-r--r--tools/perf/util/python.c17
-rw-r--r--tools/perf/util/session.c132
-rw-r--r--tools/perf/util/session.h9
-rw-r--r--tools/perf/util/sort.c223
-rw-r--r--tools/perf/util/sort.h14
-rw-r--r--tools/perf/util/string.c19
-rw-r--r--tools/perf/util/trace-event-info.c120
-rw-r--r--tools/perf/util/util.h1
-rw-r--r--tools/power/cpupower/.gitignore22
-rw-r--r--tools/power/cpupower/Makefile279
-rw-r--r--tools/power/cpupower/README49
-rw-r--r--tools/power/cpupower/ToDo11
-rw-r--r--tools/power/cpupower/bench/Makefile29
-rw-r--r--tools/power/cpupower/bench/README-BENCH124
-rw-r--r--tools/power/cpupower/bench/benchmark.c194
-rw-r--r--tools/power/cpupower/bench/benchmark.h29
-rw-r--r--tools/power/cpupower/bench/config.h36
-rw-r--r--tools/power/cpupower/bench/cpufreq-bench_plot.sh104
-rw-r--r--tools/power/cpupower/bench/cpufreq-bench_script.sh101
-rw-r--r--tools/power/cpupower/bench/example.cfg11
-rw-r--r--tools/power/cpupower/bench/main.c202
-rw-r--r--tools/power/cpupower/bench/parse.c225
-rw-r--r--tools/power/cpupower/bench/parse.h53
-rw-r--r--tools/power/cpupower/bench/system.c191
-rw-r--r--tools/power/cpupower/bench/system.h29
-rw-r--r--tools/power/cpupower/debug/i386/Makefile20
-rw-r--r--tools/power/cpupower/debug/i386/centrino-decode.c113
-rw-r--r--tools/power/cpupower/debug/i386/dump_psb.c196
-rw-r--r--tools/power/cpupower/debug/i386/intel_gsic.c78
-rw-r--r--tools/power/cpupower/debug/i386/powernow-k8-decode.c96
-rw-r--r--tools/power/cpupower/debug/kernel/Makefile23
-rw-r--r--tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c113
-rw-r--r--tools/power/cpupower/debug/x86_64/Makefile14
l---------tools/power/cpupower/debug/x86_64/centrino-decode.c1
l---------tools/power/cpupower/debug/x86_64/powernow-k8-decode.c1
-rw-r--r--tools/power/cpupower/lib/cpufreq.c208
-rw-r--r--tools/power/cpupower/lib/cpufreq.h223
-rw-r--r--tools/power/cpupower/lib/sysfs.c672
-rw-r--r--tools/power/cpupower/lib/sysfs.h31
-rw-r--r--tools/power/cpupower/man/cpupower-frequency-info.176
-rw-r--r--tools/power/cpupower/man/cpupower-frequency-set.154
-rw-r--r--tools/power/cpupower/man/cpupower-info.119
-rw-r--r--tools/power/cpupower/man/cpupower-monitor.1179
-rw-r--r--tools/power/cpupower/man/cpupower-set.1103
-rw-r--r--tools/power/cpupower/man/cpupower.172
-rw-r--r--tools/power/cpupower/po/cs.po944
-rw-r--r--tools/power/cpupower/po/de.po961
-rw-r--r--tools/power/cpupower/po/fr.po947
-rw-r--r--tools/power/cpupower/po/it.po961
-rw-r--r--tools/power/cpupower/po/pt.po957
-rw-r--r--tools/power/cpupower/utils/builtin.h18
-rw-r--r--tools/power/cpupower/utils/cpufreq-info.c708
-rw-r--r--tools/power/cpupower/utils/cpufreq-set.c358
-rw-r--r--tools/power/cpupower/utils/cpuidle-info.c244
-rw-r--r--tools/power/cpupower/utils/cpupower-info.c153
-rw-r--r--tools/power/cpupower/utils/cpupower-set.c153
-rw-r--r--tools/power/cpupower/utils/cpupower.c203
-rw-r--r--tools/power/cpupower/utils/helpers/amd.c137
-rw-r--r--tools/power/cpupower/utils/helpers/bitmask.c292
-rw-r--r--tools/power/cpupower/utils/helpers/bitmask.h33
-rw-r--r--tools/power/cpupower/utils/helpers/cpuid.c176
-rw-r--r--tools/power/cpupower/utils/helpers/helpers.h178
-rw-r--r--tools/power/cpupower/utils/helpers/misc.c27
-rw-r--r--tools/power/cpupower/utils/helpers/msr.c115
-rw-r--r--tools/power/cpupower/utils/helpers/pci.c44
-rw-r--r--tools/power/cpupower/utils/helpers/sysfs.c358
-rw-r--r--tools/power/cpupower/utils/helpers/sysfs.h28
-rw-r--r--tools/power/cpupower/utils/helpers/topology.c108
-rw-r--r--tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c338
-rw-r--r--tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c196
-rw-r--r--tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c448
-rw-r--r--tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h68
-rw-r--r--tools/power/cpupower/utils/idle_monitor/idle_monitors.def7
-rw-r--r--tools/power/cpupower/utils/idle_monitor/idle_monitors.h18
-rw-r--r--tools/power/cpupower/utils/idle_monitor/mperf_monitor.c255
-rw-r--r--tools/power/cpupower/utils/idle_monitor/nhm_idle.c216
-rw-r--r--tools/power/cpupower/utils/idle_monitor/snb_idle.c190
-rwxr-xr-xtools/power/cpupower/utils/version-gen.sh35
-rw-r--r--tools/slub/slabinfo.c59
-rwxr-xr-xtools/testing/ktest/ktest.pl970
-rw-r--r--tools/testing/ktest/sample.conf142
107 files changed, 16678 insertions, 1198 deletions
diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt
index 6f5a498608b2..85c5f026930d 100644
--- a/tools/perf/Documentation/perf-annotate.txt
+++ b/tools/perf/Documentation/perf-annotate.txt
@@ -66,6 +66,12 @@ OPTIONS
66 used. This interfaces starts by centering on the line with more 66 used. This interfaces starts by centering on the line with more
67 samples, TAB/UNTAB cycles through the lines with more samples. 67 samples, TAB/UNTAB cycles through the lines with more samples.
68 68
69-c::
70--cpu:: Only report samples for the list of CPUs provided. Multiple CPUs can
71 be provided as a comma-separated list with no space: 0,1. Ranges of
72 CPUs are specified with -: 0-2. Default is to report samples on all
73 CPUs.
74
69SEE ALSO 75SEE ALSO
70-------- 76--------
71linkperf:perf-record[1], linkperf:perf-report[1] 77linkperf:perf-record[1], linkperf:perf-report[1]
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 02bafce4b341..2780d9ce48bf 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -34,9 +34,11 @@ OPTIONS
34 Specify vmlinux path which has debuginfo (Dwarf binary). 34 Specify vmlinux path which has debuginfo (Dwarf binary).
35 35
36-m:: 36-m::
37--module=MODNAME:: 37--module=MODNAME|PATH::
38 Specify module name in which perf-probe searches probe points 38 Specify module name in which perf-probe searches probe points
39 or lines. 39 or lines. If a path of module file is passed, perf-probe
40 treat it as an offline module (this means you can add a probe on
41 a module which has not been loaded yet).
40 42
41-s:: 43-s::
42--source=PATH:: 44--source=PATH::
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 8ba03d6e5398..04253c07d19a 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -80,15 +80,24 @@ OPTIONS
80--dump-raw-trace:: 80--dump-raw-trace::
81 Dump raw trace in ASCII. 81 Dump raw trace in ASCII.
82 82
83-g [type,min]:: 83-g [type,min,order]::
84--call-graph:: 84--call-graph::
85 Display call chains using type and min percent threshold. 85 Display call chains using type, min percent threshold and order.
86 type can be either: 86 type can be either:
87 - flat: single column, linear exposure of call chains. 87 - flat: single column, linear exposure of call chains.
88 - graph: use a graph tree, displaying absolute overhead rates. 88 - graph: use a graph tree, displaying absolute overhead rates.
89 - fractal: like graph, but displays relative rates. Each branch of 89 - fractal: like graph, but displays relative rates. Each branch of
90 the tree is considered as a new profiled object. + 90 the tree is considered as a new profiled object. +
91 Default: fractal,0.5. 91
92 order can be either:
93 - callee: callee based call graph.
94 - caller: inverted caller based call graph.
95
96 Default: fractal,0.5,callee.
97
98-G::
99--inverted::
100 alias for inverted caller based call graph.
92 101
93--pretty=<key>:: 102--pretty=<key>::
94 Pretty printing style. key: normal, raw 103 Pretty printing style. key: normal, raw
@@ -119,6 +128,12 @@ OPTIONS
119--symfs=<directory>:: 128--symfs=<directory>::
120 Look for files with symbols relative to this directory. 129 Look for files with symbols relative to this directory.
121 130
131-c::
132--cpu:: Only report samples for the list of CPUs provided. Multiple CPUs can
133 be provided as a comma-separated list with no space: 0,1. Ranges of
134 CPUs are specified with -: 0-2. Default is to report samples on all
135 CPUs.
136
122SEE ALSO 137SEE ALSO
123-------- 138--------
124linkperf:perf-stat[1] 139linkperf:perf-stat[1]
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index 86c87e214b11..db017867d9e8 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -115,10 +115,10 @@ OPTIONS
115-f:: 115-f::
116--fields:: 116--fields::
117 Comma separated list of fields to print. Options are: 117 Comma separated list of fields to print. Options are:
118 comm, tid, pid, time, cpu, event, trace, sym. Field 118 comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr.
119 list can be prepended with the type, trace, sw or hw, 119 Field list can be prepended with the type, trace, sw or hw,
120 to indicate to which event type the field list applies. 120 to indicate to which event type the field list applies.
121 e.g., -f sw:comm,tid,time,sym and -f trace:time,cpu,trace 121 e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace
122 122
123 perf script -f <fields> 123 perf script -f <fields>
124 124
@@ -132,17 +132,17 @@ OPTIONS
132 The arguments are processed in the order received. A later usage can 132 The arguments are processed in the order received. A later usage can
133 reset a prior request. e.g.: 133 reset a prior request. e.g.:
134 134
135 -f trace: -f comm,tid,time,sym 135 -f trace: -f comm,tid,time,ip,sym
136 136
137 The first -f suppresses trace events (field list is ""), but then the 137 The first -f suppresses trace events (field list is ""), but then the
138 second invocation sets the fields to comm,tid,time,sym. In this case a 138 second invocation sets the fields to comm,tid,time,ip,sym. In this case a
139 warning is given to the user: 139 warning is given to the user:
140 140
141 "Overriding previous field request for all events." 141 "Overriding previous field request for all events."
142 142
143 Alternativey, consider the order: 143 Alternativey, consider the order:
144 144
145 -f comm,tid,time,sym -f trace: 145 -f comm,tid,time,ip,sym -f trace:
146 146
147 The first -f sets the fields for all events and the second -f 147 The first -f sets the fields for all events and the second -f
148 suppresses trace events. The user is given a warning message about 148 suppresses trace events. The user is given a warning message about
@@ -182,6 +182,12 @@ OPTIONS
182--hide-call-graph:: 182--hide-call-graph::
183 When printing symbols do not display call chain. 183 When printing symbols do not display call chain.
184 184
185-c::
186--cpu:: Only report samples for the list of CPUs provided. Multiple CPUs can
187 be provided as a comma-separated list with no space: 0,1. Ranges of
188 CPUs are specified with -: 0-2. Default is to report samples on all
189 CPUs.
190
185SEE ALSO 191SEE ALSO
186-------- 192--------
187linkperf:perf-record[1], linkperf:perf-script-perl[1], 193linkperf:perf-record[1], linkperf:perf-script-perl[1],
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 940257b5774e..56d62d3fb167 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -52,7 +52,10 @@ ifeq ($(ARCH),i386)
52endif 52endif
53ifeq ($(ARCH),x86_64) 53ifeq ($(ARCH),x86_64)
54 ARCH := x86 54 ARCH := x86
55 IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1) 55 IS_X86_64 := 0
56 ifeq (, $(findstring m32,$(EXTRA_CFLAGS)))
57 IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1)
58 endif
56 ifeq (${IS_X86_64}, 1) 59 ifeq (${IS_X86_64}, 1)
57 RAW_ARCH := x86_64 60 RAW_ARCH := x86_64
58 ARCH_CFLAGS := -DARCH_X86_64 61 ARCH_CFLAGS := -DARCH_X86_64
@@ -279,6 +282,7 @@ LIB_H += util/thread.h
279LIB_H += util/thread_map.h 282LIB_H += util/thread_map.h
280LIB_H += util/trace-event.h 283LIB_H += util/trace-event.h
281LIB_H += util/probe-finder.h 284LIB_H += util/probe-finder.h
285LIB_H += util/dwarf-aux.h
282LIB_H += util/probe-event.h 286LIB_H += util/probe-event.h
283LIB_H += util/pstack.h 287LIB_H += util/pstack.h
284LIB_H += util/cpumap.h 288LIB_H += util/cpumap.h
@@ -435,6 +439,7 @@ else
435 BASIC_CFLAGS += -DDWARF_SUPPORT 439 BASIC_CFLAGS += -DDWARF_SUPPORT
436 EXTLIBS += -lelf -ldw 440 EXTLIBS += -lelf -ldw
437 LIB_OBJS += $(OUTPUT)util/probe-finder.o 441 LIB_OBJS += $(OUTPUT)util/probe-finder.o
442 LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
438endif # PERF_HAVE_DWARF_REGS 443endif # PERF_HAVE_DWARF_REGS
439endif # NO_DWARF 444endif # NO_DWARF
440 445
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 7b139e1e7e86..555aefd7fe01 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -28,6 +28,8 @@
28#include "util/hist.h" 28#include "util/hist.h"
29#include "util/session.h" 29#include "util/session.h"
30 30
31#include <linux/bitmap.h>
32
31static char const *input_name = "perf.data"; 33static char const *input_name = "perf.data";
32 34
33static bool force, use_tui, use_stdio; 35static bool force, use_tui, use_stdio;
@@ -38,6 +40,9 @@ static bool print_line;
38 40
39static const char *sym_hist_filter; 41static const char *sym_hist_filter;
40 42
43static const char *cpu_list;
44static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
45
41static int perf_evlist__add_sample(struct perf_evlist *evlist, 46static int perf_evlist__add_sample(struct perf_evlist *evlist,
42 struct perf_sample *sample, 47 struct perf_sample *sample,
43 struct perf_evsel *evsel, 48 struct perf_evsel *evsel,
@@ -90,6 +95,9 @@ static int process_sample_event(union perf_event *event,
90 return -1; 95 return -1;
91 } 96 }
92 97
98 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
99 return 0;
100
93 if (!al.filtered && 101 if (!al.filtered &&
94 perf_evlist__add_sample(session->evlist, sample, evsel, &al)) { 102 perf_evlist__add_sample(session->evlist, sample, evsel, &al)) {
95 pr_warning("problem incrementing symbol count, " 103 pr_warning("problem incrementing symbol count, "
@@ -177,6 +185,12 @@ static int __cmd_annotate(void)
177 if (session == NULL) 185 if (session == NULL)
178 return -ENOMEM; 186 return -ENOMEM;
179 187
188 if (cpu_list) {
189 ret = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
190 if (ret)
191 goto out_delete;
192 }
193
180 ret = perf_session__process_events(session, &event_ops); 194 ret = perf_session__process_events(session, &event_ops);
181 if (ret) 195 if (ret)
182 goto out_delete; 196 goto out_delete;
@@ -252,6 +266,7 @@ static const struct option options[] = {
252 "print matching source lines (may be slow)"), 266 "print matching source lines (may be slow)"),
253 OPT_BOOLEAN('P', "full-paths", &full_paths, 267 OPT_BOOLEAN('P', "full-paths", &full_paths,
254 "Don't shorten the displayed pathnames"), 268 "Don't shorten the displayed pathnames"),
269 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
255 OPT_END() 270 OPT_END()
256}; 271};
257 272
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 2c0e64d0b4aa..5f2a5c7046df 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -242,7 +242,8 @@ static const struct option options[] = {
242 OPT_STRING('s', "source", &symbol_conf.source_prefix, 242 OPT_STRING('s', "source", &symbol_conf.source_prefix,
243 "directory", "path to kernel source"), 243 "directory", "path to kernel source"),
244 OPT_STRING('m', "module", &params.target_module, 244 OPT_STRING('m', "module", &params.target_module,
245 "modname", "target module name"), 245 "modname|path",
246 "target module name (for online) or path (for offline)"),
246#endif 247#endif
247 OPT__DRY_RUN(&probe_event_dry_run), 248 OPT__DRY_RUN(&probe_event_dry_run),
248 OPT_INTEGER('\0', "max-probes", &params.max_probe_points, 249 OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 8e2c85798185..80dc5b790e47 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -740,7 +740,7 @@ static bool force, append_file;
740const struct option record_options[] = { 740const struct option record_options[] = {
741 OPT_CALLBACK('e', "event", &evsel_list, "event", 741 OPT_CALLBACK('e', "event", &evsel_list, "event",
742 "event selector. use 'perf list' to list available events", 742 "event selector. use 'perf list' to list available events",
743 parse_events), 743 parse_events_option),
744 OPT_CALLBACK(0, "filter", &evsel_list, "filter", 744 OPT_CALLBACK(0, "filter", &evsel_list, "filter",
745 "event filter", parse_filter), 745 "event filter", parse_filter),
746 OPT_INTEGER('p', "pid", &target_pid, 746 OPT_INTEGER('p', "pid", &target_pid,
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 287a173523a7..f854efda7686 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -33,6 +33,8 @@
33#include "util/sort.h" 33#include "util/sort.h"
34#include "util/hist.h" 34#include "util/hist.h"
35 35
36#include <linux/bitmap.h>
37
36static char const *input_name = "perf.data"; 38static char const *input_name = "perf.data";
37 39
38static bool force, use_tui, use_stdio; 40static bool force, use_tui, use_stdio;
@@ -45,9 +47,13 @@ static struct perf_read_values show_threads_values;
45static const char default_pretty_printing_style[] = "normal"; 47static const char default_pretty_printing_style[] = "normal";
46static const char *pretty_printing_style = default_pretty_printing_style; 48static const char *pretty_printing_style = default_pretty_printing_style;
47 49
48static char callchain_default_opt[] = "fractal,0.5"; 50static char callchain_default_opt[] = "fractal,0.5,callee";
51static bool inverted_callchain;
49static symbol_filter_t annotate_init; 52static symbol_filter_t annotate_init;
50 53
54static const char *cpu_list;
55static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
56
51static int perf_session__add_hist_entry(struct perf_session *session, 57static int perf_session__add_hist_entry(struct perf_session *session,
52 struct addr_location *al, 58 struct addr_location *al,
53 struct perf_sample *sample, 59 struct perf_sample *sample,
@@ -116,6 +122,9 @@ static int process_sample_event(union perf_event *event,
116 if (al.filtered || (hide_unresolved && al.sym == NULL)) 122 if (al.filtered || (hide_unresolved && al.sym == NULL))
117 return 0; 123 return 0;
118 124
125 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
126 return 0;
127
119 if (al.map != NULL) 128 if (al.map != NULL)
120 al.map->dso->hit = 1; 129 al.map->dso->hit = 1;
121 130
@@ -262,6 +271,12 @@ static int __cmd_report(void)
262 if (session == NULL) 271 if (session == NULL)
263 return -ENOMEM; 272 return -ENOMEM;
264 273
274 if (cpu_list) {
275 ret = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
276 if (ret)
277 goto out_delete;
278 }
279
265 if (show_threads) 280 if (show_threads)
266 perf_read_values_init(&show_threads_values); 281 perf_read_values_init(&show_threads_values);
267 282
@@ -386,13 +401,29 @@ parse_callchain_opt(const struct option *opt __used, const char *arg,
386 if (!tok) 401 if (!tok)
387 goto setup; 402 goto setup;
388 403
389 tok2 = strtok(NULL, ",");
390 callchain_param.min_percent = strtod(tok, &endptr); 404 callchain_param.min_percent = strtod(tok, &endptr);
391 if (tok == endptr) 405 if (tok == endptr)
392 return -1; 406 return -1;
393 407
394 if (tok2) 408 /* get the print limit */
409 tok2 = strtok(NULL, ",");
410 if (!tok2)
411 goto setup;
412
413 if (tok2[0] != 'c') {
395 callchain_param.print_limit = strtod(tok2, &endptr); 414 callchain_param.print_limit = strtod(tok2, &endptr);
415 tok2 = strtok(NULL, ",");
416 if (!tok2)
417 goto setup;
418 }
419
420 /* get the call chain order */
421 if (!strcmp(tok2, "caller"))
422 callchain_param.order = ORDER_CALLER;
423 else if (!strcmp(tok2, "callee"))
424 callchain_param.order = ORDER_CALLEE;
425 else
426 return -1;
396setup: 427setup:
397 if (callchain_register_param(&callchain_param) < 0) { 428 if (callchain_register_param(&callchain_param) < 0) {
398 fprintf(stderr, "Can't register callchain params\n"); 429 fprintf(stderr, "Can't register callchain params\n");
@@ -436,9 +467,10 @@ static const struct option options[] = {
436 "regex filter to identify parent, see: '--sort parent'"), 467 "regex filter to identify parent, see: '--sort parent'"),
437 OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other, 468 OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
438 "Only display entries with parent-match"), 469 "Only display entries with parent-match"),
439 OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent", 470 OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent, call_order",
440 "Display callchains using output_type (graph, flat, fractal, or none) and min percent threshold. " 471 "Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold and callchain order. "
441 "Default: fractal,0.5", &parse_callchain_opt, callchain_default_opt), 472 "Default: fractal,0.5,callee", &parse_callchain_opt, callchain_default_opt),
473 OPT_BOOLEAN('G', "inverted", &inverted_callchain, "alias for inverted call graph"),
442 OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", 474 OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
443 "only consider symbols in these dsos"), 475 "only consider symbols in these dsos"),
444 OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]", 476 OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
@@ -455,6 +487,7 @@ static const struct option options[] = {
455 "Only display entries resolved to a symbol"), 487 "Only display entries resolved to a symbol"),
456 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 488 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
457 "Look for files with symbols relative to this directory"), 489 "Look for files with symbols relative to this directory"),
490 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
458 OPT_END() 491 OPT_END()
459}; 492};
460 493
@@ -467,6 +500,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
467 else if (use_tui) 500 else if (use_tui)
468 use_browser = 1; 501 use_browser = 1;
469 502
503 if (inverted_callchain)
504 callchain_param.order = ORDER_CALLER;
505
470 if (strcmp(input_name, "-") != 0) 506 if (strcmp(input_name, "-") != 0)
471 setup_browser(true); 507 setup_browser(true);
472 else 508 else
@@ -504,7 +540,14 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
504 if (parent_pattern != default_parent_pattern) { 540 if (parent_pattern != default_parent_pattern) {
505 if (sort_dimension__add("parent") < 0) 541 if (sort_dimension__add("parent") < 0)
506 return -1; 542 return -1;
507 sort_parent.elide = 1; 543
544 /*
545 * Only show the parent fields if we explicitly
546 * sort that way. If we only use parent machinery
547 * for filtering, we don't want it.
548 */
549 if (!strstr(sort_order, "parent"))
550 sort_parent.elide = 1;
508 } else 551 } else
509 symbol_conf.exclude_other = false; 552 symbol_conf.exclude_other = false;
510 553
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 22747de7234b..09024ec2ab2e 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -13,6 +13,7 @@
13#include "util/util.h" 13#include "util/util.h"
14#include "util/evlist.h" 14#include "util/evlist.h"
15#include "util/evsel.h" 15#include "util/evsel.h"
16#include <linux/bitmap.h>
16 17
17static char const *script_name; 18static char const *script_name;
18static char const *generate_script_lang; 19static char const *generate_script_lang;
@@ -21,6 +22,8 @@ static u64 last_timestamp;
21static u64 nr_unordered; 22static u64 nr_unordered;
22extern const struct option record_options[]; 23extern const struct option record_options[];
23static bool no_callchain; 24static bool no_callchain;
25static const char *cpu_list;
26static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
24 27
25enum perf_output_field { 28enum perf_output_field {
26 PERF_OUTPUT_COMM = 1U << 0, 29 PERF_OUTPUT_COMM = 1U << 0,
@@ -30,7 +33,10 @@ enum perf_output_field {
30 PERF_OUTPUT_CPU = 1U << 4, 33 PERF_OUTPUT_CPU = 1U << 4,
31 PERF_OUTPUT_EVNAME = 1U << 5, 34 PERF_OUTPUT_EVNAME = 1U << 5,
32 PERF_OUTPUT_TRACE = 1U << 6, 35 PERF_OUTPUT_TRACE = 1U << 6,
33 PERF_OUTPUT_SYM = 1U << 7, 36 PERF_OUTPUT_IP = 1U << 7,
37 PERF_OUTPUT_SYM = 1U << 8,
38 PERF_OUTPUT_DSO = 1U << 9,
39 PERF_OUTPUT_ADDR = 1U << 10,
34}; 40};
35 41
36struct output_option { 42struct output_option {
@@ -44,7 +50,10 @@ struct output_option {
44 {.str = "cpu", .field = PERF_OUTPUT_CPU}, 50 {.str = "cpu", .field = PERF_OUTPUT_CPU},
45 {.str = "event", .field = PERF_OUTPUT_EVNAME}, 51 {.str = "event", .field = PERF_OUTPUT_EVNAME},
46 {.str = "trace", .field = PERF_OUTPUT_TRACE}, 52 {.str = "trace", .field = PERF_OUTPUT_TRACE},
53 {.str = "ip", .field = PERF_OUTPUT_IP},
47 {.str = "sym", .field = PERF_OUTPUT_SYM}, 54 {.str = "sym", .field = PERF_OUTPUT_SYM},
55 {.str = "dso", .field = PERF_OUTPUT_DSO},
56 {.str = "addr", .field = PERF_OUTPUT_ADDR},
48}; 57};
49 58
50/* default set to maintain compatibility with current format */ 59/* default set to maintain compatibility with current format */
@@ -60,7 +69,8 @@ static struct {
60 69
61 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 70 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
62 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 71 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
63 PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM, 72 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
73 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO,
64 74
65 .invalid_fields = PERF_OUTPUT_TRACE, 75 .invalid_fields = PERF_OUTPUT_TRACE,
66 }, 76 },
@@ -70,7 +80,8 @@ static struct {
70 80
71 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 81 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
72 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 82 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
73 PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM, 83 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
84 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO,
74 85
75 .invalid_fields = PERF_OUTPUT_TRACE, 86 .invalid_fields = PERF_OUTPUT_TRACE,
76 }, 87 },
@@ -88,7 +99,8 @@ static struct {
88 99
89 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 100 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
90 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 101 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
91 PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM, 102 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
103 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO,
92 104
93 .invalid_fields = PERF_OUTPUT_TRACE, 105 .invalid_fields = PERF_OUTPUT_TRACE,
94 }, 106 },
@@ -157,9 +169,9 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
157 !perf_session__has_traces(session, "record -R")) 169 !perf_session__has_traces(session, "record -R"))
158 return -EINVAL; 170 return -EINVAL;
159 171
160 if (PRINT_FIELD(SYM)) { 172 if (PRINT_FIELD(IP)) {
161 if (perf_event_attr__check_stype(attr, PERF_SAMPLE_IP, "IP", 173 if (perf_event_attr__check_stype(attr, PERF_SAMPLE_IP, "IP",
162 PERF_OUTPUT_SYM)) 174 PERF_OUTPUT_IP))
163 return -EINVAL; 175 return -EINVAL;
164 176
165 if (!no_callchain && 177 if (!no_callchain &&
@@ -167,6 +179,24 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
167 symbol_conf.use_callchain = false; 179 symbol_conf.use_callchain = false;
168 } 180 }
169 181
182 if (PRINT_FIELD(ADDR) &&
183 perf_event_attr__check_stype(attr, PERF_SAMPLE_ADDR, "ADDR",
184 PERF_OUTPUT_ADDR))
185 return -EINVAL;
186
187 if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
188 pr_err("Display of symbols requested but neither sample IP nor "
189 "sample address\nis selected. Hence, no addresses to convert "
190 "to symbols.\n");
191 return -EINVAL;
192 }
193 if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
194 pr_err("Display of DSO requested but neither sample IP nor "
195 "sample address\nis selected. Hence, no addresses to convert "
196 "to DSO.\n");
197 return -EINVAL;
198 }
199
170 if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) && 200 if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
171 perf_event_attr__check_stype(attr, PERF_SAMPLE_TID, "TID", 201 perf_event_attr__check_stype(attr, PERF_SAMPLE_TID, "TID",
172 PERF_OUTPUT_TID|PERF_OUTPUT_PID)) 202 PERF_OUTPUT_TID|PERF_OUTPUT_PID))
@@ -230,7 +260,7 @@ static void print_sample_start(struct perf_sample *sample,
230 if (PRINT_FIELD(COMM)) { 260 if (PRINT_FIELD(COMM)) {
231 if (latency_format) 261 if (latency_format)
232 printf("%8.8s ", thread->comm); 262 printf("%8.8s ", thread->comm);
233 else if (PRINT_FIELD(SYM) && symbol_conf.use_callchain) 263 else if (PRINT_FIELD(IP) && symbol_conf.use_callchain)
234 printf("%s ", thread->comm); 264 printf("%s ", thread->comm);
235 else 265 else
236 printf("%16s ", thread->comm); 266 printf("%16s ", thread->comm);
@@ -271,6 +301,63 @@ static void print_sample_start(struct perf_sample *sample,
271 } 301 }
272} 302}
273 303
304static bool sample_addr_correlates_sym(struct perf_event_attr *attr)
305{
306 if ((attr->type == PERF_TYPE_SOFTWARE) &&
307 ((attr->config == PERF_COUNT_SW_PAGE_FAULTS) ||
308 (attr->config == PERF_COUNT_SW_PAGE_FAULTS_MIN) ||
309 (attr->config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)))
310 return true;
311
312 return false;
313}
314
315static void print_sample_addr(union perf_event *event,
316 struct perf_sample *sample,
317 struct perf_session *session,
318 struct thread *thread,
319 struct perf_event_attr *attr)
320{
321 struct addr_location al;
322 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
323 const char *symname, *dsoname;
324
325 printf("%16" PRIx64, sample->addr);
326
327 if (!sample_addr_correlates_sym(attr))
328 return;
329
330 thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
331 event->ip.pid, sample->addr, &al);
332 if (!al.map)
333 thread__find_addr_map(thread, session, cpumode, MAP__VARIABLE,
334 event->ip.pid, sample->addr, &al);
335
336 al.cpu = sample->cpu;
337 al.sym = NULL;
338
339 if (al.map)
340 al.sym = map__find_symbol(al.map, al.addr, NULL);
341
342 if (PRINT_FIELD(SYM)) {
343 if (al.sym && al.sym->name)
344 symname = al.sym->name;
345 else
346 symname = "";
347
348 printf(" %16s", symname);
349 }
350
351 if (PRINT_FIELD(DSO)) {
352 if (al.map && al.map->dso && al.map->dso->name)
353 dsoname = al.map->dso->name;
354 else
355 dsoname = "";
356
357 printf(" (%s)", dsoname);
358 }
359}
360
274static void process_event(union perf_event *event __unused, 361static void process_event(union perf_event *event __unused,
275 struct perf_sample *sample, 362 struct perf_sample *sample,
276 struct perf_evsel *evsel, 363 struct perf_evsel *evsel,
@@ -288,12 +375,16 @@ static void process_event(union perf_event *event __unused,
288 print_trace_event(sample->cpu, sample->raw_data, 375 print_trace_event(sample->cpu, sample->raw_data,
289 sample->raw_size); 376 sample->raw_size);
290 377
291 if (PRINT_FIELD(SYM)) { 378 if (PRINT_FIELD(ADDR))
379 print_sample_addr(event, sample, session, thread, attr);
380
381 if (PRINT_FIELD(IP)) {
292 if (!symbol_conf.use_callchain) 382 if (!symbol_conf.use_callchain)
293 printf(" "); 383 printf(" ");
294 else 384 else
295 printf("\n"); 385 printf("\n");
296 perf_session__print_symbols(event, sample, session); 386 perf_session__print_ip(event, sample, session,
387 PRINT_FIELD(SYM), PRINT_FIELD(DSO));
297 } 388 }
298 389
299 printf("\n"); 390 printf("\n");
@@ -365,6 +456,10 @@ static int process_sample_event(union perf_event *event,
365 last_timestamp = sample->time; 456 last_timestamp = sample->time;
366 return 0; 457 return 0;
367 } 458 }
459
460 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
461 return 0;
462
368 scripting_ops->process_event(event, sample, evsel, session, thread); 463 scripting_ops->process_event(event, sample, evsel, session, thread);
369 464
370 session->hists.stats.total_period += sample->period; 465 session->hists.stats.total_period += sample->period;
@@ -985,8 +1080,9 @@ static const struct option options[] = {
985 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 1080 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
986 "Look for files with symbols relative to this directory"), 1081 "Look for files with symbols relative to this directory"),
987 OPT_CALLBACK('f', "fields", NULL, "str", 1082 OPT_CALLBACK('f', "fields", NULL, "str",
988 "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,sym", 1083 "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,addr",
989 parse_output_fields), 1084 parse_output_fields),
1085 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
990 1086
991 OPT_END() 1087 OPT_END()
992}; 1088};
@@ -1167,6 +1263,11 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1167 if (session == NULL) 1263 if (session == NULL)
1168 return -ENOMEM; 1264 return -ENOMEM;
1169 1265
1266 if (cpu_list) {
1267 if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap))
1268 return -1;
1269 }
1270
1170 if (!no_callchain) 1271 if (!no_callchain)
1171 symbol_conf.use_callchain = true; 1272 symbol_conf.use_callchain = true;
1172 else 1273 else
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index a9f06715e44d..1ad04ce29c34 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -61,6 +61,8 @@
61#include <locale.h> 61#include <locale.h>
62 62
63#define DEFAULT_SEPARATOR " " 63#define DEFAULT_SEPARATOR " "
64#define CNTR_NOT_SUPPORTED "<not supported>"
65#define CNTR_NOT_COUNTED "<not counted>"
64 66
65static struct perf_event_attr default_attrs[] = { 67static struct perf_event_attr default_attrs[] = {
66 68
@@ -448,6 +450,7 @@ static int run_perf_stat(int argc __used, const char **argv)
448 if (verbose) 450 if (verbose)
449 ui__warning("%s event is not supported by the kernel.\n", 451 ui__warning("%s event is not supported by the kernel.\n",
450 event_name(counter)); 452 event_name(counter));
453 counter->supported = false;
451 continue; 454 continue;
452 } 455 }
453 456
@@ -466,6 +469,7 @@ static int run_perf_stat(int argc __used, const char **argv)
466 die("Not all events could be opened.\n"); 469 die("Not all events could be opened.\n");
467 return -1; 470 return -1;
468 } 471 }
472 counter->supported = true;
469 } 473 }
470 474
471 if (perf_evlist__set_filters(evsel_list)) { 475 if (perf_evlist__set_filters(evsel_list)) {
@@ -513,7 +517,10 @@ static void print_noise_pct(double total, double avg)
513 if (avg) 517 if (avg)
514 pct = 100.0*total/avg; 518 pct = 100.0*total/avg;
515 519
516 fprintf(stderr, " ( +-%6.2f%% )", pct); 520 if (csv_output)
521 fprintf(stderr, "%s%.2f%%", csv_sep, pct);
522 else
523 fprintf(stderr, " ( +-%6.2f%% )", pct);
517} 524}
518 525
519static void print_noise(struct perf_evsel *evsel, double avg) 526static void print_noise(struct perf_evsel *evsel, double avg)
@@ -861,7 +868,7 @@ static void print_counter_aggr(struct perf_evsel *counter)
861 if (scaled == -1) { 868 if (scaled == -1) {
862 fprintf(stderr, "%*s%s%*s", 869 fprintf(stderr, "%*s%s%*s",
863 csv_output ? 0 : 18, 870 csv_output ? 0 : 18,
864 "<not counted>", 871 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
865 csv_sep, 872 csv_sep,
866 csv_output ? 0 : -24, 873 csv_output ? 0 : -24,
867 event_name(counter)); 874 event_name(counter));
@@ -878,13 +885,13 @@ static void print_counter_aggr(struct perf_evsel *counter)
878 else 885 else
879 abs_printout(-1, counter, avg); 886 abs_printout(-1, counter, avg);
880 887
888 print_noise(counter, avg);
889
881 if (csv_output) { 890 if (csv_output) {
882 fputc('\n', stderr); 891 fputc('\n', stderr);
883 return; 892 return;
884 } 893 }
885 894
886 print_noise(counter, avg);
887
888 if (scaled) { 895 if (scaled) {
889 double avg_enabled, avg_running; 896 double avg_enabled, avg_running;
890 897
@@ -914,7 +921,8 @@ static void print_counter(struct perf_evsel *counter)
914 csv_output ? 0 : -4, 921 csv_output ? 0 : -4,
915 evsel_list->cpus->map[cpu], csv_sep, 922 evsel_list->cpus->map[cpu], csv_sep,
916 csv_output ? 0 : 18, 923 csv_output ? 0 : 18,
917 "<not counted>", csv_sep, 924 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
925 csv_sep,
918 csv_output ? 0 : -24, 926 csv_output ? 0 : -24,
919 event_name(counter)); 927 event_name(counter));
920 928
@@ -1024,7 +1032,7 @@ static int stat__set_big_num(const struct option *opt __used,
1024static const struct option options[] = { 1032static const struct option options[] = {
1025 OPT_CALLBACK('e', "event", &evsel_list, "event", 1033 OPT_CALLBACK('e', "event", &evsel_list, "event",
1026 "event selector. use 'perf list' to list available events", 1034 "event selector. use 'perf list' to list available events",
1027 parse_events), 1035 parse_events_option),
1028 OPT_CALLBACK(0, "filter", &evsel_list, "filter", 1036 OPT_CALLBACK(0, "filter", &evsel_list, "filter",
1029 "event filter", parse_filter), 1037 "event filter", parse_filter),
1030 OPT_BOOLEAN('i', "no-inherit", &no_inherit, 1038 OPT_BOOLEAN('i', "no-inherit", &no_inherit,
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index 2da9162262b0..55f4c76f2821 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -12,6 +12,7 @@
12#include "util/parse-events.h" 12#include "util/parse-events.h"
13#include "util/symbol.h" 13#include "util/symbol.h"
14#include "util/thread_map.h" 14#include "util/thread_map.h"
15#include "../../include/linux/hw_breakpoint.h"
15 16
16static long page_size; 17static long page_size;
17 18
@@ -245,8 +246,8 @@ static int trace_event__id(const char *evname)
245 int err = -1, fd; 246 int err = -1, fd;
246 247
247 if (asprintf(&filename, 248 if (asprintf(&filename,
248 "/sys/kernel/debug/tracing/events/syscalls/%s/id", 249 "%s/syscalls/%s/id",
249 evname) < 0) 250 debugfs_path, evname) < 0)
250 return -1; 251 return -1;
251 252
252 fd = open(filename, O_RDONLY); 253 fd = open(filename, O_RDONLY);
@@ -600,6 +601,246 @@ out_free_threads:
600#undef nsyscalls 601#undef nsyscalls
601} 602}
602 603
604#define TEST_ASSERT_VAL(text, cond) \
605do { \
606 if (!cond) { \
607 pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \
608 return -1; \
609 } \
610} while (0)
611
612static int test__checkevent_tracepoint(struct perf_evlist *evlist)
613{
614 struct perf_evsel *evsel = list_entry(evlist->entries.next,
615 struct perf_evsel, node);
616
617 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
618 TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type);
619 TEST_ASSERT_VAL("wrong sample_type",
620 (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) ==
621 evsel->attr.sample_type);
622 TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period);
623 return 0;
624}
625
626static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist)
627{
628 struct perf_evsel *evsel;
629
630 TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);
631
632 list_for_each_entry(evsel, &evlist->entries, node) {
633 TEST_ASSERT_VAL("wrong type",
634 PERF_TYPE_TRACEPOINT == evsel->attr.type);
635 TEST_ASSERT_VAL("wrong sample_type",
636 (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU)
637 == evsel->attr.sample_type);
638 TEST_ASSERT_VAL("wrong sample_period",
639 1 == evsel->attr.sample_period);
640 }
641 return 0;
642}
643
644static int test__checkevent_raw(struct perf_evlist *evlist)
645{
646 struct perf_evsel *evsel = list_entry(evlist->entries.next,
647 struct perf_evsel, node);
648
649 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
650 TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
651 TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config);
652 return 0;
653}
654
655static int test__checkevent_numeric(struct perf_evlist *evlist)
656{
657 struct perf_evsel *evsel = list_entry(evlist->entries.next,
658 struct perf_evsel, node);
659
660 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
661 TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type);
662 TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config);
663 return 0;
664}
665
666static int test__checkevent_symbolic_name(struct perf_evlist *evlist)
667{
668 struct perf_evsel *evsel = list_entry(evlist->entries.next,
669 struct perf_evsel, node);
670
671 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
672 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
673 TEST_ASSERT_VAL("wrong config",
674 PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
675 return 0;
676}
677
678static int test__checkevent_symbolic_alias(struct perf_evlist *evlist)
679{
680 struct perf_evsel *evsel = list_entry(evlist->entries.next,
681 struct perf_evsel, node);
682
683 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
684 TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type);
685 TEST_ASSERT_VAL("wrong config",
686 PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config);
687 return 0;
688}
689
690static int test__checkevent_genhw(struct perf_evlist *evlist)
691{
692 struct perf_evsel *evsel = list_entry(evlist->entries.next,
693 struct perf_evsel, node);
694
695 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
696 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->attr.type);
697 TEST_ASSERT_VAL("wrong config", (1 << 16) == evsel->attr.config);
698 return 0;
699}
700
701static int test__checkevent_breakpoint(struct perf_evlist *evlist)
702{
703 struct perf_evsel *evsel = list_entry(evlist->entries.next,
704 struct perf_evsel, node);
705
706 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
707 TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type);
708 TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
709 TEST_ASSERT_VAL("wrong bp_type", (HW_BREAKPOINT_R | HW_BREAKPOINT_W) ==
710 evsel->attr.bp_type);
711 TEST_ASSERT_VAL("wrong bp_len", HW_BREAKPOINT_LEN_4 ==
712 evsel->attr.bp_len);
713 return 0;
714}
715
716static int test__checkevent_breakpoint_x(struct perf_evlist *evlist)
717{
718 struct perf_evsel *evsel = list_entry(evlist->entries.next,
719 struct perf_evsel, node);
720
721 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
722 TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type);
723 TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
724 TEST_ASSERT_VAL("wrong bp_type",
725 HW_BREAKPOINT_X == evsel->attr.bp_type);
726 TEST_ASSERT_VAL("wrong bp_len", sizeof(long) == evsel->attr.bp_len);
727 return 0;
728}
729
730static int test__checkevent_breakpoint_r(struct perf_evlist *evlist)
731{
732 struct perf_evsel *evsel = list_entry(evlist->entries.next,
733 struct perf_evsel, node);
734
735 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
736 TEST_ASSERT_VAL("wrong type",
737 PERF_TYPE_BREAKPOINT == evsel->attr.type);
738 TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
739 TEST_ASSERT_VAL("wrong bp_type",
740 HW_BREAKPOINT_R == evsel->attr.bp_type);
741 TEST_ASSERT_VAL("wrong bp_len",
742 HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len);
743 return 0;
744}
745
746static int test__checkevent_breakpoint_w(struct perf_evlist *evlist)
747{
748 struct perf_evsel *evsel = list_entry(evlist->entries.next,
749 struct perf_evsel, node);
750
751 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
752 TEST_ASSERT_VAL("wrong type",
753 PERF_TYPE_BREAKPOINT == evsel->attr.type);
754 TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
755 TEST_ASSERT_VAL("wrong bp_type",
756 HW_BREAKPOINT_W == evsel->attr.bp_type);
757 TEST_ASSERT_VAL("wrong bp_len",
758 HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len);
759 return 0;
760}
761
762static struct test__event_st {
763 const char *name;
764 __u32 type;
765 int (*check)(struct perf_evlist *evlist);
766} test__events[] = {
767 {
768 .name = "syscalls:sys_enter_open",
769 .check = test__checkevent_tracepoint,
770 },
771 {
772 .name = "syscalls:*",
773 .check = test__checkevent_tracepoint_multi,
774 },
775 {
776 .name = "r1",
777 .check = test__checkevent_raw,
778 },
779 {
780 .name = "1:1",
781 .check = test__checkevent_numeric,
782 },
783 {
784 .name = "instructions",
785 .check = test__checkevent_symbolic_name,
786 },
787 {
788 .name = "faults",
789 .check = test__checkevent_symbolic_alias,
790 },
791 {
792 .name = "L1-dcache-load-miss",
793 .check = test__checkevent_genhw,
794 },
795 {
796 .name = "mem:0",
797 .check = test__checkevent_breakpoint,
798 },
799 {
800 .name = "mem:0:x",
801 .check = test__checkevent_breakpoint_x,
802 },
803 {
804 .name = "mem:0:r",
805 .check = test__checkevent_breakpoint_r,
806 },
807 {
808 .name = "mem:0:w",
809 .check = test__checkevent_breakpoint_w,
810 },
811};
812
813#define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st))
814
815static int test__parse_events(void)
816{
817 struct perf_evlist *evlist;
818 u_int i;
819 int ret = 0;
820
821 for (i = 0; i < TEST__EVENTS_CNT; i++) {
822 struct test__event_st *e = &test__events[i];
823
824 evlist = perf_evlist__new(NULL, NULL);
825 if (evlist == NULL)
826 break;
827
828 ret = parse_events(evlist, e->name, 0);
829 if (ret) {
830 pr_debug("failed to parse event '%s', err %d\n",
831 e->name, ret);
832 break;
833 }
834
835 ret = e->check(evlist);
836 if (ret)
837 break;
838
839 perf_evlist__delete(evlist);
840 }
841
842 return ret;
843}
603static struct test { 844static struct test {
604 const char *desc; 845 const char *desc;
605 int (*func)(void); 846 int (*func)(void);
@@ -621,6 +862,10 @@ static struct test {
621 .func = test__basic_mmap, 862 .func = test__basic_mmap,
622 }, 863 },
623 { 864 {
865 .desc = "parse events tests",
866 .func = test__parse_events,
867 },
868 {
624 .func = NULL, 869 .func = NULL,
625 }, 870 },
626}; 871};
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index f2f3f4937aa2..a43433f08300 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -990,7 +990,7 @@ static const char * const top_usage[] = {
990static const struct option options[] = { 990static const struct option options[] = {
991 OPT_CALLBACK('e', "event", &top.evlist, "event", 991 OPT_CALLBACK('e', "event", &top.evlist, "event",
992 "event selector. use 'perf list' to list available events", 992 "event selector. use 'perf list' to list available events",
993 parse_events), 993 parse_events_option),
994 OPT_INTEGER('c', "count", &default_interval, 994 OPT_INTEGER('c', "count", &default_interval,
995 "event period to sample"), 995 "event period to sample"),
996 OPT_INTEGER('p', "pid", &top.target_pid, 996 OPT_INTEGER('p', "pid", &top.target_pid,
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 1a79df9f739f..9b4ff16cac96 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -14,6 +14,11 @@ enum chain_mode {
14 CHAIN_GRAPH_REL 14 CHAIN_GRAPH_REL
15}; 15};
16 16
17enum chain_order {
18 ORDER_CALLER,
19 ORDER_CALLEE
20};
21
17struct callchain_node { 22struct callchain_node {
18 struct callchain_node *parent; 23 struct callchain_node *parent;
19 struct list_head siblings; 24 struct list_head siblings;
@@ -41,6 +46,7 @@ struct callchain_param {
41 u32 print_limit; 46 u32 print_limit;
42 double min_percent; 47 double min_percent;
43 sort_chain_func_t sort; 48 sort_chain_func_t sort;
49 enum chain_order order;
44}; 50};
45 51
46struct callchain_list { 52struct callchain_list {
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
new file mode 100644
index 000000000000..fddf40f30d3e
--- /dev/null
+++ b/tools/perf/util/dwarf-aux.c
@@ -0,0 +1,663 @@
1/*
2 * dwarf-aux.c : libdw auxiliary interfaces
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 */
19
20#include <stdbool.h>
21#include "util.h"
22#include "debug.h"
23#include "dwarf-aux.h"
24
25/**
26 * cu_find_realpath - Find the realpath of the target file
27 * @cu_die: A DIE(dwarf information entry) of CU(compilation Unit)
28 * @fname: The tail filename of the target file
29 *
30 * Find the real(long) path of @fname in @cu_die.
31 */
32const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname)
33{
34 Dwarf_Files *files;
35 size_t nfiles, i;
36 const char *src = NULL;
37 int ret;
38
39 if (!fname)
40 return NULL;
41
42 ret = dwarf_getsrcfiles(cu_die, &files, &nfiles);
43 if (ret != 0)
44 return NULL;
45
46 for (i = 0; i < nfiles; i++) {
47 src = dwarf_filesrc(files, i, NULL, NULL);
48 if (strtailcmp(src, fname) == 0)
49 break;
50 }
51 if (i == nfiles)
52 return NULL;
53 return src;
54}
55
56/**
57 * cu_get_comp_dir - Get the path of compilation directory
58 * @cu_die: a CU DIE
59 *
60 * Get the path of compilation directory of given @cu_die.
61 * Since this depends on DW_AT_comp_dir, older gcc will not
62 * embedded it. In that case, this returns NULL.
63 */
64const char *cu_get_comp_dir(Dwarf_Die *cu_die)
65{
66 Dwarf_Attribute attr;
67 if (dwarf_attr(cu_die, DW_AT_comp_dir, &attr) == NULL)
68 return NULL;
69 return dwarf_formstring(&attr);
70}
71
72/**
73 * cu_find_lineinfo - Get a line number and file name for given address
74 * @cu_die: a CU DIE
75 * @addr: An address
76 * @fname: a pointer which returns the file name string
77 * @lineno: a pointer which returns the line number
78 *
79 * Find a line number and file name for @addr in @cu_die.
80 */
81int cu_find_lineinfo(Dwarf_Die *cu_die, unsigned long addr,
82 const char **fname, int *lineno)
83{
84 Dwarf_Line *line;
85 Dwarf_Addr laddr;
86
87 line = dwarf_getsrc_die(cu_die, (Dwarf_Addr)addr);
88 if (line && dwarf_lineaddr(line, &laddr) == 0 &&
89 addr == (unsigned long)laddr && dwarf_lineno(line, lineno) == 0) {
90 *fname = dwarf_linesrc(line, NULL, NULL);
91 if (!*fname)
92 /* line number is useless without filename */
93 *lineno = 0;
94 }
95
96 return *lineno ?: -ENOENT;
97}
98
99/**
100 * die_compare_name - Compare diename and tname
101 * @dw_die: a DIE
102 * @tname: a string of target name
103 *
104 * Compare the name of @dw_die and @tname. Return false if @dw_die has no name.
105 */
106bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
107{
108 const char *name;
109 name = dwarf_diename(dw_die);
110 return name ? (strcmp(tname, name) == 0) : false;
111}
112
113/**
114 * die_get_call_lineno - Get callsite line number of inline-function instance
115 * @in_die: a DIE of an inlined function instance
116 *
117 * Get call-site line number of @in_die. This means from where the inline
118 * function is called.
119 */
120int die_get_call_lineno(Dwarf_Die *in_die)
121{
122 Dwarf_Attribute attr;
123 Dwarf_Word ret;
124
125 if (!dwarf_attr(in_die, DW_AT_call_line, &attr))
126 return -ENOENT;
127
128 dwarf_formudata(&attr, &ret);
129 return (int)ret;
130}
131
132/**
133 * die_get_type - Get type DIE
134 * @vr_die: a DIE of a variable
135 * @die_mem: where to store a type DIE
136 *
137 * Get a DIE of the type of given variable (@vr_die), and store
138 * it to die_mem. Return NULL if fails to get a type DIE.
139 */
140Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
141{
142 Dwarf_Attribute attr;
143
144 if (dwarf_attr_integrate(vr_die, DW_AT_type, &attr) &&
145 dwarf_formref_die(&attr, die_mem))
146 return die_mem;
147 else
148 return NULL;
149}
150
151/* Get a type die, but skip qualifiers */
152static Dwarf_Die *__die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
153{
154 int tag;
155
156 do {
157 vr_die = die_get_type(vr_die, die_mem);
158 if (!vr_die)
159 break;
160 tag = dwarf_tag(vr_die);
161 } while (tag == DW_TAG_const_type ||
162 tag == DW_TAG_restrict_type ||
163 tag == DW_TAG_volatile_type ||
164 tag == DW_TAG_shared_type);
165
166 return vr_die;
167}
168
169/**
170 * die_get_real_type - Get a type die, but skip qualifiers and typedef
171 * @vr_die: a DIE of a variable
172 * @die_mem: where to store a type DIE
173 *
174 * Get a DIE of the type of given variable (@vr_die), and store
175 * it to die_mem. Return NULL if fails to get a type DIE.
176 * If the type is qualifiers (e.g. const) or typedef, this skips it
177 * and tries to find real type (structure or basic types, e.g. int).
178 */
179Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
180{
181 do {
182 vr_die = __die_get_real_type(vr_die, die_mem);
183 } while (vr_die && dwarf_tag(vr_die) == DW_TAG_typedef);
184
185 return vr_die;
186}
187
188/* Get attribute and translate it as a udata */
189static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name,
190 Dwarf_Word *result)
191{
192 Dwarf_Attribute attr;
193
194 if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
195 dwarf_formudata(&attr, result) != 0)
196 return -ENOENT;
197
198 return 0;
199}
200
201/**
202 * die_is_signed_type - Check whether a type DIE is signed or not
203 * @tp_die: a DIE of a type
204 *
205 * Get the encoding of @tp_die and return true if the encoding
206 * is signed.
207 */
208bool die_is_signed_type(Dwarf_Die *tp_die)
209{
210 Dwarf_Word ret;
211
212 if (die_get_attr_udata(tp_die, DW_AT_encoding, &ret))
213 return false;
214
215 return (ret == DW_ATE_signed_char || ret == DW_ATE_signed ||
216 ret == DW_ATE_signed_fixed);
217}
218
219/**
220 * die_get_data_member_location - Get the data-member offset
221 * @mb_die: a DIE of a member of a data structure
222 * @offs: The offset of the member in the data structure
223 *
224 * Get the offset of @mb_die in the data structure including @mb_die, and
225 * stores result offset to @offs. If any error occurs this returns errno.
226 */
227int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
228{
229 Dwarf_Attribute attr;
230 Dwarf_Op *expr;
231 size_t nexpr;
232 int ret;
233
234 if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) == NULL)
235 return -ENOENT;
236
237 if (dwarf_formudata(&attr, offs) != 0) {
238 /* DW_AT_data_member_location should be DW_OP_plus_uconst */
239 ret = dwarf_getlocation(&attr, &expr, &nexpr);
240 if (ret < 0 || nexpr == 0)
241 return -ENOENT;
242
243 if (expr[0].atom != DW_OP_plus_uconst || nexpr != 1) {
244 pr_debug("Unable to get offset:Unexpected OP %x (%zd)\n",
245 expr[0].atom, nexpr);
246 return -ENOTSUP;
247 }
248 *offs = (Dwarf_Word)expr[0].number;
249 }
250 return 0;
251}
252
253/**
254 * die_find_child - Generic DIE search function in DIE tree
255 * @rt_die: a root DIE
256 * @callback: a callback function
257 * @data: a user data passed to the callback function
258 * @die_mem: a buffer for result DIE
259 *
260 * Trace DIE tree from @rt_die and call @callback for each child DIE.
261 * If @callback returns DIE_FIND_CB_END, this stores the DIE into
262 * @die_mem and returns it. If @callback returns DIE_FIND_CB_CONTINUE,
263 * this continues to trace the tree. Optionally, @callback can return
264 * DIE_FIND_CB_CHILD and DIE_FIND_CB_SIBLING, those means trace only
265 * the children and trace only the siblings respectively.
266 * Returns NULL if @callback can't find any appropriate DIE.
267 */
268Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
269 int (*callback)(Dwarf_Die *, void *),
270 void *data, Dwarf_Die *die_mem)
271{
272 Dwarf_Die child_die;
273 int ret;
274
275 ret = dwarf_child(rt_die, die_mem);
276 if (ret != 0)
277 return NULL;
278
279 do {
280 ret = callback(die_mem, data);
281 if (ret == DIE_FIND_CB_END)
282 return die_mem;
283
284 if ((ret & DIE_FIND_CB_CHILD) &&
285 die_find_child(die_mem, callback, data, &child_die)) {
286 memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
287 return die_mem;
288 }
289 } while ((ret & DIE_FIND_CB_SIBLING) &&
290 dwarf_siblingof(die_mem, die_mem) == 0);
291
292 return NULL;
293}
294
295struct __addr_die_search_param {
296 Dwarf_Addr addr;
297 Dwarf_Die *die_mem;
298};
299
300/* die_find callback for non-inlined function search */
301static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
302{
303 struct __addr_die_search_param *ad = data;
304
305 if (dwarf_tag(fn_die) == DW_TAG_subprogram &&
306 dwarf_haspc(fn_die, ad->addr)) {
307 memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die));
308 return DWARF_CB_ABORT;
309 }
310 return DWARF_CB_OK;
311}
312
313/**
314 * die_find_realfunc - Search a non-inlined function at given address
315 * @cu_die: a CU DIE which including @addr
316 * @addr: target address
317 * @die_mem: a buffer for result DIE
318 *
319 * Search a non-inlined function DIE which includes @addr. Stores the
320 * DIE to @die_mem and returns it if found. Returns NULl if failed.
321 */
322Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
323 Dwarf_Die *die_mem)
324{
325 struct __addr_die_search_param ad;
326 ad.addr = addr;
327 ad.die_mem = die_mem;
328 /* dwarf_getscopes can't find subprogram. */
329 if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0))
330 return NULL;
331 else
332 return die_mem;
333}
334
335/* die_find callback for inline function search */
336static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
337{
338 Dwarf_Addr *addr = data;
339
340 if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine &&
341 dwarf_haspc(die_mem, *addr))
342 return DIE_FIND_CB_END;
343
344 return DIE_FIND_CB_CONTINUE;
345}
346
347/**
348 * die_find_inlinefunc - Search an inlined function at given address
349 * @cu_die: a CU DIE which including @addr
350 * @addr: target address
351 * @die_mem: a buffer for result DIE
352 *
353 * Search an inlined function DIE which includes @addr. Stores the
354 * DIE to @die_mem and returns it if found. Returns NULl if failed.
355 * If several inlined functions are expanded recursively, this trace
356 * it and returns deepest one.
357 */
358Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
359 Dwarf_Die *die_mem)
360{
361 Dwarf_Die tmp_die;
362
363 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, &tmp_die);
364 if (!sp_die)
365 return NULL;
366
367 /* Inlined function could be recursive. Trace it until fail */
368 while (sp_die) {
369 memcpy(die_mem, sp_die, sizeof(Dwarf_Die));
370 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr,
371 &tmp_die);
372 }
373
374 return die_mem;
375}
376
377/* Line walker internal parameters */
378struct __line_walk_param {
379 const char *fname;
380 line_walk_callback_t callback;
381 void *data;
382 int retval;
383};
384
385static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data)
386{
387 struct __line_walk_param *lw = data;
388 Dwarf_Addr addr;
389 int lineno;
390
391 if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) {
392 lineno = die_get_call_lineno(in_die);
393 if (lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) {
394 lw->retval = lw->callback(lw->fname, lineno, addr,
395 lw->data);
396 if (lw->retval != 0)
397 return DIE_FIND_CB_END;
398 }
399 }
400 return DIE_FIND_CB_SIBLING;
401}
402
403/* Walk on lines of blocks included in given DIE */
404static int __die_walk_funclines(Dwarf_Die *sp_die,
405 line_walk_callback_t callback, void *data)
406{
407 struct __line_walk_param lw = {
408 .callback = callback,
409 .data = data,
410 .retval = 0,
411 };
412 Dwarf_Die die_mem;
413 Dwarf_Addr addr;
414 int lineno;
415
416 /* Handle function declaration line */
417 lw.fname = dwarf_decl_file(sp_die);
418 if (lw.fname && dwarf_decl_line(sp_die, &lineno) == 0 &&
419 dwarf_entrypc(sp_die, &addr) == 0) {
420 lw.retval = callback(lw.fname, lineno, addr, data);
421 if (lw.retval != 0)
422 goto done;
423 }
424 die_find_child(sp_die, __die_walk_funclines_cb, &lw, &die_mem);
425done:
426 return lw.retval;
427}
428
429static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data)
430{
431 struct __line_walk_param *lw = data;
432
433 lw->retval = __die_walk_funclines(sp_die, lw->callback, lw->data);
434 if (lw->retval != 0)
435 return DWARF_CB_ABORT;
436
437 return DWARF_CB_OK;
438}
439
440/**
441 * die_walk_lines - Walk on lines inside given DIE
442 * @rt_die: a root DIE (CU or subprogram)
443 * @callback: callback routine
444 * @data: user data
445 *
446 * Walk on all lines inside given @rt_die and call @callback on each line.
447 * If the @rt_die is a function, walk only on the lines inside the function,
448 * otherwise @rt_die must be a CU DIE.
449 * Note that this walks not only dwarf line list, but also function entries
450 * and inline call-site.
451 */
452int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)
453{
454 Dwarf_Lines *lines;
455 Dwarf_Line *line;
456 Dwarf_Addr addr;
457 const char *fname;
458 int lineno, ret = 0;
459 Dwarf_Die die_mem, *cu_die;
460 size_t nlines, i;
461
462 /* Get the CU die */
463 if (dwarf_tag(rt_die) == DW_TAG_subprogram)
464 cu_die = dwarf_diecu(rt_die, &die_mem, NULL, NULL);
465 else
466 cu_die = rt_die;
467 if (!cu_die) {
468 pr_debug2("Failed to get CU from subprogram\n");
469 return -EINVAL;
470 }
471
472 /* Get lines list in the CU */
473 if (dwarf_getsrclines(cu_die, &lines, &nlines) != 0) {
474 pr_debug2("Failed to get source lines on this CU.\n");
475 return -ENOENT;
476 }
477 pr_debug2("Get %zd lines from this CU\n", nlines);
478
479 /* Walk on the lines on lines list */
480 for (i = 0; i < nlines; i++) {
481 line = dwarf_onesrcline(lines, i);
482 if (line == NULL ||
483 dwarf_lineno(line, &lineno) != 0 ||
484 dwarf_lineaddr(line, &addr) != 0) {
485 pr_debug2("Failed to get line info. "
486 "Possible error in debuginfo.\n");
487 continue;
488 }
489 /* Filter lines based on address */
490 if (rt_die != cu_die)
491 /*
492 * Address filtering
493 * The line is included in given function, and
494 * no inline block includes it.
495 */
496 if (!dwarf_haspc(rt_die, addr) ||
497 die_find_inlinefunc(rt_die, addr, &die_mem))
498 continue;
499 /* Get source line */
500 fname = dwarf_linesrc(line, NULL, NULL);
501
502 ret = callback(fname, lineno, addr, data);
503 if (ret != 0)
504 return ret;
505 }
506
507 /*
508 * Dwarf lines doesn't include function declarations and inlined
509 * subroutines. We have to check functions list or given function.
510 */
511 if (rt_die != cu_die)
512 ret = __die_walk_funclines(rt_die, callback, data);
513 else {
514 struct __line_walk_param param = {
515 .callback = callback,
516 .data = data,
517 .retval = 0,
518 };
519 dwarf_getfuncs(cu_die, __die_walk_culines_cb, &param, 0);
520 ret = param.retval;
521 }
522
523 return ret;
524}
525
526struct __find_variable_param {
527 const char *name;
528 Dwarf_Addr addr;
529};
530
531static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data)
532{
533 struct __find_variable_param *fvp = data;
534 int tag;
535
536 tag = dwarf_tag(die_mem);
537 if ((tag == DW_TAG_formal_parameter ||
538 tag == DW_TAG_variable) &&
539 die_compare_name(die_mem, fvp->name))
540 return DIE_FIND_CB_END;
541
542 if (dwarf_haspc(die_mem, fvp->addr))
543 return DIE_FIND_CB_CONTINUE;
544 else
545 return DIE_FIND_CB_SIBLING;
546}
547
548/**
549 * die_find_variable_at - Find a given name variable at given address
550 * @sp_die: a function DIE
551 * @name: variable name
552 * @addr: address
553 * @die_mem: a buffer for result DIE
554 *
555 * Find a variable DIE called @name at @addr in @sp_die.
556 */
557Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name,
558 Dwarf_Addr addr, Dwarf_Die *die_mem)
559{
560 struct __find_variable_param fvp = { .name = name, .addr = addr};
561
562 return die_find_child(sp_die, __die_find_variable_cb, (void *)&fvp,
563 die_mem);
564}
565
566static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
567{
568 const char *name = data;
569
570 if ((dwarf_tag(die_mem) == DW_TAG_member) &&
571 die_compare_name(die_mem, name))
572 return DIE_FIND_CB_END;
573
574 return DIE_FIND_CB_SIBLING;
575}
576
577/**
578 * die_find_member - Find a given name member in a data structure
579 * @st_die: a data structure type DIE
580 * @name: member name
581 * @die_mem: a buffer for result DIE
582 *
583 * Find a member DIE called @name in @st_die.
584 */
585Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
586 Dwarf_Die *die_mem)
587{
588 return die_find_child(st_die, __die_find_member_cb, (void *)name,
589 die_mem);
590}
591
592/**
593 * die_get_typename - Get the name of given variable DIE
594 * @vr_die: a variable DIE
595 * @buf: a buffer for result type name
596 * @len: a max-length of @buf
597 *
598 * Get the name of @vr_die and stores it to @buf. Return the actual length
599 * of type name if succeeded. Return -E2BIG if @len is not enough long, and
600 * Return -ENOENT if failed to find type name.
601 * Note that the result will stores typedef name if possible, and stores
602 * "*(function_type)" if the type is a function pointer.
603 */
604int die_get_typename(Dwarf_Die *vr_die, char *buf, int len)
605{
606 Dwarf_Die type;
607 int tag, ret, ret2;
608 const char *tmp = "";
609
610 if (__die_get_real_type(vr_die, &type) == NULL)
611 return -ENOENT;
612
613 tag = dwarf_tag(&type);
614 if (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)
615 tmp = "*";
616 else if (tag == DW_TAG_subroutine_type) {
617 /* Function pointer */
618 ret = snprintf(buf, len, "(function_type)");
619 return (ret >= len) ? -E2BIG : ret;
620 } else {
621 if (!dwarf_diename(&type))
622 return -ENOENT;
623 if (tag == DW_TAG_union_type)
624 tmp = "union ";
625 else if (tag == DW_TAG_structure_type)
626 tmp = "struct ";
627 /* Write a base name */
628 ret = snprintf(buf, len, "%s%s", tmp, dwarf_diename(&type));
629 return (ret >= len) ? -E2BIG : ret;
630 }
631 ret = die_get_typename(&type, buf, len);
632 if (ret > 0) {
633 ret2 = snprintf(buf + ret, len - ret, "%s", tmp);
634 ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret;
635 }
636 return ret;
637}
638
639/**
640 * die_get_varname - Get the name and type of given variable DIE
641 * @vr_die: a variable DIE
642 * @buf: a buffer for type and variable name
643 * @len: the max-length of @buf
644 *
645 * Get the name and type of @vr_die and stores it in @buf as "type\tname".
646 */
647int die_get_varname(Dwarf_Die *vr_die, char *buf, int len)
648{
649 int ret, ret2;
650
651 ret = die_get_typename(vr_die, buf, len);
652 if (ret < 0) {
653 pr_debug("Failed to get type, make it unknown.\n");
654 ret = snprintf(buf, len, "(unknown_type)");
655 }
656 if (ret > 0) {
657 ret2 = snprintf(buf + ret, len - ret, "\t%s",
658 dwarf_diename(vr_die));
659 ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret;
660 }
661 return ret;
662}
663
diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h
new file mode 100644
index 000000000000..bc3b21167e70
--- /dev/null
+++ b/tools/perf/util/dwarf-aux.h
@@ -0,0 +1,100 @@
1#ifndef _DWARF_AUX_H
2#define _DWARF_AUX_H
3/*
4 * dwarf-aux.h : libdw auxiliary interfaces
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22#include <dwarf.h>
23#include <elfutils/libdw.h>
24#include <elfutils/libdwfl.h>
25#include <elfutils/version.h>
26
27/* Find the realpath of the target file */
28extern const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname);
29
30/* Get DW_AT_comp_dir (should be NULL with older gcc) */
31extern const char *cu_get_comp_dir(Dwarf_Die *cu_die);
32
33/* Get a line number and file name for given address */
34extern int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr,
35 const char **fname, int *lineno);
36
37/* Compare diename and tname */
38extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname);
39
40/* Get callsite line number of inline-function instance */
41extern int die_get_call_lineno(Dwarf_Die *in_die);
42
43/* Get type die */
44extern Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem);
45
46/* Get a type die, but skip qualifiers and typedef */
47extern Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem);
48
49/* Check whether the DIE is signed or not */
50extern bool die_is_signed_type(Dwarf_Die *tp_die);
51
52/* Get data_member_location offset */
53extern int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs);
54
55/* Return values for die_find_child() callbacks */
56enum {
57 DIE_FIND_CB_END = 0, /* End of Search */
58 DIE_FIND_CB_CHILD = 1, /* Search only children */
59 DIE_FIND_CB_SIBLING = 2, /* Search only siblings */
60 DIE_FIND_CB_CONTINUE = 3, /* Search children and siblings */
61};
62
63/* Search child DIEs */
64extern Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
65 int (*callback)(Dwarf_Die *, void *),
66 void *data, Dwarf_Die *die_mem);
67
68/* Search a non-inlined function including given address */
69extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
70 Dwarf_Die *die_mem);
71
72/* Search an inlined function including given address */
73extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
74 Dwarf_Die *die_mem);
75
76/* Walker on lines (Note: line number will not be sorted) */
77typedef int (* line_walk_callback_t) (const char *fname, int lineno,
78 Dwarf_Addr addr, void *data);
79
80/*
81 * Walk on lines inside given DIE. If the DIE is a subprogram, walk only on
82 * the lines inside the subprogram, otherwise the DIE must be a CU DIE.
83 */
84extern int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback,
85 void *data);
86
87/* Find a variable called 'name' at given address */
88extern Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name,
89 Dwarf_Addr addr, Dwarf_Die *die_mem);
90
91/* Find a member called 'name' */
92extern Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
93 Dwarf_Die *die_mem);
94
95/* Get the name of given variable DIE */
96extern int die_get_typename(Dwarf_Die *vr_die, char *buf, int len);
97
98/* Get the name and type of given variable DIE, stored as "type\tname" */
99extern int die_get_varname(Dwarf_Die *vr_die, char *buf, int len);
100#endif
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 0239eb87b232..a03a36b7908a 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -377,6 +377,7 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
377 array++; 377 array++;
378 } 378 }
379 379
380 data->addr = 0;
380 if (type & PERF_SAMPLE_ADDR) { 381 if (type & PERF_SAMPLE_ADDR) {
381 data->addr = *array; 382 data->addr = *array;
382 array++; 383 array++;
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 7e9366e4490b..e9a31554e265 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -61,6 +61,7 @@ struct perf_evsel {
61 off_t id_offset; 61 off_t id_offset;
62 }; 62 };
63 struct cgroup_sel *cgrp; 63 struct cgroup_sel *cgrp;
64 bool supported;
64}; 65};
65 66
66struct cpu_map; 67struct cpu_map;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index afb0849fe530..cb2959a3fb43 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -877,9 +877,12 @@ int perf_session__read_header(struct perf_session *session, int fd)
877 struct perf_evsel *evsel; 877 struct perf_evsel *evsel;
878 off_t tmp; 878 off_t tmp;
879 879
880 if (perf_header__getbuffer64(header, fd, &f_attr, sizeof(f_attr))) 880 if (readn(fd, &f_attr, sizeof(f_attr)) <= 0)
881 goto out_errno; 881 goto out_errno;
882 882
883 if (header->needs_swap)
884 perf_event__attr_swap(&f_attr.attr);
885
883 tmp = lseek(fd, 0, SEEK_CUR); 886 tmp = lseek(fd, 0, SEEK_CUR);
884 evsel = perf_evsel__new(&f_attr.attr, i); 887 evsel = perf_evsel__new(&f_attr.attr, i);
885 888
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 627a02e03c57..677e1da6bb3e 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -14,7 +14,8 @@ enum hist_filter {
14 14
15struct callchain_param callchain_param = { 15struct callchain_param callchain_param = {
16 .mode = CHAIN_GRAPH_REL, 16 .mode = CHAIN_GRAPH_REL,
17 .min_percent = 0.5 17 .min_percent = 0.5,
18 .order = ORDER_CALLEE
18}; 19};
19 20
20u16 hists__col_len(struct hists *self, enum hist_column col) 21u16 hists__col_len(struct hists *self, enum hist_column col)
@@ -846,6 +847,9 @@ print_entries:
846 for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { 847 for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
847 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 848 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
848 849
850 if (h->filtered)
851 continue;
852
849 if (show_displacement) { 853 if (show_displacement) {
850 if (h->pair != NULL) 854 if (h->pair != NULL)
851 displacement = ((long)h->pair->position - 855 displacement = ((long)h->pair->position -
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 41982c373faf..4ea7e19f5251 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -86,22 +86,24 @@ static const char *sw_event_names[PERF_COUNT_SW_MAX] = {
86 86
87#define MAX_ALIASES 8 87#define MAX_ALIASES 8
88 88
89static const char *hw_cache[][MAX_ALIASES] = { 89static const char *hw_cache[PERF_COUNT_HW_CACHE_MAX][MAX_ALIASES] = {
90 { "L1-dcache", "l1-d", "l1d", "L1-data", }, 90 { "L1-dcache", "l1-d", "l1d", "L1-data", },
91 { "L1-icache", "l1-i", "l1i", "L1-instruction", }, 91 { "L1-icache", "l1-i", "l1i", "L1-instruction", },
92 { "LLC", "L2" }, 92 { "LLC", "L2", },
93 { "dTLB", "d-tlb", "Data-TLB", }, 93 { "dTLB", "d-tlb", "Data-TLB", },
94 { "iTLB", "i-tlb", "Instruction-TLB", }, 94 { "iTLB", "i-tlb", "Instruction-TLB", },
95 { "branch", "branches", "bpu", "btb", "bpc", }, 95 { "branch", "branches", "bpu", "btb", "bpc", },
96 { "node", },
96}; 97};
97 98
98static const char *hw_cache_op[][MAX_ALIASES] = { 99static const char *hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX][MAX_ALIASES] = {
99 { "load", "loads", "read", }, 100 { "load", "loads", "read", },
100 { "store", "stores", "write", }, 101 { "store", "stores", "write", },
101 { "prefetch", "prefetches", "speculative-read", "speculative-load", }, 102 { "prefetch", "prefetches", "speculative-read", "speculative-load", },
102}; 103};
103 104
104static const char *hw_cache_result[][MAX_ALIASES] = { 105static const char *hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX]
106 [MAX_ALIASES] = {
105 { "refs", "Reference", "ops", "access", }, 107 { "refs", "Reference", "ops", "access", },
106 { "misses", "miss", }, 108 { "misses", "miss", },
107}; 109};
@@ -124,6 +126,7 @@ static unsigned long hw_cache_stat[C(MAX)] = {
124 [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 126 [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
125 [C(ITLB)] = (CACHE_READ), 127 [C(ITLB)] = (CACHE_READ),
126 [C(BPU)] = (CACHE_READ), 128 [C(BPU)] = (CACHE_READ),
129 [C(NODE)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
127}; 130};
128 131
129#define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ 132#define for_each_subsystem(sys_dir, sys_dirent, sys_next) \
@@ -393,7 +396,7 @@ parse_generic_hw_event(const char **str, struct perf_event_attr *attr)
393 PERF_COUNT_HW_CACHE_OP_MAX); 396 PERF_COUNT_HW_CACHE_OP_MAX);
394 if (cache_op >= 0) { 397 if (cache_op >= 0) {
395 if (!is_cache_op_valid(cache_type, cache_op)) 398 if (!is_cache_op_valid(cache_type, cache_op))
396 return 0; 399 return EVT_FAILED;
397 continue; 400 continue;
398 } 401 }
399 } 402 }
@@ -475,7 +478,7 @@ parse_single_tracepoint_event(char *sys_name,
475/* sys + ':' + event + ':' + flags*/ 478/* sys + ':' + event + ':' + flags*/
476#define MAX_EVOPT_LEN (MAX_EVENT_LENGTH * 2 + 2 + 128) 479#define MAX_EVOPT_LEN (MAX_EVENT_LENGTH * 2 + 2 + 128)
477static enum event_result 480static enum event_result
478parse_multiple_tracepoint_event(const struct option *opt, char *sys_name, 481parse_multiple_tracepoint_event(struct perf_evlist *evlist, char *sys_name,
479 const char *evt_exp, char *flags) 482 const char *evt_exp, char *flags)
480{ 483{
481 char evt_path[MAXPATHLEN]; 484 char evt_path[MAXPATHLEN];
@@ -509,7 +512,7 @@ parse_multiple_tracepoint_event(const struct option *opt, char *sys_name,
509 if (len < 0) 512 if (len < 0)
510 return EVT_FAILED; 513 return EVT_FAILED;
511 514
512 if (parse_events(opt, event_opt, 0)) 515 if (parse_events(evlist, event_opt, 0))
513 return EVT_FAILED; 516 return EVT_FAILED;
514 } 517 }
515 518
@@ -517,7 +520,7 @@ parse_multiple_tracepoint_event(const struct option *opt, char *sys_name,
517} 520}
518 521
519static enum event_result 522static enum event_result
520parse_tracepoint_event(const struct option *opt, const char **strp, 523parse_tracepoint_event(struct perf_evlist *evlist, const char **strp,
521 struct perf_event_attr *attr) 524 struct perf_event_attr *attr)
522{ 525{
523 const char *evt_name; 526 const char *evt_name;
@@ -557,8 +560,8 @@ parse_tracepoint_event(const struct option *opt, const char **strp,
557 return EVT_FAILED; 560 return EVT_FAILED;
558 if (strpbrk(evt_name, "*?")) { 561 if (strpbrk(evt_name, "*?")) {
559 *strp += strlen(sys_name) + evt_length + 1; /* 1 == the ':' */ 562 *strp += strlen(sys_name) + evt_length + 1; /* 1 == the ':' */
560 return parse_multiple_tracepoint_event(opt, sys_name, evt_name, 563 return parse_multiple_tracepoint_event(evlist, sys_name,
561 flags); 564 evt_name, flags);
562 } else { 565 } else {
563 return parse_single_tracepoint_event(sys_name, evt_name, 566 return parse_single_tracepoint_event(sys_name, evt_name,
564 evt_length, attr, strp); 567 evt_length, attr, strp);
@@ -778,12 +781,12 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr)
778 * Symbolic names are (almost) exactly matched. 781 * Symbolic names are (almost) exactly matched.
779 */ 782 */
780static enum event_result 783static enum event_result
781parse_event_symbols(const struct option *opt, const char **str, 784parse_event_symbols(struct perf_evlist *evlist, const char **str,
782 struct perf_event_attr *attr) 785 struct perf_event_attr *attr)
783{ 786{
784 enum event_result ret; 787 enum event_result ret;
785 788
786 ret = parse_tracepoint_event(opt, str, attr); 789 ret = parse_tracepoint_event(evlist, str, attr);
787 if (ret != EVT_FAILED) 790 if (ret != EVT_FAILED)
788 goto modifier; 791 goto modifier;
789 792
@@ -822,9 +825,8 @@ modifier:
822 return ret; 825 return ret;
823} 826}
824 827
825int parse_events(const struct option *opt, const char *str, int unset __used) 828int parse_events(struct perf_evlist *evlist , const char *str, int unset __used)
826{ 829{
827 struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
828 struct perf_event_attr attr; 830 struct perf_event_attr attr;
829 enum event_result ret; 831 enum event_result ret;
830 const char *ostr; 832 const char *ostr;
@@ -832,7 +834,7 @@ int parse_events(const struct option *opt, const char *str, int unset __used)
832 for (;;) { 834 for (;;) {
833 ostr = str; 835 ostr = str;
834 memset(&attr, 0, sizeof(attr)); 836 memset(&attr, 0, sizeof(attr));
835 ret = parse_event_symbols(opt, &str, &attr); 837 ret = parse_event_symbols(evlist, &str, &attr);
836 if (ret == EVT_FAILED) 838 if (ret == EVT_FAILED)
837 return -1; 839 return -1;
838 840
@@ -863,6 +865,13 @@ int parse_events(const struct option *opt, const char *str, int unset __used)
863 return 0; 865 return 0;
864} 866}
865 867
868int parse_events_option(const struct option *opt, const char *str,
869 int unset __used)
870{
871 struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
872 return parse_events(evlist, str, unset);
873}
874
866int parse_filter(const struct option *opt, const char *str, 875int parse_filter(const struct option *opt, const char *str,
867 int unset __used) 876 int unset __used)
868{ 877{
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 746d3fcbfc2a..2f8e375e038d 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -8,6 +8,7 @@
8 8
9struct list_head; 9struct list_head;
10struct perf_evsel; 10struct perf_evsel;
11struct perf_evlist;
11 12
12struct option; 13struct option;
13 14
@@ -24,7 +25,10 @@ const char *event_type(int type);
24const char *event_name(struct perf_evsel *event); 25const char *event_name(struct perf_evsel *event);
25extern const char *__event_name(int type, u64 config); 26extern const char *__event_name(int type, u64 config);
26 27
27extern int parse_events(const struct option *opt, const char *str, int unset); 28extern int parse_events_option(const struct option *opt, const char *str,
29 int unset);
30extern int parse_events(struct perf_evlist *evlist, const char *str,
31 int unset);
28extern int parse_filter(const struct option *opt, const char *str, int unset); 32extern int parse_filter(const struct option *opt, const char *str, int unset);
29 33
30#define EVENTS_HELP_MAX (128*1024) 34#define EVENTS_HELP_MAX (128*1024)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index f0223166e761..b82d54fa2c56 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -117,6 +117,10 @@ static struct map *kernel_get_module_map(const char *module)
117 struct rb_node *nd; 117 struct rb_node *nd;
118 struct map_groups *grp = &machine.kmaps; 118 struct map_groups *grp = &machine.kmaps;
119 119
120 /* A file path -- this is an offline module */
121 if (module && strchr(module, '/'))
122 return machine__new_module(&machine, 0, module);
123
120 if (!module) 124 if (!module)
121 module = "kernel"; 125 module = "kernel";
122 126
@@ -170,16 +174,24 @@ const char *kernel_get_module_path(const char *module)
170} 174}
171 175
172#ifdef DWARF_SUPPORT 176#ifdef DWARF_SUPPORT
173static int open_vmlinux(const char *module) 177/* Open new debuginfo of given module */
178static struct debuginfo *open_debuginfo(const char *module)
174{ 179{
175 const char *path = kernel_get_module_path(module); 180 const char *path;
176 if (!path) { 181
177 pr_err("Failed to find path of %s module.\n", 182 /* A file path -- this is an offline module */
178 module ?: "kernel"); 183 if (module && strchr(module, '/'))
179 return -ENOENT; 184 path = module;
185 else {
186 path = kernel_get_module_path(module);
187
188 if (!path) {
189 pr_err("Failed to find path of %s module.\n",
190 module ?: "kernel");
191 return NULL;
192 }
180 } 193 }
181 pr_debug("Try to open %s\n", path); 194 return debuginfo__new(path);
182 return open(path, O_RDONLY);
183} 195}
184 196
185/* 197/*
@@ -193,13 +205,24 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
193 struct map *map; 205 struct map *map;
194 u64 addr; 206 u64 addr;
195 int ret = -ENOENT; 207 int ret = -ENOENT;
208 struct debuginfo *dinfo;
196 209
197 sym = __find_kernel_function_by_name(tp->symbol, &map); 210 sym = __find_kernel_function_by_name(tp->symbol, &map);
198 if (sym) { 211 if (sym) {
199 addr = map->unmap_ip(map, sym->start + tp->offset); 212 addr = map->unmap_ip(map, sym->start + tp->offset);
200 pr_debug("try to find %s+%ld@%" PRIx64 "\n", tp->symbol, 213 pr_debug("try to find %s+%ld@%" PRIx64 "\n", tp->symbol,
201 tp->offset, addr); 214 tp->offset, addr);
202 ret = find_perf_probe_point((unsigned long)addr, pp); 215
216 dinfo = debuginfo__new_online_kernel(addr);
217 if (dinfo) {
218 ret = debuginfo__find_probe_point(dinfo,
219 (unsigned long)addr, pp);
220 debuginfo__delete(dinfo);
221 } else {
222 pr_debug("Failed to open debuginfo at 0x%" PRIx64 "\n",
223 addr);
224 ret = -ENOENT;
225 }
203 } 226 }
204 if (ret <= 0) { 227 if (ret <= 0) {
205 pr_debug("Failed to find corresponding probes from " 228 pr_debug("Failed to find corresponding probes from "
@@ -214,30 +237,70 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
214 return 0; 237 return 0;
215} 238}
216 239
240static int add_module_to_probe_trace_events(struct probe_trace_event *tevs,
241 int ntevs, const char *module)
242{
243 int i, ret = 0;
244 char *tmp;
245
246 if (!module)
247 return 0;
248
249 tmp = strrchr(module, '/');
250 if (tmp) {
251 /* This is a module path -- get the module name */
252 module = strdup(tmp + 1);
253 if (!module)
254 return -ENOMEM;
255 tmp = strchr(module, '.');
256 if (tmp)
257 *tmp = '\0';
258 tmp = (char *)module; /* For free() */
259 }
260
261 for (i = 0; i < ntevs; i++) {
262 tevs[i].point.module = strdup(module);
263 if (!tevs[i].point.module) {
264 ret = -ENOMEM;
265 break;
266 }
267 }
268
269 if (tmp)
270 free(tmp);
271
272 return ret;
273}
274
217/* Try to find perf_probe_event with debuginfo */ 275/* Try to find perf_probe_event with debuginfo */
218static int try_to_find_probe_trace_events(struct perf_probe_event *pev, 276static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
219 struct probe_trace_event **tevs, 277 struct probe_trace_event **tevs,
220 int max_tevs, const char *module) 278 int max_tevs, const char *module)
221{ 279{
222 bool need_dwarf = perf_probe_event_need_dwarf(pev); 280 bool need_dwarf = perf_probe_event_need_dwarf(pev);
223 int fd, ntevs; 281 struct debuginfo *dinfo = open_debuginfo(module);
282 int ntevs, ret = 0;
224 283
225 fd = open_vmlinux(module); 284 if (!dinfo) {
226 if (fd < 0) {
227 if (need_dwarf) { 285 if (need_dwarf) {
228 pr_warning("Failed to open debuginfo file.\n"); 286 pr_warning("Failed to open debuginfo file.\n");
229 return fd; 287 return -ENOENT;
230 } 288 }
231 pr_debug("Could not open vmlinux. Try to use symbols.\n"); 289 pr_debug("Could not open debuginfo. Try to use symbols.\n");
232 return 0; 290 return 0;
233 } 291 }
234 292
235 /* Searching trace events corresponding to probe event */ 293 /* Searching trace events corresponding to a probe event */
236 ntevs = find_probe_trace_events(fd, pev, tevs, max_tevs); 294 ntevs = debuginfo__find_trace_events(dinfo, pev, tevs, max_tevs);
295
296 debuginfo__delete(dinfo);
237 297
238 if (ntevs > 0) { /* Succeeded to find trace events */ 298 if (ntevs > 0) { /* Succeeded to find trace events */
239 pr_debug("find %d probe_trace_events.\n", ntevs); 299 pr_debug("find %d probe_trace_events.\n", ntevs);
240 return ntevs; 300 if (module)
301 ret = add_module_to_probe_trace_events(*tevs, ntevs,
302 module);
303 return ret < 0 ? ret : ntevs;
241 } 304 }
242 305
243 if (ntevs == 0) { /* No error but failed to find probe point. */ 306 if (ntevs == 0) { /* No error but failed to find probe point. */
@@ -371,8 +434,9 @@ int show_line_range(struct line_range *lr, const char *module)
371{ 434{
372 int l = 1; 435 int l = 1;
373 struct line_node *ln; 436 struct line_node *ln;
437 struct debuginfo *dinfo;
374 FILE *fp; 438 FILE *fp;
375 int fd, ret; 439 int ret;
376 char *tmp; 440 char *tmp;
377 441
378 /* Search a line range */ 442 /* Search a line range */
@@ -380,13 +444,14 @@ int show_line_range(struct line_range *lr, const char *module)
380 if (ret < 0) 444 if (ret < 0)
381 return ret; 445 return ret;
382 446
383 fd = open_vmlinux(module); 447 dinfo = open_debuginfo(module);
384 if (fd < 0) { 448 if (!dinfo) {
385 pr_warning("Failed to open debuginfo file.\n"); 449 pr_warning("Failed to open debuginfo file.\n");
386 return fd; 450 return -ENOENT;
387 } 451 }
388 452
389 ret = find_line_range(fd, lr); 453 ret = debuginfo__find_line_range(dinfo, lr);
454 debuginfo__delete(dinfo);
390 if (ret == 0) { 455 if (ret == 0) {
391 pr_warning("Specified source line is not found.\n"); 456 pr_warning("Specified source line is not found.\n");
392 return -ENOENT; 457 return -ENOENT;
@@ -448,7 +513,8 @@ end:
448 return ret; 513 return ret;
449} 514}
450 515
451static int show_available_vars_at(int fd, struct perf_probe_event *pev, 516static int show_available_vars_at(struct debuginfo *dinfo,
517 struct perf_probe_event *pev,
452 int max_vls, struct strfilter *_filter, 518 int max_vls, struct strfilter *_filter,
453 bool externs) 519 bool externs)
454{ 520{
@@ -463,7 +529,8 @@ static int show_available_vars_at(int fd, struct perf_probe_event *pev,
463 return -EINVAL; 529 return -EINVAL;
464 pr_debug("Searching variables at %s\n", buf); 530 pr_debug("Searching variables at %s\n", buf);
465 531
466 ret = find_available_vars_at(fd, pev, &vls, max_vls, externs); 532 ret = debuginfo__find_available_vars_at(dinfo, pev, &vls,
533 max_vls, externs);
467 if (ret <= 0) { 534 if (ret <= 0) {
468 pr_err("Failed to find variables at %s (%d)\n", buf, ret); 535 pr_err("Failed to find variables at %s (%d)\n", buf, ret);
469 goto end; 536 goto end;
@@ -504,24 +571,26 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
504 int max_vls, const char *module, 571 int max_vls, const char *module,
505 struct strfilter *_filter, bool externs) 572 struct strfilter *_filter, bool externs)
506{ 573{
507 int i, fd, ret = 0; 574 int i, ret = 0;
575 struct debuginfo *dinfo;
508 576
509 ret = init_vmlinux(); 577 ret = init_vmlinux();
510 if (ret < 0) 578 if (ret < 0)
511 return ret; 579 return ret;
512 580
581 dinfo = open_debuginfo(module);
582 if (!dinfo) {
583 pr_warning("Failed to open debuginfo file.\n");
584 return -ENOENT;
585 }
586
513 setup_pager(); 587 setup_pager();
514 588
515 for (i = 0; i < npevs && ret >= 0; i++) { 589 for (i = 0; i < npevs && ret >= 0; i++)
516 fd = open_vmlinux(module); 590 ret = show_available_vars_at(dinfo, &pevs[i], max_vls, _filter,
517 if (fd < 0) {
518 pr_warning("Failed to open debug information file.\n");
519 ret = fd;
520 break;
521 }
522 ret = show_available_vars_at(fd, &pevs[i], max_vls, _filter,
523 externs); 591 externs);
524 } 592
593 debuginfo__delete(dinfo);
525 return ret; 594 return ret;
526} 595}
527 596
@@ -990,7 +1059,7 @@ bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
990 1059
991/* Parse probe_events event into struct probe_point */ 1060/* Parse probe_events event into struct probe_point */
992static int parse_probe_trace_command(const char *cmd, 1061static int parse_probe_trace_command(const char *cmd,
993 struct probe_trace_event *tev) 1062 struct probe_trace_event *tev)
994{ 1063{
995 struct probe_trace_point *tp = &tev->point; 1064 struct probe_trace_point *tp = &tev->point;
996 char pr; 1065 char pr;
@@ -1023,8 +1092,14 @@ static int parse_probe_trace_command(const char *cmd,
1023 1092
1024 tp->retprobe = (pr == 'r'); 1093 tp->retprobe = (pr == 'r');
1025 1094
1026 /* Scan function name and offset */ 1095 /* Scan module name(if there), function name and offset */
1027 ret = sscanf(argv[1], "%a[^+]+%lu", (float *)(void *)&tp->symbol, 1096 p = strchr(argv[1], ':');
1097 if (p) {
1098 tp->module = strndup(argv[1], p - argv[1]);
1099 p++;
1100 } else
1101 p = argv[1];
1102 ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol,
1028 &tp->offset); 1103 &tp->offset);
1029 if (ret == 1) 1104 if (ret == 1)
1030 tp->offset = 0; 1105 tp->offset = 0;
@@ -1269,9 +1344,10 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev)
1269 if (buf == NULL) 1344 if (buf == NULL)
1270 return NULL; 1345 return NULL;
1271 1346
1272 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s+%lu", 1347 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s%s%s+%lu",
1273 tp->retprobe ? 'r' : 'p', 1348 tp->retprobe ? 'r' : 'p',
1274 tev->group, tev->event, 1349 tev->group, tev->event,
1350 tp->module ?: "", tp->module ? ":" : "",
1275 tp->symbol, tp->offset); 1351 tp->symbol, tp->offset);
1276 if (len <= 0) 1352 if (len <= 0)
1277 goto error; 1353 goto error;
@@ -1378,6 +1454,8 @@ static void clear_probe_trace_event(struct probe_trace_event *tev)
1378 free(tev->group); 1454 free(tev->group);
1379 if (tev->point.symbol) 1455 if (tev->point.symbol)
1380 free(tev->point.symbol); 1456 free(tev->point.symbol);
1457 if (tev->point.module)
1458 free(tev->point.module);
1381 for (i = 0; i < tev->nargs; i++) { 1459 for (i = 0; i < tev->nargs; i++) {
1382 if (tev->args[i].name) 1460 if (tev->args[i].name)
1383 free(tev->args[i].name); 1461 free(tev->args[i].name);
@@ -1729,7 +1807,7 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
1729 /* Convert perf_probe_event with debuginfo */ 1807 /* Convert perf_probe_event with debuginfo */
1730 ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, module); 1808 ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, module);
1731 if (ret != 0) 1809 if (ret != 0)
1732 return ret; 1810 return ret; /* Found in debuginfo or got an error */
1733 1811
1734 /* Allocate trace event buffer */ 1812 /* Allocate trace event buffer */
1735 tev = *tevs = zalloc(sizeof(struct probe_trace_event)); 1813 tev = *tevs = zalloc(sizeof(struct probe_trace_event));
@@ -1742,6 +1820,11 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
1742 ret = -ENOMEM; 1820 ret = -ENOMEM;
1743 goto error; 1821 goto error;
1744 } 1822 }
1823 tev->point.module = strdup(module);
1824 if (tev->point.module == NULL) {
1825 ret = -ENOMEM;
1826 goto error;
1827 }
1745 tev->point.offset = pev->point.offset; 1828 tev->point.offset = pev->point.offset;
1746 tev->point.retprobe = pev->point.retprobe; 1829 tev->point.retprobe = pev->point.retprobe;
1747 tev->nargs = pev->nargs; 1830 tev->nargs = pev->nargs;
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 3434fc9d79d5..a7dee835f49c 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -10,6 +10,7 @@ extern bool probe_event_dry_run;
10/* kprobe-tracer tracing point */ 10/* kprobe-tracer tracing point */
11struct probe_trace_point { 11struct probe_trace_point {
12 char *symbol; /* Base symbol */ 12 char *symbol; /* Base symbol */
13 char *module; /* Module name */
13 unsigned long offset; /* Offset from symbol */ 14 unsigned long offset; /* Offset from symbol */
14 bool retprobe; /* Return probe flag */ 15 bool retprobe; /* Return probe flag */
15}; 16};
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 3b9d0b800d5c..3e44a3e36519 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -43,21 +43,6 @@
43/* Kprobe tracer basic type is up to u64 */ 43/* Kprobe tracer basic type is up to u64 */
44#define MAX_BASIC_TYPE_BITS 64 44#define MAX_BASIC_TYPE_BITS 64
45 45
46/*
47 * Compare the tail of two strings.
48 * Return 0 if whole of either string is same as another's tail part.
49 */
50static int strtailcmp(const char *s1, const char *s2)
51{
52 int i1 = strlen(s1);
53 int i2 = strlen(s2);
54 while (--i1 >= 0 && --i2 >= 0) {
55 if (s1[i1] != s2[i2])
56 return s1[i1] - s2[i2];
57 }
58 return 0;
59}
60
61/* Line number list operations */ 46/* Line number list operations */
62 47
63/* Add a line to line number list */ 48/* Add a line to line number list */
@@ -131,29 +116,37 @@ static const Dwfl_Callbacks offline_callbacks = {
131}; 116};
132 117
133/* Get a Dwarf from offline image */ 118/* Get a Dwarf from offline image */
134static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias) 119static int debuginfo__init_offline_dwarf(struct debuginfo *self,
120 const char *path)
135{ 121{
136 Dwfl_Module *mod; 122 Dwfl_Module *mod;
137 Dwarf *dbg = NULL; 123 int fd;
138 124
139 if (!dwflp) 125 fd = open(path, O_RDONLY);
140 return NULL; 126 if (fd < 0)
127 return fd;
141 128
142 *dwflp = dwfl_begin(&offline_callbacks); 129 self->dwfl = dwfl_begin(&offline_callbacks);
143 if (!*dwflp) 130 if (!self->dwfl)
144 return NULL; 131 goto error;
145 132
146 mod = dwfl_report_offline(*dwflp, "", "", fd); 133 mod = dwfl_report_offline(self->dwfl, "", "", fd);
147 if (!mod) 134 if (!mod)
148 goto error; 135 goto error;
149 136
150 dbg = dwfl_module_getdwarf(mod, bias); 137 self->dbg = dwfl_module_getdwarf(mod, &self->bias);
151 if (!dbg) { 138 if (!self->dbg)
139 goto error;
140
141 return 0;
152error: 142error:
153 dwfl_end(*dwflp); 143 if (self->dwfl)
154 *dwflp = NULL; 144 dwfl_end(self->dwfl);
155 } 145 else
156 return dbg; 146 close(fd);
147 memset(self, 0, sizeof(*self));
148
149 return -ENOENT;
157} 150}
158 151
159#if _ELFUTILS_PREREQ(0, 148) 152#if _ELFUTILS_PREREQ(0, 148)
@@ -189,597 +182,81 @@ static const Dwfl_Callbacks kernel_callbacks = {
189}; 182};
190 183
191/* Get a Dwarf from live kernel image */ 184/* Get a Dwarf from live kernel image */
192static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp, 185static int debuginfo__init_online_kernel_dwarf(struct debuginfo *self,
193 Dwarf_Addr *bias) 186 Dwarf_Addr addr)
194{ 187{
195 Dwarf *dbg; 188 self->dwfl = dwfl_begin(&kernel_callbacks);
196 189 if (!self->dwfl)
197 if (!dwflp) 190 return -EINVAL;
198 return NULL;
199
200 *dwflp = dwfl_begin(&kernel_callbacks);
201 if (!*dwflp)
202 return NULL;
203 191
204 /* Load the kernel dwarves: Don't care the result here */ 192 /* Load the kernel dwarves: Don't care the result here */
205 dwfl_linux_kernel_report_kernel(*dwflp); 193 dwfl_linux_kernel_report_kernel(self->dwfl);
206 dwfl_linux_kernel_report_modules(*dwflp); 194 dwfl_linux_kernel_report_modules(self->dwfl);
207 195
208 dbg = dwfl_addrdwarf(*dwflp, addr, bias); 196 self->dbg = dwfl_addrdwarf(self->dwfl, addr, &self->bias);
209 /* Here, check whether we could get a real dwarf */ 197 /* Here, check whether we could get a real dwarf */
210 if (!dbg) { 198 if (!self->dbg) {
211 pr_debug("Failed to find kernel dwarf at %lx\n", 199 pr_debug("Failed to find kernel dwarf at %lx\n",
212 (unsigned long)addr); 200 (unsigned long)addr);
213 dwfl_end(*dwflp); 201 dwfl_end(self->dwfl);
214 *dwflp = NULL; 202 memset(self, 0, sizeof(*self));
203 return -ENOENT;
215 } 204 }
216 return dbg; 205
206 return 0;
217} 207}
218#else 208#else
219/* With older elfutils, this just support kernel module... */ 209/* With older elfutils, this just support kernel module... */
220static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr __used, Dwfl **dwflp, 210static int debuginfo__init_online_kernel_dwarf(struct debuginfo *self,
221 Dwarf_Addr *bias) 211 Dwarf_Addr addr __used)
222{ 212{
223 int fd;
224 const char *path = kernel_get_module_path("kernel"); 213 const char *path = kernel_get_module_path("kernel");
225 214
226 if (!path) { 215 if (!path) {
227 pr_err("Failed to find vmlinux path\n"); 216 pr_err("Failed to find vmlinux path\n");
228 return NULL; 217 return -ENOENT;
229 } 218 }
230 219
231 pr_debug2("Use file %s for debuginfo\n", path); 220 pr_debug2("Use file %s for debuginfo\n", path);
232 fd = open(path, O_RDONLY); 221 return debuginfo__init_offline_dwarf(self, path);
233 if (fd < 0)
234 return NULL;
235
236 return dwfl_init_offline_dwarf(fd, dwflp, bias);
237} 222}
238#endif 223#endif
239 224
240/* Dwarf wrappers */ 225struct debuginfo *debuginfo__new(const char *path)
241
242/* Find the realpath of the target file. */
243static const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname)
244{
245 Dwarf_Files *files;
246 size_t nfiles, i;
247 const char *src = NULL;
248 int ret;
249
250 if (!fname)
251 return NULL;
252
253 ret = dwarf_getsrcfiles(cu_die, &files, &nfiles);
254 if (ret != 0)
255 return NULL;
256
257 for (i = 0; i < nfiles; i++) {
258 src = dwarf_filesrc(files, i, NULL, NULL);
259 if (strtailcmp(src, fname) == 0)
260 break;
261 }
262 if (i == nfiles)
263 return NULL;
264 return src;
265}
266
267/* Get DW_AT_comp_dir (should be NULL with older gcc) */
268static const char *cu_get_comp_dir(Dwarf_Die *cu_die)
269{
270 Dwarf_Attribute attr;
271 if (dwarf_attr(cu_die, DW_AT_comp_dir, &attr) == NULL)
272 return NULL;
273 return dwarf_formstring(&attr);
274}
275
276/* Get a line number and file name for given address */
277static int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr,
278 const char **fname, int *lineno)
279{
280 Dwarf_Line *line;
281 Dwarf_Addr laddr;
282
283 line = dwarf_getsrc_die(cudie, (Dwarf_Addr)addr);
284 if (line && dwarf_lineaddr(line, &laddr) == 0 &&
285 addr == (unsigned long)laddr && dwarf_lineno(line, lineno) == 0) {
286 *fname = dwarf_linesrc(line, NULL, NULL);
287 if (!*fname)
288 /* line number is useless without filename */
289 *lineno = 0;
290 }
291
292 return *lineno ?: -ENOENT;
293}
294
295/* Compare diename and tname */
296static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
297{
298 const char *name;
299 name = dwarf_diename(dw_die);
300 return name ? (strcmp(tname, name) == 0) : false;
301}
302
303/* Get callsite line number of inline-function instance */
304static int die_get_call_lineno(Dwarf_Die *in_die)
305{
306 Dwarf_Attribute attr;
307 Dwarf_Word ret;
308
309 if (!dwarf_attr(in_die, DW_AT_call_line, &attr))
310 return -ENOENT;
311
312 dwarf_formudata(&attr, &ret);
313 return (int)ret;
314}
315
316/* Get type die */
317static Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
318{
319 Dwarf_Attribute attr;
320
321 if (dwarf_attr_integrate(vr_die, DW_AT_type, &attr) &&
322 dwarf_formref_die(&attr, die_mem))
323 return die_mem;
324 else
325 return NULL;
326}
327
328/* Get a type die, but skip qualifiers */
329static Dwarf_Die *__die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
330{
331 int tag;
332
333 do {
334 vr_die = die_get_type(vr_die, die_mem);
335 if (!vr_die)
336 break;
337 tag = dwarf_tag(vr_die);
338 } while (tag == DW_TAG_const_type ||
339 tag == DW_TAG_restrict_type ||
340 tag == DW_TAG_volatile_type ||
341 tag == DW_TAG_shared_type);
342
343 return vr_die;
344}
345
346/* Get a type die, but skip qualifiers and typedef */
347static Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
348{
349 do {
350 vr_die = __die_get_real_type(vr_die, die_mem);
351 } while (vr_die && dwarf_tag(vr_die) == DW_TAG_typedef);
352
353 return vr_die;
354}
355
356static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name,
357 Dwarf_Word *result)
358{
359 Dwarf_Attribute attr;
360
361 if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
362 dwarf_formudata(&attr, result) != 0)
363 return -ENOENT;
364
365 return 0;
366}
367
368static bool die_is_signed_type(Dwarf_Die *tp_die)
369{
370 Dwarf_Word ret;
371
372 if (die_get_attr_udata(tp_die, DW_AT_encoding, &ret))
373 return false;
374
375 return (ret == DW_ATE_signed_char || ret == DW_ATE_signed ||
376 ret == DW_ATE_signed_fixed);
377}
378
379static int die_get_byte_size(Dwarf_Die *tp_die)
380{
381 Dwarf_Word ret;
382
383 if (die_get_attr_udata(tp_die, DW_AT_byte_size, &ret))
384 return 0;
385
386 return (int)ret;
387}
388
389static int die_get_bit_size(Dwarf_Die *tp_die)
390{
391 Dwarf_Word ret;
392
393 if (die_get_attr_udata(tp_die, DW_AT_bit_size, &ret))
394 return 0;
395
396 return (int)ret;
397}
398
399static int die_get_bit_offset(Dwarf_Die *tp_die)
400{
401 Dwarf_Word ret;
402
403 if (die_get_attr_udata(tp_die, DW_AT_bit_offset, &ret))
404 return 0;
405
406 return (int)ret;
407}
408
409/* Get data_member_location offset */
410static int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
411{
412 Dwarf_Attribute attr;
413 Dwarf_Op *expr;
414 size_t nexpr;
415 int ret;
416
417 if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) == NULL)
418 return -ENOENT;
419
420 if (dwarf_formudata(&attr, offs) != 0) {
421 /* DW_AT_data_member_location should be DW_OP_plus_uconst */
422 ret = dwarf_getlocation(&attr, &expr, &nexpr);
423 if (ret < 0 || nexpr == 0)
424 return -ENOENT;
425
426 if (expr[0].atom != DW_OP_plus_uconst || nexpr != 1) {
427 pr_debug("Unable to get offset:Unexpected OP %x (%zd)\n",
428 expr[0].atom, nexpr);
429 return -ENOTSUP;
430 }
431 *offs = (Dwarf_Word)expr[0].number;
432 }
433 return 0;
434}
435
436/* Return values for die_find callbacks */
437enum {
438 DIE_FIND_CB_FOUND = 0, /* End of Search */
439 DIE_FIND_CB_CHILD = 1, /* Search only children */
440 DIE_FIND_CB_SIBLING = 2, /* Search only siblings */
441 DIE_FIND_CB_CONTINUE = 3, /* Search children and siblings */
442};
443
444/* Search a child die */
445static Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
446 int (*callback)(Dwarf_Die *, void *),
447 void *data, Dwarf_Die *die_mem)
448{ 226{
449 Dwarf_Die child_die; 227 struct debuginfo *self = zalloc(sizeof(struct debuginfo));
450 int ret; 228 if (!self)
451
452 ret = dwarf_child(rt_die, die_mem);
453 if (ret != 0)
454 return NULL; 229 return NULL;
455 230
456 do { 231 if (debuginfo__init_offline_dwarf(self, path) < 0) {
457 ret = callback(die_mem, data); 232 free(self);
458 if (ret == DIE_FIND_CB_FOUND) 233 self = NULL;
459 return die_mem;
460
461 if ((ret & DIE_FIND_CB_CHILD) &&
462 die_find_child(die_mem, callback, data, &child_die)) {
463 memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
464 return die_mem;
465 }
466 } while ((ret & DIE_FIND_CB_SIBLING) &&
467 dwarf_siblingof(die_mem, die_mem) == 0);
468
469 return NULL;
470}
471
472struct __addr_die_search_param {
473 Dwarf_Addr addr;
474 Dwarf_Die *die_mem;
475};
476
477static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
478{
479 struct __addr_die_search_param *ad = data;
480
481 if (dwarf_tag(fn_die) == DW_TAG_subprogram &&
482 dwarf_haspc(fn_die, ad->addr)) {
483 memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die));
484 return DWARF_CB_ABORT;
485 } 234 }
486 return DWARF_CB_OK;
487}
488
489/* Search a real subprogram including this line, */
490static Dwarf_Die *die_find_real_subprogram(Dwarf_Die *cu_die, Dwarf_Addr addr,
491 Dwarf_Die *die_mem)
492{
493 struct __addr_die_search_param ad;
494 ad.addr = addr;
495 ad.die_mem = die_mem;
496 /* dwarf_getscopes can't find subprogram. */
497 if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0))
498 return NULL;
499 else
500 return die_mem;
501}
502
503/* die_find callback for inline function search */
504static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
505{
506 Dwarf_Addr *addr = data;
507
508 if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine &&
509 dwarf_haspc(die_mem, *addr))
510 return DIE_FIND_CB_FOUND;
511 235
512 return DIE_FIND_CB_CONTINUE; 236 return self;
513} 237}
514 238
515/* Similar to dwarf_getfuncs, but returns inlined_subroutine if exists. */ 239struct debuginfo *debuginfo__new_online_kernel(unsigned long addr)
516static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
517 Dwarf_Die *die_mem)
518{ 240{
519 Dwarf_Die tmp_die; 241 struct debuginfo *self = zalloc(sizeof(struct debuginfo));
520 242 if (!self)
521 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, &tmp_die);
522 if (!sp_die)
523 return NULL; 243 return NULL;
524 244
525 /* Inlined function could be recursive. Trace it until fail */ 245 if (debuginfo__init_online_kernel_dwarf(self, (Dwarf_Addr)addr) < 0) {
526 while (sp_die) { 246 free(self);
527 memcpy(die_mem, sp_die, sizeof(Dwarf_Die)); 247 self = NULL;
528 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr,
529 &tmp_die);
530 }
531
532 return die_mem;
533}
534
535/* Walker on lines (Note: line number will not be sorted) */
536typedef int (* line_walk_handler_t) (const char *fname, int lineno,
537 Dwarf_Addr addr, void *data);
538
539struct __line_walk_param {
540 const char *fname;
541 line_walk_handler_t handler;
542 void *data;
543 int retval;
544};
545
546static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data)
547{
548 struct __line_walk_param *lw = data;
549 Dwarf_Addr addr;
550 int lineno;
551
552 if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) {
553 lineno = die_get_call_lineno(in_die);
554 if (lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) {
555 lw->retval = lw->handler(lw->fname, lineno, addr,
556 lw->data);
557 if (lw->retval != 0)
558 return DIE_FIND_CB_FOUND;
559 }
560 }
561 return DIE_FIND_CB_SIBLING;
562}
563
564/* Walk on lines of blocks included in given DIE */
565static int __die_walk_funclines(Dwarf_Die *sp_die,
566 line_walk_handler_t handler, void *data)
567{
568 struct __line_walk_param lw = {
569 .handler = handler,
570 .data = data,
571 .retval = 0,
572 };
573 Dwarf_Die die_mem;
574 Dwarf_Addr addr;
575 int lineno;
576
577 /* Handle function declaration line */
578 lw.fname = dwarf_decl_file(sp_die);
579 if (lw.fname && dwarf_decl_line(sp_die, &lineno) == 0 &&
580 dwarf_entrypc(sp_die, &addr) == 0) {
581 lw.retval = handler(lw.fname, lineno, addr, data);
582 if (lw.retval != 0)
583 goto done;
584 }
585 die_find_child(sp_die, __die_walk_funclines_cb, &lw, &die_mem);
586done:
587 return lw.retval;
588}
589
590static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data)
591{
592 struct __line_walk_param *lw = data;
593
594 lw->retval = __die_walk_funclines(sp_die, lw->handler, lw->data);
595 if (lw->retval != 0)
596 return DWARF_CB_ABORT;
597
598 return DWARF_CB_OK;
599}
600
601/*
602 * Walk on lines inside given PDIE. If the PDIE is subprogram, walk only on
603 * the lines inside the subprogram, otherwise PDIE must be a CU DIE.
604 */
605static int die_walk_lines(Dwarf_Die *pdie, line_walk_handler_t handler,
606 void *data)
607{
608 Dwarf_Lines *lines;
609 Dwarf_Line *line;
610 Dwarf_Addr addr;
611 const char *fname;
612 int lineno, ret = 0;
613 Dwarf_Die die_mem, *cu_die;
614 size_t nlines, i;
615
616 /* Get the CU die */
617 if (dwarf_tag(pdie) == DW_TAG_subprogram)
618 cu_die = dwarf_diecu(pdie, &die_mem, NULL, NULL);
619 else
620 cu_die = pdie;
621 if (!cu_die) {
622 pr_debug2("Failed to get CU from subprogram\n");
623 return -EINVAL;
624 }
625
626 /* Get lines list in the CU */
627 if (dwarf_getsrclines(cu_die, &lines, &nlines) != 0) {
628 pr_debug2("Failed to get source lines on this CU.\n");
629 return -ENOENT;
630 }
631 pr_debug2("Get %zd lines from this CU\n", nlines);
632
633 /* Walk on the lines on lines list */
634 for (i = 0; i < nlines; i++) {
635 line = dwarf_onesrcline(lines, i);
636 if (line == NULL ||
637 dwarf_lineno(line, &lineno) != 0 ||
638 dwarf_lineaddr(line, &addr) != 0) {
639 pr_debug2("Failed to get line info. "
640 "Possible error in debuginfo.\n");
641 continue;
642 }
643 /* Filter lines based on address */
644 if (pdie != cu_die)
645 /*
646 * Address filtering
647 * The line is included in given function, and
648 * no inline block includes it.
649 */
650 if (!dwarf_haspc(pdie, addr) ||
651 die_find_inlinefunc(pdie, addr, &die_mem))
652 continue;
653 /* Get source line */
654 fname = dwarf_linesrc(line, NULL, NULL);
655
656 ret = handler(fname, lineno, addr, data);
657 if (ret != 0)
658 return ret;
659 }
660
661 /*
662 * Dwarf lines doesn't include function declarations and inlined
663 * subroutines. We have to check functions list or given function.
664 */
665 if (pdie != cu_die)
666 ret = __die_walk_funclines(pdie, handler, data);
667 else {
668 struct __line_walk_param param = {
669 .handler = handler,
670 .data = data,
671 .retval = 0,
672 };
673 dwarf_getfuncs(cu_die, __die_walk_culines_cb, &param, 0);
674 ret = param.retval;
675 } 248 }
676 249
677 return ret; 250 return self;
678}
679
680struct __find_variable_param {
681 const char *name;
682 Dwarf_Addr addr;
683};
684
685static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data)
686{
687 struct __find_variable_param *fvp = data;
688 int tag;
689
690 tag = dwarf_tag(die_mem);
691 if ((tag == DW_TAG_formal_parameter ||
692 tag == DW_TAG_variable) &&
693 die_compare_name(die_mem, fvp->name))
694 return DIE_FIND_CB_FOUND;
695
696 if (dwarf_haspc(die_mem, fvp->addr))
697 return DIE_FIND_CB_CONTINUE;
698 else
699 return DIE_FIND_CB_SIBLING;
700}
701
702/* Find a variable called 'name' at given address */
703static Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name,
704 Dwarf_Addr addr, Dwarf_Die *die_mem)
705{
706 struct __find_variable_param fvp = { .name = name, .addr = addr};
707
708 return die_find_child(sp_die, __die_find_variable_cb, (void *)&fvp,
709 die_mem);
710}
711
712static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
713{
714 const char *name = data;
715
716 if ((dwarf_tag(die_mem) == DW_TAG_member) &&
717 die_compare_name(die_mem, name))
718 return DIE_FIND_CB_FOUND;
719
720 return DIE_FIND_CB_SIBLING;
721}
722
723/* Find a member called 'name' */
724static Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
725 Dwarf_Die *die_mem)
726{
727 return die_find_child(st_die, __die_find_member_cb, (void *)name,
728 die_mem);
729}
730
731/* Get the name of given variable DIE */
732static int die_get_typename(Dwarf_Die *vr_die, char *buf, int len)
733{
734 Dwarf_Die type;
735 int tag, ret, ret2;
736 const char *tmp = "";
737
738 if (__die_get_real_type(vr_die, &type) == NULL)
739 return -ENOENT;
740
741 tag = dwarf_tag(&type);
742 if (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)
743 tmp = "*";
744 else if (tag == DW_TAG_subroutine_type) {
745 /* Function pointer */
746 ret = snprintf(buf, len, "(function_type)");
747 return (ret >= len) ? -E2BIG : ret;
748 } else {
749 if (!dwarf_diename(&type))
750 return -ENOENT;
751 if (tag == DW_TAG_union_type)
752 tmp = "union ";
753 else if (tag == DW_TAG_structure_type)
754 tmp = "struct ";
755 /* Write a base name */
756 ret = snprintf(buf, len, "%s%s", tmp, dwarf_diename(&type));
757 return (ret >= len) ? -E2BIG : ret;
758 }
759 ret = die_get_typename(&type, buf, len);
760 if (ret > 0) {
761 ret2 = snprintf(buf + ret, len - ret, "%s", tmp);
762 ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret;
763 }
764 return ret;
765} 251}
766 252
767/* Get the name and type of given variable DIE, stored as "type\tname" */ 253void debuginfo__delete(struct debuginfo *self)
768static int die_get_varname(Dwarf_Die *vr_die, char *buf, int len)
769{ 254{
770 int ret, ret2; 255 if (self) {
771 256 if (self->dwfl)
772 ret = die_get_typename(vr_die, buf, len); 257 dwfl_end(self->dwfl);
773 if (ret < 0) { 258 free(self);
774 pr_debug("Failed to get type, make it unknown.\n");
775 ret = snprintf(buf, len, "(unknown_type)");
776 } 259 }
777 if (ret > 0) {
778 ret2 = snprintf(buf + ret, len - ret, "\t%s",
779 dwarf_diename(vr_die));
780 ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret;
781 }
782 return ret;
783} 260}
784 261
785/* 262/*
@@ -897,6 +374,7 @@ static int convert_variable_type(Dwarf_Die *vr_die,
897 struct probe_trace_arg_ref **ref_ptr = &tvar->ref; 374 struct probe_trace_arg_ref **ref_ptr = &tvar->ref;
898 Dwarf_Die type; 375 Dwarf_Die type;
899 char buf[16]; 376 char buf[16];
377 int bsize, boffs, total;
900 int ret; 378 int ret;
901 379
902 /* TODO: check all types */ 380 /* TODO: check all types */
@@ -906,11 +384,15 @@ static int convert_variable_type(Dwarf_Die *vr_die,
906 return (tvar->type == NULL) ? -ENOMEM : 0; 384 return (tvar->type == NULL) ? -ENOMEM : 0;
907 } 385 }
908 386
909 if (die_get_bit_size(vr_die) != 0) { 387 bsize = dwarf_bitsize(vr_die);
388 if (bsize > 0) {
910 /* This is a bitfield */ 389 /* This is a bitfield */
911 ret = snprintf(buf, 16, "b%d@%d/%zd", die_get_bit_size(vr_die), 390 boffs = dwarf_bitoffset(vr_die);
912 die_get_bit_offset(vr_die), 391 total = dwarf_bytesize(vr_die);
913 BYTES_TO_BITS(die_get_byte_size(vr_die))); 392 if (boffs < 0 || total < 0)
393 return -ENOENT;
394 ret = snprintf(buf, 16, "b%d@%d/%zd", bsize, boffs,
395 BYTES_TO_BITS(total));
914 goto formatted; 396 goto formatted;
915 } 397 }
916 398
@@ -958,10 +440,11 @@ static int convert_variable_type(Dwarf_Die *vr_die,
958 return (tvar->type == NULL) ? -ENOMEM : 0; 440 return (tvar->type == NULL) ? -ENOMEM : 0;
959 } 441 }
960 442
961 ret = BYTES_TO_BITS(die_get_byte_size(&type)); 443 ret = dwarf_bytesize(&type);
962 if (!ret) 444 if (ret <= 0)
963 /* No size ... try to use default type */ 445 /* No size ... try to use default type */
964 return 0; 446 return 0;
447 ret = BYTES_TO_BITS(ret);
965 448
966 /* Check the bitwidth */ 449 /* Check the bitwidth */
967 if (ret > MAX_BASIC_TYPE_BITS) { 450 if (ret > MAX_BASIC_TYPE_BITS) {
@@ -1025,7 +508,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
1025 else 508 else
1026 *ref_ptr = ref; 509 *ref_ptr = ref;
1027 } 510 }
1028 ref->offset += die_get_byte_size(&type) * field->index; 511 ref->offset += dwarf_bytesize(&type) * field->index;
1029 if (!field->next) 512 if (!field->next)
1030 /* Save vr_die for converting types */ 513 /* Save vr_die for converting types */
1031 memcpy(die_mem, vr_die, sizeof(*die_mem)); 514 memcpy(die_mem, vr_die, sizeof(*die_mem));
@@ -1245,8 +728,7 @@ static int call_probe_finder(Dwarf_Die *sp_die, struct probe_finder *pf)
1245 728
1246 /* If no real subprogram, find a real one */ 729 /* If no real subprogram, find a real one */
1247 if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) { 730 if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) {
1248 sp_die = die_find_real_subprogram(&pf->cu_die, 731 sp_die = die_find_realfunc(&pf->cu_die, pf->addr, &die_mem);
1249 pf->addr, &die_mem);
1250 if (!sp_die) { 732 if (!sp_die) {
1251 pr_warning("Failed to find probe point in any " 733 pr_warning("Failed to find probe point in any "
1252 "functions.\n"); 734 "functions.\n");
@@ -1504,28 +986,18 @@ static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
1504} 986}
1505 987
1506/* Find probe points from debuginfo */ 988/* Find probe points from debuginfo */
1507static int find_probes(int fd, struct probe_finder *pf) 989static int debuginfo__find_probes(struct debuginfo *self,
990 struct probe_finder *pf)
1508{ 991{
1509 struct perf_probe_point *pp = &pf->pev->point; 992 struct perf_probe_point *pp = &pf->pev->point;
1510 Dwarf_Off off, noff; 993 Dwarf_Off off, noff;
1511 size_t cuhl; 994 size_t cuhl;
1512 Dwarf_Die *diep; 995 Dwarf_Die *diep;
1513 Dwarf *dbg = NULL;
1514 Dwfl *dwfl;
1515 Dwarf_Addr bias; /* Currently ignored */
1516 int ret = 0; 996 int ret = 0;
1517 997
1518 dbg = dwfl_init_offline_dwarf(fd, &dwfl, &bias);
1519 if (!dbg) {
1520 pr_warning("No debug information found in the vmlinux - "
1521 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1522 close(fd); /* Without dwfl_end(), fd isn't closed. */
1523 return -EBADF;
1524 }
1525
1526#if _ELFUTILS_PREREQ(0, 142) 998#if _ELFUTILS_PREREQ(0, 142)
1527 /* Get the call frame information from this dwarf */ 999 /* Get the call frame information from this dwarf */
1528 pf->cfi = dwarf_getcfi(dbg); 1000 pf->cfi = dwarf_getcfi(self->dbg);
1529#endif 1001#endif
1530 1002
1531 off = 0; 1003 off = 0;
@@ -1544,7 +1016,8 @@ static int find_probes(int fd, struct probe_finder *pf)
1544 .data = pf, 1016 .data = pf,
1545 }; 1017 };
1546 1018
1547 dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0); 1019 dwarf_getpubnames(self->dbg, pubname_search_cb,
1020 &pubname_param, 0);
1548 if (pubname_param.found) { 1021 if (pubname_param.found) {
1549 ret = probe_point_search_cb(&pf->sp_die, &probe_param); 1022 ret = probe_point_search_cb(&pf->sp_die, &probe_param);
1550 if (ret) 1023 if (ret)
@@ -1553,9 +1026,9 @@ static int find_probes(int fd, struct probe_finder *pf)
1553 } 1026 }
1554 1027
1555 /* Loop on CUs (Compilation Unit) */ 1028 /* Loop on CUs (Compilation Unit) */
1556 while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) { 1029 while (!dwarf_nextcu(self->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
1557 /* Get the DIE(Debugging Information Entry) of this CU */ 1030 /* Get the DIE(Debugging Information Entry) of this CU */
1558 diep = dwarf_offdie(dbg, off + cuhl, &pf->cu_die); 1031 diep = dwarf_offdie(self->dbg, off + cuhl, &pf->cu_die);
1559 if (!diep) 1032 if (!diep)
1560 continue; 1033 continue;
1561 1034
@@ -1582,8 +1055,6 @@ static int find_probes(int fd, struct probe_finder *pf)
1582 1055
1583found: 1056found:
1584 line_list__free(&pf->lcache); 1057 line_list__free(&pf->lcache);
1585 if (dwfl)
1586 dwfl_end(dwfl);
1587 1058
1588 return ret; 1059 return ret;
1589} 1060}
@@ -1629,8 +1100,9 @@ static int add_probe_trace_event(Dwarf_Die *sp_die, struct probe_finder *pf)
1629} 1100}
1630 1101
1631/* Find probe_trace_events specified by perf_probe_event from debuginfo */ 1102/* Find probe_trace_events specified by perf_probe_event from debuginfo */
1632int find_probe_trace_events(int fd, struct perf_probe_event *pev, 1103int debuginfo__find_trace_events(struct debuginfo *self,
1633 struct probe_trace_event **tevs, int max_tevs) 1104 struct perf_probe_event *pev,
1105 struct probe_trace_event **tevs, int max_tevs)
1634{ 1106{
1635 struct trace_event_finder tf = { 1107 struct trace_event_finder tf = {
1636 .pf = {.pev = pev, .callback = add_probe_trace_event}, 1108 .pf = {.pev = pev, .callback = add_probe_trace_event},
@@ -1645,7 +1117,7 @@ int find_probe_trace_events(int fd, struct perf_probe_event *pev,
1645 tf.tevs = *tevs; 1117 tf.tevs = *tevs;
1646 tf.ntevs = 0; 1118 tf.ntevs = 0;
1647 1119
1648 ret = find_probes(fd, &tf.pf); 1120 ret = debuginfo__find_probes(self, &tf.pf);
1649 if (ret < 0) { 1121 if (ret < 0) {
1650 free(*tevs); 1122 free(*tevs);
1651 *tevs = NULL; 1123 *tevs = NULL;
@@ -1739,9 +1211,10 @@ out:
1739} 1211}
1740 1212
1741/* Find available variables at given probe point */ 1213/* Find available variables at given probe point */
1742int find_available_vars_at(int fd, struct perf_probe_event *pev, 1214int debuginfo__find_available_vars_at(struct debuginfo *self,
1743 struct variable_list **vls, int max_vls, 1215 struct perf_probe_event *pev,
1744 bool externs) 1216 struct variable_list **vls,
1217 int max_vls, bool externs)
1745{ 1218{
1746 struct available_var_finder af = { 1219 struct available_var_finder af = {
1747 .pf = {.pev = pev, .callback = add_available_vars}, 1220 .pf = {.pev = pev, .callback = add_available_vars},
@@ -1756,7 +1229,7 @@ int find_available_vars_at(int fd, struct perf_probe_event *pev,
1756 af.vls = *vls; 1229 af.vls = *vls;
1757 af.nvls = 0; 1230 af.nvls = 0;
1758 1231
1759 ret = find_probes(fd, &af.pf); 1232 ret = debuginfo__find_probes(self, &af.pf);
1760 if (ret < 0) { 1233 if (ret < 0) {
1761 /* Free vlist for error */ 1234 /* Free vlist for error */
1762 while (af.nvls--) { 1235 while (af.nvls--) {
@@ -1774,28 +1247,19 @@ int find_available_vars_at(int fd, struct perf_probe_event *pev,
1774} 1247}
1775 1248
1776/* Reverse search */ 1249/* Reverse search */
1777int find_perf_probe_point(unsigned long addr, struct perf_probe_point *ppt) 1250int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
1251 struct perf_probe_point *ppt)
1778{ 1252{
1779 Dwarf_Die cudie, spdie, indie; 1253 Dwarf_Die cudie, spdie, indie;
1780 Dwarf *dbg = NULL; 1254 Dwarf_Addr _addr, baseaddr;
1781 Dwfl *dwfl = NULL;
1782 Dwarf_Addr _addr, baseaddr, bias = 0;
1783 const char *fname = NULL, *func = NULL, *tmp; 1255 const char *fname = NULL, *func = NULL, *tmp;
1784 int baseline = 0, lineno = 0, ret = 0; 1256 int baseline = 0, lineno = 0, ret = 0;
1785 1257
1786 /* Open the live linux kernel */
1787 dbg = dwfl_init_live_kernel_dwarf(addr, &dwfl, &bias);
1788 if (!dbg) {
1789 pr_warning("No debug information found in the vmlinux - "
1790 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1791 ret = -EINVAL;
1792 goto end;
1793 }
1794
1795 /* Adjust address with bias */ 1258 /* Adjust address with bias */
1796 addr += bias; 1259 addr += self->bias;
1260
1797 /* Find cu die */ 1261 /* Find cu die */
1798 if (!dwarf_addrdie(dbg, (Dwarf_Addr)addr - bias, &cudie)) { 1262 if (!dwarf_addrdie(self->dbg, (Dwarf_Addr)addr - self->bias, &cudie)) {
1799 pr_warning("Failed to find debug information for address %lx\n", 1263 pr_warning("Failed to find debug information for address %lx\n",
1800 addr); 1264 addr);
1801 ret = -EINVAL; 1265 ret = -EINVAL;
@@ -1807,7 +1271,7 @@ int find_perf_probe_point(unsigned long addr, struct perf_probe_point *ppt)
1807 /* Don't care whether it failed or not */ 1271 /* Don't care whether it failed or not */
1808 1272
1809 /* Find a corresponding function (name, baseline and baseaddr) */ 1273 /* Find a corresponding function (name, baseline and baseaddr) */
1810 if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) { 1274 if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) {
1811 /* Get function entry information */ 1275 /* Get function entry information */
1812 tmp = dwarf_diename(&spdie); 1276 tmp = dwarf_diename(&spdie);
1813 if (!tmp || 1277 if (!tmp ||
@@ -1871,8 +1335,6 @@ post:
1871 } 1335 }
1872 } 1336 }
1873end: 1337end:
1874 if (dwfl)
1875 dwfl_end(dwfl);
1876 if (ret == 0 && (fname || func)) 1338 if (ret == 0 && (fname || func))
1877 ret = 1; /* Found a point */ 1339 ret = 1; /* Found a point */
1878 return ret; 1340 return ret;
@@ -1982,26 +1444,15 @@ static int find_line_range_by_func(struct line_finder *lf)
1982 return param.retval; 1444 return param.retval;
1983} 1445}
1984 1446
1985int find_line_range(int fd, struct line_range *lr) 1447int debuginfo__find_line_range(struct debuginfo *self, struct line_range *lr)
1986{ 1448{
1987 struct line_finder lf = {.lr = lr, .found = 0}; 1449 struct line_finder lf = {.lr = lr, .found = 0};
1988 int ret = 0; 1450 int ret = 0;
1989 Dwarf_Off off = 0, noff; 1451 Dwarf_Off off = 0, noff;
1990 size_t cuhl; 1452 size_t cuhl;
1991 Dwarf_Die *diep; 1453 Dwarf_Die *diep;
1992 Dwarf *dbg = NULL;
1993 Dwfl *dwfl;
1994 Dwarf_Addr bias; /* Currently ignored */
1995 const char *comp_dir; 1454 const char *comp_dir;
1996 1455
1997 dbg = dwfl_init_offline_dwarf(fd, &dwfl, &bias);
1998 if (!dbg) {
1999 pr_warning("No debug information found in the vmlinux - "
2000 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
2001 close(fd); /* Without dwfl_end(), fd isn't closed. */
2002 return -EBADF;
2003 }
2004
2005 /* Fastpath: lookup by function name from .debug_pubnames section */ 1456 /* Fastpath: lookup by function name from .debug_pubnames section */
2006 if (lr->function) { 1457 if (lr->function) {
2007 struct pubname_callback_param pubname_param = { 1458 struct pubname_callback_param pubname_param = {
@@ -2010,7 +1461,8 @@ int find_line_range(int fd, struct line_range *lr)
2010 struct dwarf_callback_param line_range_param = { 1461 struct dwarf_callback_param line_range_param = {
2011 .data = (void *)&lf, .retval = 0}; 1462 .data = (void *)&lf, .retval = 0};
2012 1463
2013 dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0); 1464 dwarf_getpubnames(self->dbg, pubname_search_cb,
1465 &pubname_param, 0);
2014 if (pubname_param.found) { 1466 if (pubname_param.found) {
2015 line_range_search_cb(&lf.sp_die, &line_range_param); 1467 line_range_search_cb(&lf.sp_die, &line_range_param);
2016 if (lf.found) 1468 if (lf.found)
@@ -2020,11 +1472,12 @@ int find_line_range(int fd, struct line_range *lr)
2020 1472
2021 /* Loop on CUs (Compilation Unit) */ 1473 /* Loop on CUs (Compilation Unit) */
2022 while (!lf.found && ret >= 0) { 1474 while (!lf.found && ret >= 0) {
2023 if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0) 1475 if (dwarf_nextcu(self->dbg, off, &noff, &cuhl,
1476 NULL, NULL, NULL) != 0)
2024 break; 1477 break;
2025 1478
2026 /* Get the DIE(Debugging Information Entry) of this CU */ 1479 /* Get the DIE(Debugging Information Entry) of this CU */
2027 diep = dwarf_offdie(dbg, off + cuhl, &lf.cu_die); 1480 diep = dwarf_offdie(self->dbg, off + cuhl, &lf.cu_die);
2028 if (!diep) 1481 if (!diep)
2029 continue; 1482 continue;
2030 1483
@@ -2058,7 +1511,6 @@ found:
2058 } 1511 }
2059 1512
2060 pr_debug("path: %s\n", lr->path); 1513 pr_debug("path: %s\n", lr->path);
2061 dwfl_end(dwfl);
2062 return (ret < 0) ? ret : lf.found; 1514 return (ret < 0) ? ret : lf.found;
2063} 1515}
2064 1516
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index 605730a366db..c478b42a2473 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -16,27 +16,42 @@ static inline int is_c_varname(const char *name)
16} 16}
17 17
18#ifdef DWARF_SUPPORT 18#ifdef DWARF_SUPPORT
19
20#include "dwarf-aux.h"
21
22/* TODO: export debuginfo data structure even if no dwarf support */
23
24/* debug information structure */
25struct debuginfo {
26 Dwarf *dbg;
27 Dwfl *dwfl;
28 Dwarf_Addr bias;
29};
30
31extern struct debuginfo *debuginfo__new(const char *path);
32extern struct debuginfo *debuginfo__new_online_kernel(unsigned long addr);
33extern void debuginfo__delete(struct debuginfo *self);
34
19/* Find probe_trace_events specified by perf_probe_event from debuginfo */ 35/* Find probe_trace_events specified by perf_probe_event from debuginfo */
20extern int find_probe_trace_events(int fd, struct perf_probe_event *pev, 36extern int debuginfo__find_trace_events(struct debuginfo *self,
21 struct probe_trace_event **tevs, 37 struct perf_probe_event *pev,
22 int max_tevs); 38 struct probe_trace_event **tevs,
39 int max_tevs);
23 40
24/* Find a perf_probe_point from debuginfo */ 41/* Find a perf_probe_point from debuginfo */
25extern int find_perf_probe_point(unsigned long addr, 42extern int debuginfo__find_probe_point(struct debuginfo *self,
26 struct perf_probe_point *ppt); 43 unsigned long addr,
44 struct perf_probe_point *ppt);
27 45
28/* Find a line range */ 46/* Find a line range */
29extern int find_line_range(int fd, struct line_range *lr); 47extern int debuginfo__find_line_range(struct debuginfo *self,
48 struct line_range *lr);
30 49
31/* Find available variables */ 50/* Find available variables */
32extern int find_available_vars_at(int fd, struct perf_probe_event *pev, 51extern int debuginfo__find_available_vars_at(struct debuginfo *self,
33 struct variable_list **vls, int max_points, 52 struct perf_probe_event *pev,
34 bool externs); 53 struct variable_list **vls,
35 54 int max_points, bool externs);
36#include <dwarf.h>
37#include <elfutils/libdw.h>
38#include <elfutils/libdwfl.h>
39#include <elfutils/version.h>
40 55
41struct probe_finder { 56struct probe_finder {
42 struct perf_probe_event *pev; /* Target probe event */ 57 struct perf_probe_event *pev; /* Target probe event */
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index a9ac0504aabd..8e0b5a39d8a7 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -247,7 +247,7 @@ struct pyrf_cpu_map {
247static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus, 247static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
248 PyObject *args, PyObject *kwargs) 248 PyObject *args, PyObject *kwargs)
249{ 249{
250 static char *kwlist[] = { "cpustr", NULL, NULL, }; 250 static char *kwlist[] = { "cpustr", NULL };
251 char *cpustr = NULL; 251 char *cpustr = NULL;
252 252
253 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", 253 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
@@ -316,7 +316,7 @@ struct pyrf_thread_map {
316static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads, 316static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
317 PyObject *args, PyObject *kwargs) 317 PyObject *args, PyObject *kwargs)
318{ 318{
319 static char *kwlist[] = { "pid", "tid", NULL, NULL, }; 319 static char *kwlist[] = { "pid", "tid", NULL };
320 int pid = -1, tid = -1; 320 int pid = -1, tid = -1;
321 321
322 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", 322 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii",
@@ -418,7 +418,9 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
418 "wakeup_events", 418 "wakeup_events",
419 "bp_type", 419 "bp_type",
420 "bp_addr", 420 "bp_addr",
421 "bp_len", NULL, NULL, }; 421 "bp_len",
422 NULL
423 };
422 u64 sample_period = 0; 424 u64 sample_period = 0;
423 u32 disabled = 0, 425 u32 disabled = 0,
424 inherit = 0, 426 inherit = 0,
@@ -499,7 +501,7 @@ static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
499 struct thread_map *threads = NULL; 501 struct thread_map *threads = NULL;
500 PyObject *pcpus = NULL, *pthreads = NULL; 502 PyObject *pcpus = NULL, *pthreads = NULL;
501 int group = 0, inherit = 0; 503 int group = 0, inherit = 0;
502 static char *kwlist[] = {"cpus", "threads", "group", "inherit", NULL, NULL}; 504 static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL };
503 505
504 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, 506 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
505 &pcpus, &pthreads, &group, &inherit)) 507 &pcpus, &pthreads, &group, &inherit))
@@ -582,8 +584,7 @@ static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
582 PyObject *args, PyObject *kwargs) 584 PyObject *args, PyObject *kwargs)
583{ 585{
584 struct perf_evlist *evlist = &pevlist->evlist; 586 struct perf_evlist *evlist = &pevlist->evlist;
585 static char *kwlist[] = {"pages", "overwrite", 587 static char *kwlist[] = { "pages", "overwrite", NULL };
586 NULL, NULL};
587 int pages = 128, overwrite = false; 588 int pages = 128, overwrite = false;
588 589
589 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist, 590 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
@@ -603,7 +604,7 @@ static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
603 PyObject *args, PyObject *kwargs) 604 PyObject *args, PyObject *kwargs)
604{ 605{
605 struct perf_evlist *evlist = &pevlist->evlist; 606 struct perf_evlist *evlist = &pevlist->evlist;
606 static char *kwlist[] = {"timeout", NULL, NULL}; 607 static char *kwlist[] = { "timeout", NULL };
607 int timeout = -1, n; 608 int timeout = -1, n;
608 609
609 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout)) 610 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
@@ -674,7 +675,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
674 struct perf_evlist *evlist = &pevlist->evlist; 675 struct perf_evlist *evlist = &pevlist->evlist;
675 union perf_event *event; 676 union perf_event *event;
676 int sample_id_all = 1, cpu; 677 int sample_id_all = 1, cpu;
677 static char *kwlist[] = {"cpu", "sample_id_all", NULL, NULL}; 678 static char *kwlist[] = { "cpu", "sample_id_all", NULL };
678 int err; 679 int err;
679 680
680 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist, 681 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index f5a8fbdd3f76..72458d9da5b1 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -12,6 +12,7 @@
12#include "session.h" 12#include "session.h"
13#include "sort.h" 13#include "sort.h"
14#include "util.h" 14#include "util.h"
15#include "cpumap.h"
15 16
16static int perf_session__open(struct perf_session *self, bool force) 17static int perf_session__open(struct perf_session *self, bool force)
17{ 18{
@@ -247,9 +248,14 @@ int perf_session__resolve_callchain(struct perf_session *self,
247 callchain_cursor_reset(&self->callchain_cursor); 248 callchain_cursor_reset(&self->callchain_cursor);
248 249
249 for (i = 0; i < chain->nr; i++) { 250 for (i = 0; i < chain->nr; i++) {
250 u64 ip = chain->ips[i]; 251 u64 ip;
251 struct addr_location al; 252 struct addr_location al;
252 253
254 if (callchain_param.order == ORDER_CALLEE)
255 ip = chain->ips[i];
256 else
257 ip = chain->ips[chain->nr - i - 1];
258
253 if (ip >= PERF_CONTEXT_MAX) { 259 if (ip >= PERF_CONTEXT_MAX) {
254 switch (ip) { 260 switch (ip) {
255 case PERF_CONTEXT_HV: 261 case PERF_CONTEXT_HV:
@@ -407,20 +413,26 @@ static void perf_event__read_swap(union perf_event *event)
407 event->read.id = bswap_64(event->read.id); 413 event->read.id = bswap_64(event->read.id);
408} 414}
409 415
410static void perf_event__attr_swap(union perf_event *event) 416/* exported for swapping attributes in file header */
417void perf_event__attr_swap(struct perf_event_attr *attr)
418{
419 attr->type = bswap_32(attr->type);
420 attr->size = bswap_32(attr->size);
421 attr->config = bswap_64(attr->config);
422 attr->sample_period = bswap_64(attr->sample_period);
423 attr->sample_type = bswap_64(attr->sample_type);
424 attr->read_format = bswap_64(attr->read_format);
425 attr->wakeup_events = bswap_32(attr->wakeup_events);
426 attr->bp_type = bswap_32(attr->bp_type);
427 attr->bp_addr = bswap_64(attr->bp_addr);
428 attr->bp_len = bswap_64(attr->bp_len);
429}
430
431static void perf_event__hdr_attr_swap(union perf_event *event)
411{ 432{
412 size_t size; 433 size_t size;
413 434
414 event->attr.attr.type = bswap_32(event->attr.attr.type); 435 perf_event__attr_swap(&event->attr.attr);
415 event->attr.attr.size = bswap_32(event->attr.attr.size);
416 event->attr.attr.config = bswap_64(event->attr.attr.config);
417 event->attr.attr.sample_period = bswap_64(event->attr.attr.sample_period);
418 event->attr.attr.sample_type = bswap_64(event->attr.attr.sample_type);
419 event->attr.attr.read_format = bswap_64(event->attr.attr.read_format);
420 event->attr.attr.wakeup_events = bswap_32(event->attr.attr.wakeup_events);
421 event->attr.attr.bp_type = bswap_32(event->attr.attr.bp_type);
422 event->attr.attr.bp_addr = bswap_64(event->attr.attr.bp_addr);
423 event->attr.attr.bp_len = bswap_64(event->attr.attr.bp_len);
424 436
425 size = event->header.size; 437 size = event->header.size;
426 size -= (void *)&event->attr.id - (void *)event; 438 size -= (void *)&event->attr.id - (void *)event;
@@ -448,7 +460,7 @@ static perf_event__swap_op perf_event__swap_ops[] = {
448 [PERF_RECORD_LOST] = perf_event__all64_swap, 460 [PERF_RECORD_LOST] = perf_event__all64_swap,
449 [PERF_RECORD_READ] = perf_event__read_swap, 461 [PERF_RECORD_READ] = perf_event__read_swap,
450 [PERF_RECORD_SAMPLE] = perf_event__all64_swap, 462 [PERF_RECORD_SAMPLE] = perf_event__all64_swap,
451 [PERF_RECORD_HEADER_ATTR] = perf_event__attr_swap, 463 [PERF_RECORD_HEADER_ATTR] = perf_event__hdr_attr_swap,
452 [PERF_RECORD_HEADER_EVENT_TYPE] = perf_event__event_type_swap, 464 [PERF_RECORD_HEADER_EVENT_TYPE] = perf_event__event_type_swap,
453 [PERF_RECORD_HEADER_TRACING_DATA] = perf_event__tracing_data_swap, 465 [PERF_RECORD_HEADER_TRACING_DATA] = perf_event__tracing_data_swap,
454 [PERF_RECORD_HEADER_BUILD_ID] = NULL, 466 [PERF_RECORD_HEADER_BUILD_ID] = NULL,
@@ -708,9 +720,9 @@ static void dump_sample(struct perf_session *session, union perf_event *event,
708 if (!dump_trace) 720 if (!dump_trace)
709 return; 721 return;
710 722
711 printf("(IP, %d): %d/%d: %#" PRIx64 " period: %" PRIu64 "\n", 723 printf("(IP, %d): %d/%d: %#" PRIx64 " period: %" PRIu64 " addr: %#" PRIx64 "\n",
712 event->header.misc, sample->pid, sample->tid, sample->ip, 724 event->header.misc, sample->pid, sample->tid, sample->ip,
713 sample->period); 725 sample->period, sample->addr);
714 726
715 if (session->sample_type & PERF_SAMPLE_CALLCHAIN) 727 if (session->sample_type & PERF_SAMPLE_CALLCHAIN)
716 callchain__printf(sample); 728 callchain__printf(sample);
@@ -1202,9 +1214,10 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
1202 return NULL; 1214 return NULL;
1203} 1215}
1204 1216
1205void perf_session__print_symbols(union perf_event *event, 1217void perf_session__print_ip(union perf_event *event,
1206 struct perf_sample *sample, 1218 struct perf_sample *sample,
1207 struct perf_session *session) 1219 struct perf_session *session,
1220 int print_sym, int print_dso)
1208{ 1221{
1209 struct addr_location al; 1222 struct addr_location al;
1210 const char *symname, *dsoname; 1223 const char *symname, *dsoname;
@@ -1233,32 +1246,83 @@ void perf_session__print_symbols(union perf_event *event,
1233 if (!node) 1246 if (!node)
1234 break; 1247 break;
1235 1248
1236 if (node->sym && node->sym->name) 1249 printf("\t%16" PRIx64, node->ip);
1237 symname = node->sym->name; 1250 if (print_sym) {
1251 if (node->sym && node->sym->name)
1252 symname = node->sym->name;
1253 else
1254 symname = "";
1255
1256 printf(" %s", symname);
1257 }
1258 if (print_dso) {
1259 if (node->map && node->map->dso && node->map->dso->name)
1260 dsoname = node->map->dso->name;
1261 else
1262 dsoname = "";
1263
1264 printf(" (%s)", dsoname);
1265 }
1266 printf("\n");
1267
1268 callchain_cursor_advance(cursor);
1269 }
1270
1271 } else {
1272 printf("%16" PRIx64, sample->ip);
1273 if (print_sym) {
1274 if (al.sym && al.sym->name)
1275 symname = al.sym->name;
1238 else 1276 else
1239 symname = ""; 1277 symname = "";
1240 1278
1241 if (node->map && node->map->dso && node->map->dso->name) 1279 printf(" %s", symname);
1242 dsoname = node->map->dso->name; 1280 }
1281
1282 if (print_dso) {
1283 if (al.map && al.map->dso && al.map->dso->name)
1284 dsoname = al.map->dso->name;
1243 else 1285 else
1244 dsoname = ""; 1286 dsoname = "";
1245 1287
1246 printf("\t%16" PRIx64 " %s (%s)\n", node->ip, symname, dsoname); 1288 printf(" (%s)", dsoname);
1289 }
1290 }
1291}
1247 1292
1248 callchain_cursor_advance(cursor); 1293int perf_session__cpu_bitmap(struct perf_session *session,
1294 const char *cpu_list, unsigned long *cpu_bitmap)
1295{
1296 int i;
1297 struct cpu_map *map;
1298
1299 for (i = 0; i < PERF_TYPE_MAX; ++i) {
1300 struct perf_evsel *evsel;
1301
1302 evsel = perf_session__find_first_evtype(session, i);
1303 if (!evsel)
1304 continue;
1305
1306 if (!(evsel->attr.sample_type & PERF_SAMPLE_CPU)) {
1307 pr_err("File does not contain CPU events. "
1308 "Remove -c option to proceed.\n");
1309 return -1;
1249 } 1310 }
1311 }
1250 1312
1251 } else { 1313 map = cpu_map__new(cpu_list);
1252 if (al.sym && al.sym->name)
1253 symname = al.sym->name;
1254 else
1255 symname = "";
1256 1314
1257 if (al.map && al.map->dso && al.map->dso->name) 1315 for (i = 0; i < map->nr; i++) {
1258 dsoname = al.map->dso->name; 1316 int cpu = map->map[i];
1259 else 1317
1260 dsoname = ""; 1318 if (cpu >= MAX_NR_CPUS) {
1319 pr_err("Requested CPU %d too large. "
1320 "Consider raising MAX_NR_CPUS\n", cpu);
1321 return -1;
1322 }
1261 1323
1262 printf("%16" PRIx64 " %s (%s)", al.addr, symname, dsoname); 1324 set_bit(cpu, cpu_bitmap);
1263 } 1325 }
1326
1327 return 0;
1264} 1328}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 66d4e1490879..170601e67d6b 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -112,6 +112,7 @@ int perf_session__set_kallsyms_ref_reloc_sym(struct map **maps,
112 u64 addr); 112 u64 addr);
113 113
114void mem_bswap_64(void *src, int byte_size); 114void mem_bswap_64(void *src, int byte_size);
115void perf_event__attr_swap(struct perf_event_attr *attr);
115 116
116int perf_session__create_kernel_maps(struct perf_session *self); 117int perf_session__create_kernel_maps(struct perf_session *self);
117 118
@@ -167,8 +168,12 @@ static inline int perf_session__parse_sample(struct perf_session *session,
167struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, 168struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
168 unsigned int type); 169 unsigned int type);
169 170
170void perf_session__print_symbols(union perf_event *event, 171void perf_session__print_ip(union perf_event *event,
171 struct perf_sample *sample, 172 struct perf_sample *sample,
172 struct perf_session *session); 173 struct perf_session *session,
174 int print_sym, int print_dso);
175
176int perf_session__cpu_bitmap(struct perf_session *session,
177 const char *cpu_list, unsigned long *cpu_bitmap);
173 178
174#endif /* __PERF_SESSION_H */ 179#endif /* __PERF_SESSION_H */
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index f44fa541d56e..401e220566fd 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -15,95 +15,6 @@ char * field_sep;
15 15
16LIST_HEAD(hist_entry__sort_list); 16LIST_HEAD(hist_entry__sort_list);
17 17
18static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
19 size_t size, unsigned int width);
20static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
21 size_t size, unsigned int width);
22static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
23 size_t size, unsigned int width);
24static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
25 size_t size, unsigned int width);
26static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
27 size_t size, unsigned int width);
28static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf,
29 size_t size, unsigned int width);
30
31struct sort_entry sort_thread = {
32 .se_header = "Command: Pid",
33 .se_cmp = sort__thread_cmp,
34 .se_snprintf = hist_entry__thread_snprintf,
35 .se_width_idx = HISTC_THREAD,
36};
37
38struct sort_entry sort_comm = {
39 .se_header = "Command",
40 .se_cmp = sort__comm_cmp,
41 .se_collapse = sort__comm_collapse,
42 .se_snprintf = hist_entry__comm_snprintf,
43 .se_width_idx = HISTC_COMM,
44};
45
46struct sort_entry sort_dso = {
47 .se_header = "Shared Object",
48 .se_cmp = sort__dso_cmp,
49 .se_snprintf = hist_entry__dso_snprintf,
50 .se_width_idx = HISTC_DSO,
51};
52
53struct sort_entry sort_sym = {
54 .se_header = "Symbol",
55 .se_cmp = sort__sym_cmp,
56 .se_snprintf = hist_entry__sym_snprintf,
57 .se_width_idx = HISTC_SYMBOL,
58};
59
60struct sort_entry sort_parent = {
61 .se_header = "Parent symbol",
62 .se_cmp = sort__parent_cmp,
63 .se_snprintf = hist_entry__parent_snprintf,
64 .se_width_idx = HISTC_PARENT,
65};
66
67struct sort_entry sort_cpu = {
68 .se_header = "CPU",
69 .se_cmp = sort__cpu_cmp,
70 .se_snprintf = hist_entry__cpu_snprintf,
71 .se_width_idx = HISTC_CPU,
72};
73
74struct sort_dimension {
75 const char *name;
76 struct sort_entry *entry;
77 int taken;
78};
79
80static struct sort_dimension sort_dimensions[] = {
81 { .name = "pid", .entry = &sort_thread, },
82 { .name = "comm", .entry = &sort_comm, },
83 { .name = "dso", .entry = &sort_dso, },
84 { .name = "symbol", .entry = &sort_sym, },
85 { .name = "parent", .entry = &sort_parent, },
86 { .name = "cpu", .entry = &sort_cpu, },
87};
88
89int64_t cmp_null(void *l, void *r)
90{
91 if (!l && !r)
92 return 0;
93 else if (!l)
94 return -1;
95 else
96 return 1;
97}
98
99/* --sort pid */
100
101int64_t
102sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
103{
104 return right->thread->pid - left->thread->pid;
105}
106
107static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...) 18static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
108{ 19{
109 int n; 20 int n;
@@ -125,6 +36,24 @@ static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
125 return n; 36 return n;
126} 37}
127 38
39static int64_t cmp_null(void *l, void *r)
40{
41 if (!l && !r)
42 return 0;
43 else if (!l)
44 return -1;
45 else
46 return 1;
47}
48
49/* --sort pid */
50
51static int64_t
52sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
53{
54 return right->thread->pid - left->thread->pid;
55}
56
128static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf, 57static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
129 size_t size, unsigned int width) 58 size_t size, unsigned int width)
130{ 59{
@@ -132,15 +61,50 @@ static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
132 self->thread->comm ?: "", self->thread->pid); 61 self->thread->comm ?: "", self->thread->pid);
133} 62}
134 63
64struct sort_entry sort_thread = {
65 .se_header = "Command: Pid",
66 .se_cmp = sort__thread_cmp,
67 .se_snprintf = hist_entry__thread_snprintf,
68 .se_width_idx = HISTC_THREAD,
69};
70
71/* --sort comm */
72
73static int64_t
74sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
75{
76 return right->thread->pid - left->thread->pid;
77}
78
79static int64_t
80sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
81{
82 char *comm_l = left->thread->comm;
83 char *comm_r = right->thread->comm;
84
85 if (!comm_l || !comm_r)
86 return cmp_null(comm_l, comm_r);
87
88 return strcmp(comm_l, comm_r);
89}
90
135static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf, 91static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
136 size_t size, unsigned int width) 92 size_t size, unsigned int width)
137{ 93{
138 return repsep_snprintf(bf, size, "%*s", width, self->thread->comm); 94 return repsep_snprintf(bf, size, "%*s", width, self->thread->comm);
139} 95}
140 96
97struct sort_entry sort_comm = {
98 .se_header = "Command",
99 .se_cmp = sort__comm_cmp,
100 .se_collapse = sort__comm_collapse,
101 .se_snprintf = hist_entry__comm_snprintf,
102 .se_width_idx = HISTC_COMM,
103};
104
141/* --sort dso */ 105/* --sort dso */
142 106
143int64_t 107static int64_t
144sort__dso_cmp(struct hist_entry *left, struct hist_entry *right) 108sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
145{ 109{
146 struct dso *dso_l = left->ms.map ? left->ms.map->dso : NULL; 110 struct dso *dso_l = left->ms.map ? left->ms.map->dso : NULL;
@@ -173,9 +137,16 @@ static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
173 return repsep_snprintf(bf, size, "%-*s", width, "[unknown]"); 137 return repsep_snprintf(bf, size, "%-*s", width, "[unknown]");
174} 138}
175 139
140struct sort_entry sort_dso = {
141 .se_header = "Shared Object",
142 .se_cmp = sort__dso_cmp,
143 .se_snprintf = hist_entry__dso_snprintf,
144 .se_width_idx = HISTC_DSO,
145};
146
176/* --sort symbol */ 147/* --sort symbol */
177 148
178int64_t 149static int64_t
179sort__sym_cmp(struct hist_entry *left, struct hist_entry *right) 150sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
180{ 151{
181 u64 ip_l, ip_r; 152 u64 ip_l, ip_r;
@@ -211,29 +182,16 @@ static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
211 return ret; 182 return ret;
212} 183}
213 184
214/* --sort comm */ 185struct sort_entry sort_sym = {
215 186 .se_header = "Symbol",
216int64_t 187 .se_cmp = sort__sym_cmp,
217sort__comm_cmp(struct hist_entry *left, struct hist_entry *right) 188 .se_snprintf = hist_entry__sym_snprintf,
218{ 189 .se_width_idx = HISTC_SYMBOL,
219 return right->thread->pid - left->thread->pid; 190};
220}
221
222int64_t
223sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
224{
225 char *comm_l = left->thread->comm;
226 char *comm_r = right->thread->comm;
227
228 if (!comm_l || !comm_r)
229 return cmp_null(comm_l, comm_r);
230
231 return strcmp(comm_l, comm_r);
232}
233 191
234/* --sort parent */ 192/* --sort parent */
235 193
236int64_t 194static int64_t
237sort__parent_cmp(struct hist_entry *left, struct hist_entry *right) 195sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
238{ 196{
239 struct symbol *sym_l = left->parent; 197 struct symbol *sym_l = left->parent;
@@ -252,9 +210,16 @@ static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
252 self->parent ? self->parent->name : "[other]"); 210 self->parent ? self->parent->name : "[other]");
253} 211}
254 212
213struct sort_entry sort_parent = {
214 .se_header = "Parent symbol",
215 .se_cmp = sort__parent_cmp,
216 .se_snprintf = hist_entry__parent_snprintf,
217 .se_width_idx = HISTC_PARENT,
218};
219
255/* --sort cpu */ 220/* --sort cpu */
256 221
257int64_t 222static int64_t
258sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right) 223sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right)
259{ 224{
260 return right->cpu - left->cpu; 225 return right->cpu - left->cpu;
@@ -266,6 +231,28 @@ static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf,
266 return repsep_snprintf(bf, size, "%-*d", width, self->cpu); 231 return repsep_snprintf(bf, size, "%-*d", width, self->cpu);
267} 232}
268 233
234struct sort_entry sort_cpu = {
235 .se_header = "CPU",
236 .se_cmp = sort__cpu_cmp,
237 .se_snprintf = hist_entry__cpu_snprintf,
238 .se_width_idx = HISTC_CPU,
239};
240
241struct sort_dimension {
242 const char *name;
243 struct sort_entry *entry;
244 int taken;
245};
246
247static struct sort_dimension sort_dimensions[] = {
248 { .name = "pid", .entry = &sort_thread, },
249 { .name = "comm", .entry = &sort_comm, },
250 { .name = "dso", .entry = &sort_dso, },
251 { .name = "symbol", .entry = &sort_sym, },
252 { .name = "parent", .entry = &sort_parent, },
253 { .name = "cpu", .entry = &sort_cpu, },
254};
255
269int sort_dimension__add(const char *tok) 256int sort_dimension__add(const char *tok)
270{ 257{
271 unsigned int i; 258 unsigned int i;
@@ -273,15 +260,9 @@ int sort_dimension__add(const char *tok)
273 for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) { 260 for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
274 struct sort_dimension *sd = &sort_dimensions[i]; 261 struct sort_dimension *sd = &sort_dimensions[i];
275 262
276 if (sd->taken)
277 continue;
278
279 if (strncasecmp(tok, sd->name, strlen(tok))) 263 if (strncasecmp(tok, sd->name, strlen(tok)))
280 continue; 264 continue;
281 265
282 if (sd->entry->se_collapse)
283 sort__need_collapse = 1;
284
285 if (sd->entry == &sort_parent) { 266 if (sd->entry == &sort_parent) {
286 int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED); 267 int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED);
287 if (ret) { 268 if (ret) {
@@ -294,6 +275,12 @@ int sort_dimension__add(const char *tok)
294 sort__has_parent = 1; 275 sort__has_parent = 1;
295 } 276 }
296 277
278 if (sd->taken)
279 return 0;
280
281 if (sd->entry->se_collapse)
282 sort__need_collapse = 1;
283
297 if (list_empty(&hist_entry__sort_list)) { 284 if (list_empty(&hist_entry__sort_list)) {
298 if (!strcmp(sd->name, "pid")) 285 if (!strcmp(sd->name, "pid"))
299 sort__first_dimension = SORT_PID; 286 sort__first_dimension = SORT_PID;
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 0b91053a7d11..77d0388ad415 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -103,20 +103,6 @@ extern struct sort_entry sort_thread;
103extern struct list_head hist_entry__sort_list; 103extern struct list_head hist_entry__sort_list;
104 104
105void setup_sorting(const char * const usagestr[], const struct option *opts); 105void setup_sorting(const char * const usagestr[], const struct option *opts);
106
107extern size_t sort__thread_print(FILE *, struct hist_entry *, unsigned int);
108extern size_t sort__comm_print(FILE *, struct hist_entry *, unsigned int);
109extern size_t sort__dso_print(FILE *, struct hist_entry *, unsigned int);
110extern size_t sort__sym_print(FILE *, struct hist_entry *, unsigned int __used);
111extern int64_t cmp_null(void *, void *);
112extern int64_t sort__thread_cmp(struct hist_entry *, struct hist_entry *);
113extern int64_t sort__comm_cmp(struct hist_entry *, struct hist_entry *);
114extern int64_t sort__comm_collapse(struct hist_entry *, struct hist_entry *);
115extern int64_t sort__dso_cmp(struct hist_entry *, struct hist_entry *);
116extern int64_t sort__sym_cmp(struct hist_entry *, struct hist_entry *);
117extern int64_t sort__parent_cmp(struct hist_entry *, struct hist_entry *);
118int64_t sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right);
119extern size_t sort__parent_print(FILE *, struct hist_entry *, unsigned int);
120extern int sort_dimension__add(const char *); 106extern int sort_dimension__add(const char *);
121void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list, 107void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list,
122 const char *list_name, FILE *fp); 108 const char *list_name, FILE *fp);
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c
index b9a985dadd08..d5836382ff2c 100644
--- a/tools/perf/util/string.c
+++ b/tools/perf/util/string.c
@@ -294,3 +294,22 @@ bool strlazymatch(const char *str, const char *pat)
294{ 294{
295 return __match_glob(str, pat, true); 295 return __match_glob(str, pat, true);
296} 296}
297
298/**
299 * strtailcmp - Compare the tail of two strings
300 * @s1: 1st string to be compared
301 * @s2: 2nd string to be compared
302 *
303 * Return 0 if whole of either string is same as another's tail part.
304 */
305int strtailcmp(const char *s1, const char *s2)
306{
307 int i1 = strlen(s1);
308 int i2 = strlen(s2);
309 while (--i1 >= 0 && --i2 >= 0) {
310 if (s1[i1] != s2[i2])
311 return s1[i1] - s2[i2];
312 }
313 return 0;
314}
315
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index 35729f4c40cb..3403f814ad72 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -183,106 +183,59 @@ int bigendian(void)
183 return *ptr == 0x01020304; 183 return *ptr == 0x01020304;
184} 184}
185 185
186static unsigned long long copy_file_fd(int fd) 186/* unfortunately, you can not stat debugfs or proc files for size */
187static void record_file(const char *file, size_t hdr_sz)
187{ 188{
188 unsigned long long size = 0; 189 unsigned long long size = 0;
189 char buf[BUFSIZ]; 190 char buf[BUFSIZ], *sizep;
190 int r; 191 off_t hdr_pos = lseek(output_fd, 0, SEEK_CUR);
191 192 int r, fd;
192 do {
193 r = read(fd, buf, BUFSIZ);
194 if (r > 0) {
195 size += r;
196 write_or_die(buf, r);
197 }
198 } while (r > 0);
199
200 return size;
201}
202
203static unsigned long long copy_file(const char *file)
204{
205 unsigned long long size = 0;
206 int fd;
207 193
208 fd = open(file, O_RDONLY); 194 fd = open(file, O_RDONLY);
209 if (fd < 0) 195 if (fd < 0)
210 die("Can't read '%s'", file); 196 die("Can't read '%s'", file);
211 size = copy_file_fd(fd);
212 close(fd);
213 197
214 return size; 198 /* put in zeros for file size, then fill true size later */
215} 199 write_or_die(&size, hdr_sz);
216
217static unsigned long get_size_fd(int fd)
218{
219 unsigned long long size = 0;
220 char buf[BUFSIZ];
221 int r;
222 200
223 do { 201 do {
224 r = read(fd, buf, BUFSIZ); 202 r = read(fd, buf, BUFSIZ);
225 if (r > 0) 203 if (r > 0) {
226 size += r; 204 size += r;
205 write_or_die(buf, r);
206 }
227 } while (r > 0); 207 } while (r > 0);
228
229 lseek(fd, 0, SEEK_SET);
230
231 return size;
232}
233
234static unsigned long get_size(const char *file)
235{
236 unsigned long long size = 0;
237 int fd;
238
239 fd = open(file, O_RDONLY);
240 if (fd < 0)
241 die("Can't read '%s'", file);
242 size = get_size_fd(fd);
243 close(fd); 208 close(fd);
244 209
245 return size; 210 /* ugh, handle big-endian hdr_size == 4 */
211 sizep = (char*)&size;
212 if (bigendian())
213 sizep += sizeof(u64) - hdr_sz;
214
215 if (pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0)
216 die("writing to %s", output_file);
246} 217}
247 218
248static void read_header_files(void) 219static void read_header_files(void)
249{ 220{
250 unsigned long long size, check_size;
251 char *path; 221 char *path;
252 int fd; 222 struct stat st;
253 223
254 path = get_tracing_file("events/header_page"); 224 path = get_tracing_file("events/header_page");
255 fd = open(path, O_RDONLY); 225 if (stat(path, &st) < 0)
256 if (fd < 0)
257 die("can't read '%s'", path); 226 die("can't read '%s'", path);
258 227
259 /* unfortunately, you can not stat debugfs files for size */
260 size = get_size_fd(fd);
261
262 write_or_die("header_page", 12); 228 write_or_die("header_page", 12);
263 write_or_die(&size, 8); 229 record_file(path, 8);
264 check_size = copy_file_fd(fd);
265 close(fd);
266
267 if (size != check_size)
268 die("wrong size for '%s' size=%lld read=%lld",
269 path, size, check_size);
270 put_tracing_file(path); 230 put_tracing_file(path);
271 231
272 path = get_tracing_file("events/header_event"); 232 path = get_tracing_file("events/header_event");
273 fd = open(path, O_RDONLY); 233 if (stat(path, &st) < 0)
274 if (fd < 0)
275 die("can't read '%s'", path); 234 die("can't read '%s'", path);
276 235
277 size = get_size_fd(fd);
278
279 write_or_die("header_event", 13); 236 write_or_die("header_event", 13);
280 write_or_die(&size, 8); 237 record_file(path, 8);
281 check_size = copy_file_fd(fd);
282 if (size != check_size)
283 die("wrong size for '%s'", path);
284 put_tracing_file(path); 238 put_tracing_file(path);
285 close(fd);
286} 239}
287 240
288static bool name_in_tp_list(char *sys, struct tracepoint_path *tps) 241static bool name_in_tp_list(char *sys, struct tracepoint_path *tps)
@@ -298,7 +251,6 @@ static bool name_in_tp_list(char *sys, struct tracepoint_path *tps)
298 251
299static void copy_event_system(const char *sys, struct tracepoint_path *tps) 252static void copy_event_system(const char *sys, struct tracepoint_path *tps)
300{ 253{
301 unsigned long long size, check_size;
302 struct dirent *dent; 254 struct dirent *dent;
303 struct stat st; 255 struct stat st;
304 char *format; 256 char *format;
@@ -338,14 +290,8 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps)
338 sprintf(format, "%s/%s/format", sys, dent->d_name); 290 sprintf(format, "%s/%s/format", sys, dent->d_name);
339 ret = stat(format, &st); 291 ret = stat(format, &st);
340 292
341 if (ret >= 0) { 293 if (ret >= 0)
342 /* unfortunately, you can not stat debugfs files for size */ 294 record_file(format, 8);
343 size = get_size(format);
344 write_or_die(&size, 8);
345 check_size = copy_file(format);
346 if (size != check_size)
347 die("error in size of file '%s'", format);
348 }
349 295
350 free(format); 296 free(format);
351 } 297 }
@@ -426,7 +372,7 @@ static void read_event_files(struct tracepoint_path *tps)
426 372
427static void read_proc_kallsyms(void) 373static void read_proc_kallsyms(void)
428{ 374{
429 unsigned int size, check_size; 375 unsigned int size;
430 const char *path = "/proc/kallsyms"; 376 const char *path = "/proc/kallsyms";
431 struct stat st; 377 struct stat st;
432 int ret; 378 int ret;
@@ -438,17 +384,12 @@ static void read_proc_kallsyms(void)
438 write_or_die(&size, 4); 384 write_or_die(&size, 4);
439 return; 385 return;
440 } 386 }
441 size = get_size(path); 387 record_file(path, 4);
442 write_or_die(&size, 4);
443 check_size = copy_file(path);
444 if (size != check_size)
445 die("error in size of file '%s'", path);
446
447} 388}
448 389
449static void read_ftrace_printk(void) 390static void read_ftrace_printk(void)
450{ 391{
451 unsigned int size, check_size; 392 unsigned int size;
452 char *path; 393 char *path;
453 struct stat st; 394 struct stat st;
454 int ret; 395 int ret;
@@ -461,11 +402,8 @@ static void read_ftrace_printk(void)
461 write_or_die(&size, 4); 402 write_or_die(&size, 4);
462 goto out; 403 goto out;
463 } 404 }
464 size = get_size(path); 405 record_file(path, 4);
465 write_or_die(&size, 4); 406
466 check_size = copy_file(path);
467 if (size != check_size)
468 die("error in size of file '%s'", path);
469out: 407out:
470 put_tracing_file(path); 408 put_tracing_file(path);
471} 409}
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index fc784284ac8b..0128906bac88 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -238,6 +238,7 @@ char **argv_split(const char *str, int *argcp);
238void argv_free(char **argv); 238void argv_free(char **argv);
239bool strglobmatch(const char *str, const char *pat); 239bool strglobmatch(const char *str, const char *pat);
240bool strlazymatch(const char *str, const char *pat); 240bool strlazymatch(const char *str, const char *pat);
241int strtailcmp(const char *s1, const char *s2);
241unsigned long convert_unit(unsigned long value, char *unit); 242unsigned long convert_unit(unsigned long value, char *unit);
242int readn(int fd, void *buf, size_t size); 243int readn(int fd, void *buf, size_t size);
243 244
diff --git a/tools/power/cpupower/.gitignore b/tools/power/cpupower/.gitignore
new file mode 100644
index 000000000000..8a83dd2ffc11
--- /dev/null
+++ b/tools/power/cpupower/.gitignore
@@ -0,0 +1,22 @@
1.libs
2libcpupower.so
3libcpupower.so.0
4libcpupower.so.0.0.0
5build/ccdv
6cpufreq-info
7cpufreq-set
8cpufreq-aperf
9lib/.libs
10lib/cpufreq.lo
11lib/cpufreq.o
12lib/proc.lo
13lib/proc.o
14lib/sysfs.lo
15lib/sysfs.o
16po/cpupowerutils.pot
17po/*.gmo
18utils/cpufreq-info.o
19utils/cpufreq-set.o
20utils/cpufreq-aperf.o
21cpupower
22bench/cpufreq-bench
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile
new file mode 100644
index 000000000000..94c2cf0a98b8
--- /dev/null
+++ b/tools/power/cpupower/Makefile
@@ -0,0 +1,279 @@
1# Makefile for cpupower
2#
3# Copyright (C) 2005,2006 Dominik Brodowski <linux@dominikbrodowski.net>
4#
5# Based largely on the Makefile for udev by:
6#
7# Copyright (C) 2003,2004 Greg Kroah-Hartman <greg@kroah.com>
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; version 2 of the License.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16# General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21#
22
23# --- CONFIGURATION BEGIN ---
24
25# Set the following to `true' to make a unstripped, unoptimized
26# binary. Leave this set to `false' for production use.
27DEBUG ?= false
28
29# make the build silent. Set this to something else to make it noisy again.
30V ?= false
31
32# Internationalization support (output in different languages).
33# Requires gettext.
34NLS ?= true
35
36# Set the following to 'true' to build/install the
37# cpufreq-bench benchmarking tool
38CPUFRQ_BENCH ?= true
39
40# Prefix to the directories we're installing to
41DESTDIR ?=
42
43# --- CONFIGURATION END ---
44
45
46
47# Package-related definitions. Distributions can modify the version
48# and _should_ modify the PACKAGE_BUGREPORT definition
49
50VERSION= $(shell ./utils/version-gen.sh)
51LIB_MAJ= 0.0.0
52LIB_MIN= 0
53
54PACKAGE = cpupower
55PACKAGE_BUGREPORT = cpufreq@vger.kernel.org
56LANGUAGES = de fr it cs pt
57
58
59# Directory definitions. These are default and most probably
60# do not need to be changed. Please note that DESTDIR is
61# added in front of any of them
62
63bindir ?= /usr/bin
64sbindir ?= /usr/sbin
65mandir ?= /usr/man
66includedir ?= /usr/include
67libdir ?= /usr/lib
68localedir ?= /usr/share/locale
69docdir ?= /usr/share/doc/packages/cpupower
70confdir ?= /etc/
71
72# Toolchain: what tools do we use, and what options do they need:
73
74CP = cp -fpR
75INSTALL = /usr/bin/install -c
76INSTALL_PROGRAM = ${INSTALL}
77INSTALL_DATA = ${INSTALL} -m 644
78INSTALL_SCRIPT = ${INSTALL_PROGRAM}
79
80# If you are running a cross compiler, you may want to set this
81# to something more interesting, like "arm-linux-". If you want
82# to compile vs uClibc, that can be done here as well.
83CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc-
84CC = $(CROSS)gcc
85LD = $(CROSS)gcc
86AR = $(CROSS)ar
87STRIP = $(CROSS)strip
88RANLIB = $(CROSS)ranlib
89HOSTCC = gcc
90
91
92# Now we set up the build system
93#
94
95# set up PWD so that older versions of make will work with our build.
96PWD = $(shell pwd)
97
98GMO_FILES = ${shell for HLANG in ${LANGUAGES}; do echo po/$$HLANG.gmo; done;}
99
100export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS
101
102# check if compiler option is supported
103cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; fi;}
104
105# use '-Os' optimization if available, else use -O2
106OPTIMIZATION := $(call cc-supports,-Os,-O2)
107
108WARNINGS := -Wall -Wchar-subscripts -Wpointer-arith -Wsign-compare
109WARNINGS += $(call cc-supports,-Wno-pointer-sign)
110WARNINGS += $(call cc-supports,-Wdeclaration-after-statement)
111WARNINGS += -Wshadow
112
113CFLAGS += -DVERSION=\"$(VERSION)\" -DPACKAGE=\"$(PACKAGE)\" \
114 -DPACKAGE_BUGREPORT=\"$(PACKAGE_BUGREPORT)\" -D_GNU_SOURCE
115
116UTIL_OBJS = utils/helpers/amd.o utils/helpers/topology.o utils/helpers/msr.o \
117 utils/helpers/sysfs.o utils/helpers/misc.o utils/helpers/cpuid.o \
118 utils/helpers/pci.o utils/helpers/bitmask.o \
119 utils/idle_monitor/nhm_idle.o utils/idle_monitor/snb_idle.o \
120 utils/idle_monitor/amd_fam14h_idle.o utils/idle_monitor/cpuidle_sysfs.o \
121 utils/idle_monitor/mperf_monitor.o utils/idle_monitor/cpupower-monitor.o \
122 utils/cpupower.o utils/cpufreq-info.o utils/cpufreq-set.o \
123 utils/cpupower-set.o utils/cpupower-info.o utils/cpuidle-info.o
124
125UTIL_HEADERS = utils/helpers/helpers.h utils/idle_monitor/cpupower-monitor.h \
126 utils/helpers/bitmask.h \
127 utils/idle_monitor/idle_monitors.h utils/idle_monitor/idle_monitors.def
128
129UTIL_SRC := $(UTIL_OBJS:.o=.c)
130
131LIB_HEADERS = lib/cpufreq.h lib/sysfs.h
132LIB_SRC = lib/cpufreq.c lib/sysfs.c
133LIB_OBJS = lib/cpufreq.o lib/sysfs.o
134
135CFLAGS += -pipe
136
137ifeq ($(strip $(NLS)),true)
138 INSTALL_NLS += install-gmo
139 COMPILE_NLS += create-gmo
140endif
141
142ifeq ($(strip $(CPUFRQ_BENCH)),true)
143 INSTALL_BENCH += install-bench
144 COMPILE_BENCH += compile-bench
145endif
146
147CFLAGS += $(WARNINGS)
148
149ifeq ($(strip $(V)),false)
150 QUIET=@
151 ECHO=@echo
152else
153 QUIET=
154 ECHO=@\#
155endif
156export QUIET ECHO
157
158# if DEBUG is enabled, then we do not strip or optimize
159ifeq ($(strip $(DEBUG)),true)
160 CFLAGS += -O1 -g -DDEBUG
161 STRIPCMD = /bin/true -Since_we_are_debugging
162else
163 CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer
164 STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment
165endif
166
167
168# the actual make rules
169
170all: libcpupower cpupower $(COMPILE_NLS) $(COMPILE_BENCH)
171
172lib/%.o: $(LIB_SRC) $(LIB_HEADERS)
173 $(ECHO) " CC " $@
174 $(QUIET) $(CC) $(CFLAGS) -fPIC -o $@ -c lib/$*.c
175
176libcpupower.so.$(LIB_MAJ): $(LIB_OBJS)
177 $(ECHO) " LD " $@
178 $(QUIET) $(CC) -shared $(CFLAGS) $(LDFLAGS) -o $@ \
179 -Wl,-soname,libcpupower.so.$(LIB_MIN) $(LIB_OBJS)
180 @ln -sf $@ libcpupower.so
181 @ln -sf $@ libcpupower.so.$(LIB_MIN)
182
183libcpupower: libcpupower.so.$(LIB_MAJ)
184
185# Let all .o files depend on its .c file and all headers
186# Might be worth to put this into utils/Makefile at some point of time
187$(UTIL_OBJS): $(UTIL_HEADERS)
188
189.c.o:
190 $(ECHO) " CC " $@
191 $(QUIET) $(CC) $(CFLAGS) -I./lib -I ./utils -o $@ -c $*.c
192
193cpupower: $(UTIL_OBJS) libcpupower.so.$(LIB_MAJ)
194 $(ECHO) " CC " $@
195 $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) -lcpupower -lrt -lpci -L. -o $@ $(UTIL_OBJS)
196 $(QUIET) $(STRIPCMD) $@
197
198po/$(PACKAGE).pot: $(UTIL_SRC)
199 $(ECHO) " GETTEXT " $@
200 $(QUIET) xgettext --default-domain=$(PACKAGE) --add-comments \
201 --keyword=_ --keyword=N_ $(UTIL_SRC) && \
202 test -f $(PACKAGE).po && \
203 mv -f $(PACKAGE).po po/$(PACKAGE).pot
204
205po/%.gmo: po/%.po
206 $(ECHO) " MSGFMT " $@
207 $(QUIET) msgfmt -o $@ po/$*.po
208
209create-gmo: ${GMO_FILES}
210
211update-po: po/$(PACKAGE).pot
212 $(ECHO) " MSGMRG " $@
213 $(QUIET) @for HLANG in $(LANGUAGES); do \
214 echo -n "Updating $$HLANG "; \
215 if msgmerge po/$$HLANG.po po/$(PACKAGE).pot -o \
216 po/$$HLANG.new.po; then \
217 mv -f po/$$HLANG.new.po po/$$HLANG.po; \
218 else \
219 echo "msgmerge for $$HLANG failed!"; \
220 rm -f po/$$HLANG.new.po; \
221 fi; \
222 done;
223
224compile-bench: libcpupower.so.$(LIB_MAJ)
225 @V=$(V) confdir=$(confdir) $(MAKE) -C bench
226
227clean:
228 -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \
229 | xargs rm -f
230 -rm -f $(UTIL_BINS)
231 -rm -f $(IDLE_OBJS)
232 -rm -f cpupower
233 -rm -f libcpupower.so*
234 -rm -rf po/*.gmo po/*.pot
235 $(MAKE) -C bench clean
236
237
238install-lib:
239 $(INSTALL) -d $(DESTDIR)${libdir}
240 $(CP) libcpupower.so* $(DESTDIR)${libdir}/
241 $(INSTALL) -d $(DESTDIR)${includedir}
242 $(INSTALL_DATA) lib/cpufreq.h $(DESTDIR)${includedir}/cpufreq.h
243
244install-tools:
245 $(INSTALL) -d $(DESTDIR)${bindir}
246 $(INSTALL_PROGRAM) cpupower $(DESTDIR)${bindir}
247
248install-man:
249 $(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1
250 $(INSTALL_DATA) -D man/cpupower-frequency-set.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-set.1
251 $(INSTALL_DATA) -D man/cpupower-frequency-info.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-info.1
252 $(INSTALL_DATA) -D man/cpupower-set.1 $(DESTDIR)${mandir}/man1/cpupower-set.1
253 $(INSTALL_DATA) -D man/cpupower-info.1 $(DESTDIR)${mandir}/man1/cpupower-info.1
254 $(INSTALL_DATA) -D man/cpupower-monitor.1 $(DESTDIR)${mandir}/man1/cpupower-monitor.1
255
256install-gmo:
257 $(INSTALL) -d $(DESTDIR)${localedir}
258 for HLANG in $(LANGUAGES); do \
259 echo '$(INSTALL_DATA) -D po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo'; \
260 $(INSTALL_DATA) -D po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \
261 done;
262
263install-bench:
264 @#DESTDIR must be set from outside to survive
265 @sbindir=$(sbindir) bindir=$(bindir) docdir=$(docdir) confdir=$(confdir) $(MAKE) -C bench install
266
267install: all install-lib install-tools install-man $(INSTALL_NLS) $(INSTALL_BENCH)
268
269uninstall:
270 - rm -f $(DESTDIR)${libdir}/libcpupower.*
271 - rm -f $(DESTDIR)${includedir}/cpufreq.h
272 - rm -f $(DESTDIR)${bindir}/utils/cpupower
273 - rm -f $(DESTDIR)${mandir}/man1/cpufreq-set.1
274 - rm -f $(DESTDIR)${mandir}/man1/cpufreq-info.1
275 - for HLANG in $(LANGUAGES); do \
276 rm -f $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \
277 done;
278
279.PHONY: all utils libcpupower update-po create-gmo install-lib install-tools install-man install-gmo install uninstall clean
diff --git a/tools/power/cpupower/README b/tools/power/cpupower/README
new file mode 100644
index 000000000000..fd9d4c0d6688
--- /dev/null
+++ b/tools/power/cpupower/README
@@ -0,0 +1,49 @@
1The cpufrequtils package (homepage:
2http://www.kernel.org/pub/linux/utils/kernel/cpufreq/cpufrequtils.html )
3consists of the following elements:
4
5requirements
6------------
7
8On x86 pciutils is needed at runtime (-lpci).
9For compilation pciutils-devel (pci/pci.h) and a gcc version
10providing cpuid.h is needed.
11For both it's not explicitly checked for (yet).
12
13
14libcpufreq
15----------
16
17"libcpufreq" is a library which offers a unified access method for userspace
18tools and programs to the cpufreq core and drivers in the Linux kernel. This
19allows for code reduction in userspace tools, a clean implementation of
20the interaction to the cpufreq core, and support for both the sysfs and proc
21interfaces [depending on configuration, see below].
22
23
24compilation and installation
25----------------------------
26
27make
28su
29make install
30
31should suffice on most systems. It builds default libcpufreq,
32cpufreq-set and cpufreq-info files and installs them in /usr/lib and
33/usr/bin, respectively. If you want to set up the paths differently and/or
34want to configure the package to your specific needs, you need to open
35"Makefile" with an editor of your choice and edit the block marked
36CONFIGURATION.
37
38
39THANKS
40------
41Many thanks to Mattia Dongili who wrote the autotoolization and
42libtoolization, the manpages and the italian language file for cpufrequtils;
43to Dave Jones for his feedback and his dump_psb tool; to Bruno Ducrot for his
44powernow-k8-decode and intel_gsic tools as well as the french language file;
45and to various others commenting on the previous (pre-)releases of
46cpufrequtils.
47
48
49 Dominik Brodowski
diff --git a/tools/power/cpupower/ToDo b/tools/power/cpupower/ToDo
new file mode 100644
index 000000000000..874b78b586ee
--- /dev/null
+++ b/tools/power/cpupower/ToDo
@@ -0,0 +1,11 @@
1ToDos sorted by priority:
2
3- Use bitmask functions to parse CPU topology more robust
4 (current implementation has issues on AMD)
5- Try to read out boost states and frequencies on Intel
6- Adjust README
7- Somewhere saw the ability to read power consumption of
8 RAM from HW on Intel SandyBridge -> another monitor?
9- Add another c1e debug idle monitor
10 -> Is by design racy with BIOS, but could be added
11 with a --force option and some "be careful" messages
diff --git a/tools/power/cpupower/bench/Makefile b/tools/power/cpupower/bench/Makefile
new file mode 100644
index 000000000000..2b67606fc3e3
--- /dev/null
+++ b/tools/power/cpupower/bench/Makefile
@@ -0,0 +1,29 @@
1LIBS = -L../ -lm -lcpupower
2
3OBJS = main.o parse.o system.o benchmark.o
4CFLAGS += -D_GNU_SOURCE -I../lib -DDEFAULT_CONFIG_FILE=\"$(confdir)/cpufreq-bench.conf\"
5
6%.o : %.c
7 $(ECHO) " CC " $@
8 $(QUIET) $(CC) -c $(CFLAGS) $< -o $@
9
10cpufreq-bench: $(OBJS)
11 $(ECHO) " CC " $@
12 $(QUIET) $(CC) -o $@ $(CFLAGS) $(OBJS) $(LIBS)
13
14all: cpufreq-bench
15
16install:
17 mkdir -p $(DESTDIR)/$(sbindir)
18 mkdir -p $(DESTDIR)/$(bindir)
19 mkdir -p $(DESTDIR)/$(docdir)
20 mkdir -p $(DESTDIR)/$(confdir)
21 install -m 755 cpufreq-bench $(DESTDIR)/$(sbindir)/cpufreq-bench
22 install -m 755 cpufreq-bench_plot.sh $(DESTDIR)/$(bindir)/cpufreq-bench_plot.sh
23 install -m 644 README-BENCH $(DESTDIR)/$(docdir)/README-BENCH
24 install -m 755 cpufreq-bench_script.sh $(DESTDIR)/$(docdir)/cpufreq-bench_script.sh
25 install -m 644 example.cfg $(DESTDIR)/$(confdir)/cpufreq-bench.conf
26
27clean:
28 rm -f *.o
29 rm -f cpufreq-bench
diff --git a/tools/power/cpupower/bench/README-BENCH b/tools/power/cpupower/bench/README-BENCH
new file mode 100644
index 000000000000..8093ec738170
--- /dev/null
+++ b/tools/power/cpupower/bench/README-BENCH
@@ -0,0 +1,124 @@
1This is cpufreq-bench, a microbenchmark for the cpufreq framework.
2
3Purpose
4=======
5
6What is this benchmark for:
7 - Identify worst case performance loss when doing dynamic frequency
8 scaling using Linux kernel governors
9 - Identify average reaction time of a governor to CPU load changes
10 - (Stress) Testing whether a cpufreq low level driver or governor works
11 as expected
12 - Identify cpufreq related performance regressions between kernels
13 - Possibly Real time priority testing? -> what happens if there are
14 processes with a higher prio than the governor's kernel thread
15 - ...
16
17What this benchmark does *not* cover:
18 - Power saving related regressions (In fact as better the performance
19 throughput is, the worse the power savings will be, but the first should
20 mostly count more...)
21 - Real world (workloads)
22
23
24Description
25===========
26
27cpufreq-bench helps to test the condition of a given cpufreq governor.
28For that purpose, it compares the performance governor to a configured
29powersave module.
30
31
32How it works
33============
34You can specify load (100% CPU load) and sleep (0% CPU load) times in us which
35will be run X time in a row (cycles):
36
37 sleep=25000
38 load=25000
39 cycles=20
40
41This part of the configuration file will create 25ms load/sleep turns,
42repeated 20 times.
43
44Adding this:
45 sleep_step=25000
46 load_step=25000
47 rounds=5
48Will increase load and sleep time by 25ms 5 times.
49Together you get following test:
5025ms load/sleep time repeated 20 times (cycles).
5150ms load/sleep time repeated 20 times (cycles).
52..
53100ms load/sleep time repeated 20 times (cycles).
54
55First it is calibrated how long a specific CPU intensive calculation
56takes on this machine and needs to be run in a loop using the performance
57governor.
58Then the above test runs are processed using the performance governor
59and the governor to test. The time the calculation really needed
60with the dynamic freq scaling governor is compared with the time needed
61on full performance and you get the overall performance loss.
62
63
64Example of expected results with ondemand governor:
65
66This shows expected results of the first two test run rounds from
67above config, you there have:
68
69100% CPU load (load) | 0 % CPU load (sleep) | round
70 25 ms | 25 ms | 1
71 50 ms | 50 ms | 2
72
73For example if ondemand governor is configured to have a 50ms
74sampling rate you get:
75
76In round 1, ondemand should have rather static 50% load and probably
77won't ever switch up (as long as up_threshold is above).
78
79In round 2, if the ondemand sampling times exactly match the load/sleep
80trigger of the cpufreq-bench, you will see no performance loss (compare with
81below possible ondemand sample kick ins (1)):
82
83But if ondemand always kicks in in the middle of the load sleep cycles, it
84will always see 50% loads and you get worst performance impact never
85switching up (compare with below possible ondemand sample kick ins (2))::
86
87 50 50 50 50ms ->time
88load -----| |-----| |-----| |-----|
89 | | | | | | |
90sleep |-----| |-----| |-----| |----
91 |-----|-----|-----|-----|-----|-----|-----|---- ondemand sampling (1)
92 100 0 100 0 100 0 100 load seen by ondemand(%)
93 |-----|-----|-----|-----|-----|-----|-----|-- ondemand sampling (2)
94 50 50 50 50 50 50 50 load seen by ondemand(%)
95
96You can easily test all kind of load/sleep times and check whether your
97governor in average behaves as expected.
98
99
100ToDo
101====
102
103Provide a gnuplot utility script for easy generation of plots to present
104the outcome nicely.
105
106
107cpufreq-bench Command Usage
108===========================
109-l, --load=<long int> initial load time in us
110-s, --sleep=<long int> initial sleep time in us
111-x, --load-step=<long int> time to be added to load time, in us
112-y, --sleep-step=<long int> time to be added to sleep time, in us
113-c, --cpu=<unsigned int> CPU Number to use, starting at 0
114-p, --prio=<priority> scheduler priority, HIGH, LOW or DEFAULT
115-g, --governor=<governor> cpufreq governor to test
116-n, --cycles=<int> load/sleep cycles to get an avarage value to compare
117-r, --rounds<int> load/sleep rounds
118-f, --file=<configfile> config file to use
119-o, --output=<dir> output dir, must exist
120-v, --verbose verbose output on/off
121
122Due to the high priority, the application may not be responsible for some time.
123After the benchmark, the logfile is saved in OUTPUTDIR/benchmark_TIMESTAMP.log
124
diff --git a/tools/power/cpupower/bench/benchmark.c b/tools/power/cpupower/bench/benchmark.c
new file mode 100644
index 000000000000..81b1c48607d9
--- /dev/null
+++ b/tools/power/cpupower/bench/benchmark.c
@@ -0,0 +1,194 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#include <stdio.h>
21#include <unistd.h>
22#include <math.h>
23
24#include "config.h"
25#include "system.h"
26#include "benchmark.h"
27
28/* Print out progress if we log into a file */
29#define show_progress(total_time, progress_time) \
30if (config->output != stdout) { \
31 fprintf(stdout, "Progress: %02lu %%\r", \
32 (progress_time * 100) / total_time); \
33 fflush(stdout); \
34}
35
36/**
37 * compute how many rounds of calculation we should do
38 * to get the given load time
39 *
40 * @param load aimed load time in µs
41 *
42 * @retval rounds of calculation
43 **/
44
45unsigned int calculate_timespace(long load, struct config *config)
46{
47 int i;
48 long long now, then;
49 unsigned int estimated = GAUGECOUNT;
50 unsigned int rounds = 0;
51 unsigned int timed = 0;
52
53 if (config->verbose)
54 printf("calibrating load of %lius, please wait...\n", load);
55
56 /* get the initial calculation time for a specific number of rounds */
57 now = get_time();
58 ROUNDS(estimated);
59 then = get_time();
60
61 timed = (unsigned int)(then - now);
62
63 /* approximation of the wanted load time by comparing with the
64 * initial calculation time */
65 for (i = 0; i < 4; i++) {
66 rounds = (unsigned int)(load * estimated / timed);
67 dprintf("calibrating with %u rounds\n", rounds);
68 now = get_time();
69 ROUNDS(rounds);
70 then = get_time();
71
72 timed = (unsigned int)(then - now);
73 estimated = rounds;
74 }
75 if (config->verbose)
76 printf("calibration done\n");
77
78 return estimated;
79}
80
81/**
82 * benchmark
83 * generates a specific sleep an load time with the performance
84 * governor and compares the used time for same calculations done
85 * with the configured powersave governor
86 *
87 * @param config config values for the benchmark
88 *
89 **/
90
91void start_benchmark(struct config *config)
92{
93 unsigned int _round, cycle;
94 long long now, then;
95 long sleep_time = 0, load_time = 0;
96 long performance_time = 0, powersave_time = 0;
97 unsigned int calculations;
98 unsigned long total_time = 0, progress_time = 0;
99
100 sleep_time = config->sleep;
101 load_time = config->load;
102
103 /* For the progress bar */
104 for (_round = 1; _round <= config->rounds; _round++)
105 total_time += _round * (config->sleep + config->load);
106 total_time *= 2; /* powersave and performance cycles */
107
108 for (_round = 0; _round < config->rounds; _round++) {
109 performance_time = 0LL;
110 powersave_time = 0LL;
111
112 show_progress(total_time, progress_time);
113
114 /* set the cpufreq governor to "performance" which disables
115 * P-State switching. */
116 if (set_cpufreq_governor("performance", config->cpu) != 0)
117 return;
118
119 /* calibrate the calculation time. the resulting calculation
120 * _rounds should produce a load which matches the configured
121 * load time */
122 calculations = calculate_timespace(load_time, config);
123
124 if (config->verbose)
125 printf("_round %i: doing %u cycles with %u calculations"
126 " for %lius\n", _round + 1, config->cycles,
127 calculations, load_time);
128
129 fprintf(config->output, "%u %li %li ",
130 _round, load_time, sleep_time);
131
132 if (config->verbose)
133 printf("avarage: %lius, rps:%li\n",
134 load_time / calculations,
135 1000000 * calculations / load_time);
136
137 /* do some sleep/load cycles with the performance governor */
138 for (cycle = 0; cycle < config->cycles; cycle++) {
139 now = get_time();
140 usleep(sleep_time);
141 ROUNDS(calculations);
142 then = get_time();
143 performance_time += then - now - sleep_time;
144 if (config->verbose)
145 printf("performance cycle took %lius, "
146 "sleep: %lius, "
147 "load: %lius, rounds: %u\n",
148 (long)(then - now), sleep_time,
149 load_time, calculations);
150 }
151 fprintf(config->output, "%li ",
152 performance_time / config->cycles);
153
154 progress_time += sleep_time + load_time;
155 show_progress(total_time, progress_time);
156
157 /* set the powersave governor which activates P-State switching
158 * again */
159 if (set_cpufreq_governor(config->governor, config->cpu) != 0)
160 return;
161
162 /* again, do some sleep/load cycles with the
163 * powersave governor */
164 for (cycle = 0; cycle < config->cycles; cycle++) {
165 now = get_time();
166 usleep(sleep_time);
167 ROUNDS(calculations);
168 then = get_time();
169 powersave_time += then - now - sleep_time;
170 if (config->verbose)
171 printf("powersave cycle took %lius, "
172 "sleep: %lius, "
173 "load: %lius, rounds: %u\n",
174 (long)(then - now), sleep_time,
175 load_time, calculations);
176 }
177
178 progress_time += sleep_time + load_time;
179
180 /* compare the avarage sleep/load cycles */
181 fprintf(config->output, "%li ",
182 powersave_time / config->cycles);
183 fprintf(config->output, "%.3f\n",
184 performance_time * 100.0 / powersave_time);
185 fflush(config->output);
186
187 if (config->verbose)
188 printf("performance is at %.2f%%\n",
189 performance_time * 100.0 / powersave_time);
190
191 sleep_time += config->sleep_step;
192 load_time += config->load_step;
193 }
194}
diff --git a/tools/power/cpupower/bench/benchmark.h b/tools/power/cpupower/bench/benchmark.h
new file mode 100644
index 000000000000..51d7f50ac2bb
--- /dev/null
+++ b/tools/power/cpupower/bench/benchmark.h
@@ -0,0 +1,29 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20/* load loop, this schould take about 1 to 2ms to complete */
21#define ROUNDS(x) {unsigned int rcnt; \
22 for (rcnt = 0; rcnt < x*1000; rcnt++) { \
23 (void)(((int)(pow(rcnt, rcnt) * \
24 sqrt(rcnt*7230970)) ^ 7230716) ^ \
25 (int)atan2(rcnt, rcnt)); \
26 } } \
27
28
29void start_benchmark(struct config *config);
diff --git a/tools/power/cpupower/bench/config.h b/tools/power/cpupower/bench/config.h
new file mode 100644
index 000000000000..ee6f258e5336
--- /dev/null
+++ b/tools/power/cpupower/bench/config.h
@@ -0,0 +1,36 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20/* initial loop count for the load calibration */
21#define GAUGECOUNT 1500
22
23/* default scheduling policy SCHED_OTHER */
24#define SCHEDULER SCHED_OTHER
25
26#define PRIORITY_DEFAULT 0
27#define PRIORITY_HIGH sched_get_priority_max(SCHEDULER)
28#define PRIORITY_LOW sched_get_priority_min(SCHEDULER)
29
30/* enable further debug messages */
31#ifdef DEBUG
32#define dprintf printf
33#else
34#define dprintf(...) do { } while (0)
35#endif
36
diff --git a/tools/power/cpupower/bench/cpufreq-bench_plot.sh b/tools/power/cpupower/bench/cpufreq-bench_plot.sh
new file mode 100644
index 000000000000..410021a12f40
--- /dev/null
+++ b/tools/power/cpupower/bench/cpufreq-bench_plot.sh
@@ -0,0 +1,104 @@
1#!/bin/bash
2
3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2, or (at your option)
6# any later version.
7
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16# 02110-1301, USA.
17
18# Author/Copyright(c): 2009, Thomas Renninger <trenn@suse.de>, Novell Inc.
19
20# Helper script to easily create nice plots of your cpufreq-bench results
21
22dir=`mktemp -d`
23output_file="cpufreq-bench.png"
24global_title="cpufreq-bench plot"
25picture_type="jpeg"
26file[0]=""
27
28function usage()
29{
30 echo "cpufreq-bench_plot.sh [OPTIONS] logfile [measure_title] [logfile [measure_title]] ...]"
31 echo
32 echo "Options"
33 echo " -o output_file"
34 echo " -t global_title"
35 echo " -p picture_type [jpeg|gif|png|postscript|...]"
36 exit 1
37}
38
39if [ $# -eq 0 ];then
40 echo "No benchmark results file provided"
41 echo
42 usage
43fi
44
45while getopts o:t:p: name ; do
46 case $name in
47 o)
48 output_file="$OPTARG".$picture_type
49 ;;
50 t)
51 global_title="$OPTARG"
52 ;;
53 p)
54 picture_type="$OPTARG"
55 ;;
56 ?)
57 usage
58 ;;
59 esac
60done
61shift $(($OPTIND -1))
62
63plots=0
64while [ "$1" ];do
65 if [ ! -f "$1" ];then
66 echo "File $1 does not exist"
67 usage
68 fi
69 file[$plots]="$1"
70 title[$plots]="$2"
71 # echo "File: ${file[$plots]} - ${title[plots]}"
72 shift;shift
73 plots=$((plots + 1))
74done
75
76echo "set terminal $picture_type" >> $dir/plot_script.gpl
77echo "set output \"$output_file\"" >> $dir/plot_script.gpl
78echo "set title \"$global_title\"" >> $dir/plot_script.gpl
79echo "set xlabel \"sleep/load time\"" >> $dir/plot_script.gpl
80echo "set ylabel \"Performance (%)\"" >> $dir/plot_script.gpl
81
82for((plot=0;plot<$plots;plot++));do
83
84 # Sanity check
85 ###### I am to dump to get this redirected to stderr/stdout in one awk call... #####
86 cat ${file[$plot]} |grep -v "^#" |awk '{if ($2 != $3) printf("Error in measure %d:Load time %s does not equal sleep time %s, plot will not be correct\n", $1, $2, $3); ERR=1}'
87 ###### I am to dump to get this redirected in one awk call... #####
88
89 # Parse out load time (which must be equal to sleep time for a plot), divide it by 1000
90 # to get ms and parse out the performance in percentage and write it to a temp file for plotting
91 cat ${file[$plot]} |grep -v "^#" |awk '{printf "%lu %.1f\n",$2/1000, $6}' >$dir/data_$plot
92
93 if [ $plot -eq 0 ];then
94 echo -n "plot " >> $dir/plot_script.gpl
95 fi
96 echo -n "\"$dir/data_$plot\" title \"${title[$plot]}\" with lines" >> $dir/plot_script.gpl
97 if [ $(($plot + 1)) -ne $plots ];then
98 echo -n ", " >> $dir/plot_script.gpl
99 fi
100done
101echo >> $dir/plot_script.gpl
102
103gnuplot $dir/plot_script.gpl
104rm -r $dir \ No newline at end of file
diff --git a/tools/power/cpupower/bench/cpufreq-bench_script.sh b/tools/power/cpupower/bench/cpufreq-bench_script.sh
new file mode 100644
index 000000000000..de20d2a06879
--- /dev/null
+++ b/tools/power/cpupower/bench/cpufreq-bench_script.sh
@@ -0,0 +1,101 @@
1#!/bin/bash
2
3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2, or (at your option)
6# any later version.
7
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16# 02110-1301, USA.
17
18# Author/Copyright(c): 2009, Thomas Renninger <trenn@suse.de>, Novell Inc.
19
20# Ondemand up_threshold and sampling rate test script for cpufreq-bench
21# mircobenchmark.
22# Modify the general variables at the top or extend or copy out parts
23# if you want to test other things
24#
25
26# Default with latest kernels is 95, before micro account patches
27# it was 80, cmp. with git commit 808009131046b62ac434dbc796
28UP_THRESHOLD="60 80 95"
29# Depending on the kernel and the HW sampling rate could be restricted
30# and cannot be set that low...
31# E.g. before git commit cef9615a853ebc4972084f7 one could only set
32# min sampling rate of 80000 if CONFIG_HZ=250
33SAMPLING_RATE="20000 80000"
34
35function measure()
36{
37 local -i up_threshold_set
38 local -i sampling_rate_set
39
40 for up_threshold in $UP_THRESHOLD;do
41 for sampling_rate in $SAMPLING_RATE;do
42 # Set values in sysfs
43 echo $up_threshold >/sys/devices/system/cpu/cpu0/cpufreq/ondemand/up_threshold
44 echo $sampling_rate >/sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate
45 up_threshold_set=$(cat /sys/devices/system/cpu/cpu0/cpufreq/ondemand/up_threshold)
46 sampling_rate_set=$(cat /sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate)
47
48 # Verify set values in sysfs
49 if [ ${up_threshold_set} -eq ${up_threshold} ];then
50 echo "up_threshold: $up_threshold, set in sysfs: ${up_threshold_set}"
51 else
52 echo "WARNING: Tried to set up_threshold: $up_threshold, set in sysfs: ${up_threshold_set}"
53 fi
54 if [ ${sampling_rate_set} -eq ${sampling_rate} ];then
55 echo "sampling_rate: $sampling_rate, set in sysfs: ${sampling_rate_set}"
56 else
57 echo "WARNING: Tried to set sampling_rate: $sampling_rate, set in sysfs: ${sampling_rate_set}"
58 fi
59
60 # Benchmark
61 cpufreq-bench -o /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate}
62 done
63 done
64}
65
66function create_plots()
67{
68 local command
69
70 for up_threshold in $UP_THRESHOLD;do
71 command="cpufreq-bench_plot.sh -o \"sampling_rate_${SAMPLING_RATE}_up_threshold_${up_threshold}\" -t \"Ondemand sampling_rate: ${SAMPLING_RATE} comparison - Up_threshold: $up_threshold %\""
72 for sampling_rate in $SAMPLING_RATE;do
73 command="${command} /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate}/* \"sampling_rate = $sampling_rate\""
74 done
75 echo $command
76 eval "$command"
77 echo
78 done
79
80 for sampling_rate in $SAMPLING_RATE;do
81 command="cpufreq-bench_plot.sh -o \"up_threshold_${UP_THRESHOLD}_sampling_rate_${sampling_rate}\" -t \"Ondemand up_threshold: ${UP_THRESHOLD} % comparison - sampling_rate: $sampling_rate\""
82 for up_threshold in $UP_THRESHOLD;do
83 command="${command} /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate}/* \"up_threshold = $up_threshold\""
84 done
85 echo $command
86 eval "$command"
87 echo
88 done
89
90 command="cpufreq-bench_plot.sh -o \"up_threshold_${UP_THRESHOLD}_sampling_rate_${SAMPLING_RATE}\" -t \"Ondemand up_threshold: ${UP_THRESHOLD} and sampling_rate ${SAMPLING_RATE} comparison\""
91 for sampling_rate in $SAMPLING_RATE;do
92 for up_threshold in $UP_THRESHOLD;do
93 command="${command} /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate}/* \"up_threshold = $up_threshold - sampling_rate = $sampling_rate\""
94 done
95 done
96 echo "$command"
97 eval "$command"
98}
99
100measure
101create_plots \ No newline at end of file
diff --git a/tools/power/cpupower/bench/example.cfg b/tools/power/cpupower/bench/example.cfg
new file mode 100644
index 000000000000..f91f64360688
--- /dev/null
+++ b/tools/power/cpupower/bench/example.cfg
@@ -0,0 +1,11 @@
1sleep = 50000
2load = 50000
3cpu = 0
4priority = LOW
5output = /var/log/cpufreq-bench
6sleep_step = 50000
7load_step = 50000
8cycles = 20
9rounds = 40
10verbose = 0
11governor = ondemand
diff --git a/tools/power/cpupower/bench/main.c b/tools/power/cpupower/bench/main.c
new file mode 100644
index 000000000000..24910313a521
--- /dev/null
+++ b/tools/power/cpupower/bench/main.c
@@ -0,0 +1,202 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <unistd.h>
24#include <getopt.h>
25#include <errno.h>
26
27#include "config.h"
28#include "system.h"
29#include "benchmark.h"
30
31static struct option long_options[] = {
32 {"output", 1, 0, 'o'},
33 {"sleep", 1, 0, 's'},
34 {"load", 1, 0, 'l'},
35 {"verbose", 0, 0, 'v'},
36 {"cpu", 1, 0, 'c'},
37 {"governor", 1, 0, 'g'},
38 {"prio", 1, 0, 'p'},
39 {"file", 1, 0, 'f'},
40 {"cycles", 1, 0, 'n'},
41 {"rounds", 1, 0, 'r'},
42 {"load-step", 1, 0, 'x'},
43 {"sleep-step", 1, 0, 'y'},
44 {"help", 0, 0, 'h'},
45 {0, 0, 0, 0}
46};
47
48/*******************************************************************
49 usage
50*******************************************************************/
51
52void usage()
53{
54 printf("usage: ./bench\n");
55 printf("Options:\n");
56 printf(" -l, --load=<long int>\t\tinitial load time in us\n");
57 printf(" -s, --sleep=<long int>\t\tinitial sleep time in us\n");
58 printf(" -x, --load-step=<long int>\ttime to be added to load time, in us\n");
59 printf(" -y, --sleep-step=<long int>\ttime to be added to sleep time, in us\n");
60 printf(" -c, --cpu=<cpu #>\t\t\tCPU Nr. to use, starting at 0\n");
61 printf(" -p, --prio=<priority>\t\t\tscheduler priority, HIGH, LOW or DEFAULT\n");
62 printf(" -g, --governor=<governor>\t\tcpufreq governor to test\n");
63 printf(" -n, --cycles=<int>\t\t\tload/sleep cycles\n");
64 printf(" -r, --rounds<int>\t\t\tload/sleep rounds\n");
65 printf(" -f, --file=<configfile>\t\tconfig file to use\n");
66 printf(" -o, --output=<dir>\t\t\toutput path. Filename will be OUTPUTPATH/benchmark_TIMESTAMP.log\n");
67 printf(" -v, --verbose\t\t\t\tverbose output on/off\n");
68 printf(" -h, --help\t\t\t\tPrint this help screen\n");
69 exit(1);
70}
71
72/*******************************************************************
73 main
74*******************************************************************/
75
76int main(int argc, char **argv)
77{
78 int c;
79 int option_index = 0;
80 struct config *config = NULL;
81
82 config = prepare_default_config();
83
84 if (config == NULL)
85 return EXIT_FAILURE;
86
87 while (1) {
88 c = getopt_long (argc, argv, "hg:o:s:l:vc:p:f:n:r:x:y:",
89 long_options, &option_index);
90 if (c == -1)
91 break;
92
93 switch (c) {
94 case 'o':
95 if (config->output != NULL)
96 fclose(config->output);
97
98 config->output = prepare_output(optarg);
99
100 if (config->output == NULL)
101 return EXIT_FAILURE;
102
103 dprintf("user output path -> %s\n", optarg);
104 break;
105 case 's':
106 sscanf(optarg, "%li", &config->sleep);
107 dprintf("user sleep time -> %s\n", optarg);
108 break;
109 case 'l':
110 sscanf(optarg, "%li", &config->load);
111 dprintf("user load time -> %s\n", optarg);
112 break;
113 case 'c':
114 sscanf(optarg, "%u", &config->cpu);
115 dprintf("user cpu -> %s\n", optarg);
116 break;
117 case 'g':
118 strncpy(config->governor, optarg, 14);
119 dprintf("user governor -> %s\n", optarg);
120 break;
121 case 'p':
122 if (string_to_prio(optarg) != SCHED_ERR) {
123 config->prio = string_to_prio(optarg);
124 dprintf("user prio -> %s\n", optarg);
125 } else {
126 if (config != NULL) {
127 if (config->output != NULL)
128 fclose(config->output);
129 free(config);
130 }
131 usage();
132 }
133 break;
134 case 'n':
135 sscanf(optarg, "%u", &config->cycles);
136 dprintf("user cycles -> %s\n", optarg);
137 break;
138 case 'r':
139 sscanf(optarg, "%u", &config->rounds);
140 dprintf("user rounds -> %s\n", optarg);
141 break;
142 case 'x':
143 sscanf(optarg, "%li", &config->load_step);
144 dprintf("user load_step -> %s\n", optarg);
145 break;
146 case 'y':
147 sscanf(optarg, "%li", &config->sleep_step);
148 dprintf("user sleep_step -> %s\n", optarg);
149 break;
150 case 'f':
151 if (prepare_config(optarg, config))
152 return EXIT_FAILURE;
153 break;
154 case 'v':
155 config->verbose = 1;
156 dprintf("verbose output enabled\n");
157 break;
158 case 'h':
159 case '?':
160 default:
161 if (config != NULL) {
162 if (config->output != NULL)
163 fclose(config->output);
164 free(config);
165 }
166 usage();
167 }
168 }
169
170 if (config->verbose) {
171 printf("starting benchmark with parameters:\n");
172 printf("config:\n\t"
173 "sleep=%li\n\t"
174 "load=%li\n\t"
175 "sleep_step=%li\n\t"
176 "load_step=%li\n\t"
177 "cpu=%u\n\t"
178 "cycles=%u\n\t"
179 "rounds=%u\n\t"
180 "governor=%s\n\n",
181 config->sleep,
182 config->load,
183 config->sleep_step,
184 config->load_step,
185 config->cpu,
186 config->cycles,
187 config->rounds,
188 config->governor);
189 }
190
191 prepare_user(config);
192 prepare_system(config);
193 start_benchmark(config);
194
195 if (config->output != stdout)
196 fclose(config->output);
197
198 free(config);
199
200 return EXIT_SUCCESS;
201}
202
diff --git a/tools/power/cpupower/bench/parse.c b/tools/power/cpupower/bench/parse.c
new file mode 100644
index 000000000000..543bba14ae2c
--- /dev/null
+++ b/tools/power/cpupower/bench/parse.c
@@ -0,0 +1,225 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <stdarg.h>
23#include <string.h>
24#include <time.h>
25#include <dirent.h>
26
27#include <sys/utsname.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30
31#include "parse.h"
32#include "config.h"
33
34/**
35 * converts priority string to priority
36 *
37 * @param str string that represents a scheduler priority
38 *
39 * @retval priority
40 * @retval SCHED_ERR when the priority doesn't exit
41 **/
42
43enum sched_prio string_to_prio(const char *str)
44{
45 if (strncasecmp("high", str, strlen(str)) == 0)
46 return SCHED_HIGH;
47 else if (strncasecmp("default", str, strlen(str)) == 0)
48 return SCHED_DEFAULT;
49 else if (strncasecmp("low", str, strlen(str)) == 0)
50 return SCHED_LOW;
51 else
52 return SCHED_ERR;
53}
54
55/**
56 * create and open logfile
57 *
58 * @param dir directory in which the logfile should be created
59 *
60 * @retval logfile on success
61 * @retval NULL when the file can't be created
62 **/
63
64FILE *prepare_output(const char *dirname)
65{
66 FILE *output = NULL;
67 int len;
68 char *filename;
69 struct utsname sysdata;
70 DIR *dir;
71
72 dir = opendir(dirname);
73 if (dir == NULL) {
74 if (mkdir(dirname, 0755)) {
75 perror("mkdir");
76 fprintf(stderr, "error: Cannot create dir %s\n",
77 dirname);
78 return NULL;
79 }
80 }
81
82 len = strlen(dirname) + 30;
83 filename = malloc(sizeof(char) * len);
84
85 if (uname(&sysdata) == 0) {
86 len += strlen(sysdata.nodename) + strlen(sysdata.release);
87 filename = realloc(filename, sizeof(char) * len);
88
89 if (filename == NULL) {
90 perror("realloc");
91 return NULL;
92 }
93
94 snprintf(filename, len - 1, "%s/benchmark_%s_%s_%li.log",
95 dirname, sysdata.nodename, sysdata.release, time(NULL));
96 } else {
97 snprintf(filename, len - 1, "%s/benchmark_%li.log",
98 dirname, time(NULL));
99 }
100
101 dprintf("logilename: %s\n", filename);
102
103 output = fopen(filename, "w+");
104 if (output == NULL) {
105 perror("fopen");
106 fprintf(stderr, "error: unable to open logfile\n");
107 }
108
109 fprintf(stdout, "Logfile: %s\n", filename);
110
111 free(filename);
112 fprintf(output, "#round load sleep performance powersave percentage\n");
113 return output;
114}
115
116/**
117 * returns the default config
118 *
119 * @retval default config on success
120 * @retval NULL when the output file can't be created
121 **/
122
123struct config *prepare_default_config()
124{
125 struct config *config = malloc(sizeof(struct config));
126
127 dprintf("loading defaults\n");
128
129 config->sleep = 500000;
130 config->load = 500000;
131 config->sleep_step = 500000;
132 config->load_step = 500000;
133 config->cycles = 5;
134 config->rounds = 50;
135 config->cpu = 0;
136 config->prio = SCHED_HIGH;
137 config->verbose = 0;
138 strncpy(config->governor, "ondemand", 8);
139
140 config->output = stdout;
141
142#ifdef DEFAULT_CONFIG_FILE
143 if (prepare_config(DEFAULT_CONFIG_FILE, config))
144 return NULL;
145#endif
146 return config;
147}
148
149/**
150 * parses config file and returns the config to the caller
151 *
152 * @param path config file name
153 *
154 * @retval 1 on error
155 * @retval 0 on success
156 **/
157
158int prepare_config(const char *path, struct config *config)
159{
160 size_t len = 0;
161 char *opt, *val, *line = NULL;
162 FILE *configfile = fopen(path, "r");
163
164 if (config == NULL) {
165 fprintf(stderr, "error: config is NULL\n");
166 return 1;
167 }
168
169 if (configfile == NULL) {
170 perror("fopen");
171 fprintf(stderr, "error: unable to read configfile\n");
172 free(config);
173 return 1;
174 }
175
176 while (getline(&line, &len, configfile) != -1) {
177 if (line[0] == '#' || line[0] == ' ')
178 continue;
179
180 sscanf(line, "%as = %as", &opt, &val);
181
182 dprintf("parsing: %s -> %s\n", opt, val);
183
184 if (strncmp("sleep", opt, strlen(opt)) == 0)
185 sscanf(val, "%li", &config->sleep);
186
187 else if (strncmp("load", opt, strlen(opt)) == 0)
188 sscanf(val, "%li", &config->load);
189
190 else if (strncmp("load_step", opt, strlen(opt)) == 0)
191 sscanf(val, "%li", &config->load_step);
192
193 else if (strncmp("sleep_step", opt, strlen(opt)) == 0)
194 sscanf(val, "%li", &config->sleep_step);
195
196 else if (strncmp("cycles", opt, strlen(opt)) == 0)
197 sscanf(val, "%u", &config->cycles);
198
199 else if (strncmp("rounds", opt, strlen(opt)) == 0)
200 sscanf(val, "%u", &config->rounds);
201
202 else if (strncmp("verbose", opt, strlen(opt)) == 0)
203 sscanf(val, "%u", &config->verbose);
204
205 else if (strncmp("output", opt, strlen(opt)) == 0)
206 config->output = prepare_output(val);
207
208 else if (strncmp("cpu", opt, strlen(opt)) == 0)
209 sscanf(val, "%u", &config->cpu);
210
211 else if (strncmp("governor", opt, 14) == 0)
212 strncpy(config->governor, val, 14);
213
214 else if (strncmp("priority", opt, strlen(opt)) == 0) {
215 if (string_to_prio(val) != SCHED_ERR)
216 config->prio = string_to_prio(val);
217 }
218 }
219
220 free(line);
221 free(opt);
222 free(val);
223
224 return 0;
225}
diff --git a/tools/power/cpupower/bench/parse.h b/tools/power/cpupower/bench/parse.h
new file mode 100644
index 000000000000..a8dc632d9eee
--- /dev/null
+++ b/tools/power/cpupower/bench/parse.h
@@ -0,0 +1,53 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20/* struct that holds the required config parameters */
21struct config
22{
23 long sleep; /* sleep time in µs */
24 long load; /* load time in µs */
25 long sleep_step; /* time value which changes the
26 * sleep time after every round in µs */
27 long load_step; /* time value which changes the
28 * load time after every round in µs */
29 unsigned int cycles; /* calculation cycles with the same sleep/load time */
30 unsigned int rounds; /* calculation rounds with iterated sleep/load time */
31 unsigned int cpu; /* cpu for which the affinity is set */
32 char governor[15]; /* cpufreq governor */
33 enum sched_prio /* possible scheduler priorities */
34 {
35 SCHED_ERR = -1,
36 SCHED_HIGH,
37 SCHED_DEFAULT,
38 SCHED_LOW
39 } prio;
40
41 unsigned int verbose; /* verbose output */
42 FILE *output; /* logfile */
43 char *output_filename; /* logfile name, must be freed at the end
44 if output != NULL and output != stdout*/
45};
46
47enum sched_prio string_to_prio(const char *str);
48
49FILE *prepare_output(const char *dir);
50
51int prepare_config(const char *path, struct config *config);
52struct config *prepare_default_config();
53
diff --git a/tools/power/cpupower/bench/system.c b/tools/power/cpupower/bench/system.c
new file mode 100644
index 000000000000..f01e3f4be84c
--- /dev/null
+++ b/tools/power/cpupower/bench/system.c
@@ -0,0 +1,191 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#include <stdio.h>
21#include <time.h>
22#include <sys/time.h>
23#include <sys/types.h>
24#include <unistd.h>
25
26#include <sched.h>
27
28#include <cpufreq.h>
29
30#include "config.h"
31#include "system.h"
32
33/**
34 * returns time since epoch in µs
35 *
36 * @retval time
37 **/
38
39long long int get_time()
40{
41 struct timeval now;
42
43 gettimeofday(&now, NULL);
44
45 return (long long int)(now.tv_sec * 1000000LL + now.tv_usec);
46}
47
48/**
49 * sets the cpufreq governor
50 *
51 * @param governor cpufreq governor name
52 * @param cpu cpu for which the governor should be set
53 *
54 * @retval 0 on success
55 * @retval -1 when failed
56 **/
57
58int set_cpufreq_governor(char *governor, unsigned int cpu)
59{
60
61 dprintf("set %s as cpufreq governor\n", governor);
62
63 if (cpufreq_cpu_exists(cpu) != 0) {
64 perror("cpufreq_cpu_exists");
65 fprintf(stderr, "error: cpu %u does not exist\n", cpu);
66 return -1;
67 }
68
69 if (cpufreq_modify_policy_governor(cpu, governor) != 0) {
70 perror("cpufreq_modify_policy_governor");
71 fprintf(stderr, "error: unable to set %s governor\n", governor);
72 return -1;
73 }
74
75 return 0;
76}
77
78/**
79 * sets cpu affinity for the process
80 *
81 * @param cpu cpu# to which the affinity should be set
82 *
83 * @retval 0 on success
84 * @retval -1 when setting the affinity failed
85 **/
86
87int set_cpu_affinity(unsigned int cpu)
88{
89 cpu_set_t cpuset;
90
91 CPU_ZERO(&cpuset);
92 CPU_SET(cpu, &cpuset);
93
94 dprintf("set affinity to cpu #%u\n", cpu);
95
96 if (sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset) < 0) {
97 perror("sched_setaffinity");
98 fprintf(stderr, "warning: unable to set cpu affinity\n");
99 return -1;
100 }
101
102 return 0;
103}
104
105/**
106 * sets the process priority parameter
107 *
108 * @param priority priority value
109 *
110 * @retval 0 on success
111 * @retval -1 when setting the priority failed
112 **/
113
114int set_process_priority(int priority)
115{
116 struct sched_param param;
117
118 dprintf("set scheduler priority to %i\n", priority);
119
120 param.sched_priority = priority;
121
122 if (sched_setscheduler(0, SCHEDULER, &param) < 0) {
123 perror("sched_setscheduler");
124 fprintf(stderr, "warning: unable to set scheduler priority\n");
125 return -1;
126 }
127
128 return 0;
129}
130
131/**
132 * notifies the user that the benchmark may run some time
133 *
134 * @param config benchmark config values
135 *
136 **/
137
138void prepare_user(const struct config *config)
139{
140 unsigned long sleep_time = 0;
141 unsigned long load_time = 0;
142 unsigned int round;
143
144 for (round = 0; round < config->rounds; round++) {
145 sleep_time += 2 * config->cycles *
146 (config->sleep + config->sleep_step * round);
147 load_time += 2 * config->cycles *
148 (config->load + config->load_step * round) +
149 (config->load + config->load_step * round * 4);
150 }
151
152 if (config->verbose || config->output != stdout)
153 printf("approx. test duration: %im\n",
154 (int)((sleep_time + load_time) / 60000000));
155}
156
157/**
158 * sets up the cpu affinity and scheduler priority
159 *
160 * @param config benchmark config values
161 *
162 **/
163
164void prepare_system(const struct config *config)
165{
166 if (config->verbose)
167 printf("set cpu affinity to cpu #%u\n", config->cpu);
168
169 set_cpu_affinity(config->cpu);
170
171 switch (config->prio) {
172 case SCHED_HIGH:
173 if (config->verbose)
174 printf("high priority condition requested\n");
175
176 set_process_priority(PRIORITY_HIGH);
177 break;
178 case SCHED_LOW:
179 if (config->verbose)
180 printf("low priority condition requested\n");
181
182 set_process_priority(PRIORITY_LOW);
183 break;
184 default:
185 if (config->verbose)
186 printf("default priority condition requested\n");
187
188 set_process_priority(PRIORITY_DEFAULT);
189 }
190}
191
diff --git a/tools/power/cpupower/bench/system.h b/tools/power/cpupower/bench/system.h
new file mode 100644
index 000000000000..3a8c858b78f0
--- /dev/null
+++ b/tools/power/cpupower/bench/system.h
@@ -0,0 +1,29 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#include "parse.h"
21
22long long get_time();
23
24int set_cpufreq_governor(char *governor, unsigned int cpu);
25int set_cpu_affinity(unsigned int cpu);
26int set_process_priority(int priority);
27
28void prepare_user(const struct config *config);
29void prepare_system(const struct config *config);
diff --git a/tools/power/cpupower/debug/i386/Makefile b/tools/power/cpupower/debug/i386/Makefile
new file mode 100644
index 000000000000..d08cc1ead9bc
--- /dev/null
+++ b/tools/power/cpupower/debug/i386/Makefile
@@ -0,0 +1,20 @@
1default: all
2
3centrino-decode: centrino-decode.c
4 $(CC) $(CFLAGS) -o centrino-decode centrino-decode.c
5
6dump_psb: dump_psb.c
7 $(CC) $(CFLAGS) -o dump_psb dump_psb.c
8
9intel_gsic: intel_gsic.c
10 $(CC) $(CFLAGS) -o intel_gsic -llrmi intel_gsic.c
11
12powernow-k8-decode: powernow-k8-decode.c
13 $(CC) $(CFLAGS) -o powernow-k8-decode powernow-k8-decode.c
14
15all: centrino-decode dump_psb intel_gsic powernow-k8-decode
16
17clean:
18 rm -rf centrino-decode dump_psb intel_gsic powernow-k8-decode
19
20.PHONY: all default clean
diff --git a/tools/power/cpupower/debug/i386/centrino-decode.c b/tools/power/cpupower/debug/i386/centrino-decode.c
new file mode 100644
index 000000000000..7ef24cce4926
--- /dev/null
+++ b/tools/power/cpupower/debug/i386/centrino-decode.c
@@ -0,0 +1,113 @@
1/*
2 * (C) 2003 - 2004 Dominik Brodowski <linux@dominikbrodowski.de>
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 *
6 * Based on code found in
7 * linux/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
8 * and originally developed by Jeremy Fitzhardinge.
9 *
10 * USAGE: simply run it to decode the current settings on CPU 0,
11 * or pass the CPU number as argument, or pass the MSR content
12 * as argument.
13 */
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <stdint.h>
18#include <unistd.h>
19#include <errno.h>
20#include <fcntl.h>
21
22#include <sys/types.h>
23#include <sys/stat.h>
24
25#define MCPU 32
26
27#define MSR_IA32_PERF_STATUS 0x198
28
29static int rdmsr(unsigned int cpu, unsigned int msr,
30 unsigned int *lo, unsigned int *hi)
31{
32 int fd;
33 char file[20];
34 unsigned long long val;
35 int retval = -1;
36
37 *lo = *hi = 0;
38
39 if (cpu > MCPU)
40 goto err1;
41
42 sprintf(file, "/dev/cpu/%d/msr", cpu);
43 fd = open(file, O_RDONLY);
44
45 if (fd < 0)
46 goto err1;
47
48 if (lseek(fd, msr, SEEK_CUR) == -1)
49 goto err2;
50
51 if (read(fd, &val, 8) != 8)
52 goto err2;
53
54 *lo = (uint32_t )(val & 0xffffffffull);
55 *hi = (uint32_t )(val>>32 & 0xffffffffull);
56
57 retval = 0;
58err2:
59 close(fd);
60err1:
61 return retval;
62}
63
64static void decode (unsigned int msr)
65{
66 unsigned int multiplier;
67 unsigned int mv;
68
69 multiplier = ((msr >> 8) & 0xFF);
70
71 mv = (((msr & 0xFF) * 16) + 700);
72
73 printf("0x%x means multiplier %d @ %d mV\n", msr, multiplier, mv);
74}
75
76static int decode_live(unsigned int cpu)
77{
78 unsigned int lo, hi;
79 int err;
80
81 err = rdmsr(cpu, MSR_IA32_PERF_STATUS, &lo, &hi);
82
83 if (err) {
84 printf("can't get MSR_IA32_PERF_STATUS for cpu %d\n", cpu);
85 printf("Possible trouble: you don't run an Enhanced SpeedStep capable cpu\n");
86 printf("or you are not root, or the msr driver is not present\n");
87 return 1;
88 }
89
90 decode(lo);
91
92 return 0;
93}
94
95int main (int argc, char **argv)
96{
97 unsigned int cpu, mode = 0;
98
99 if (argc < 2)
100 cpu = 0;
101 else {
102 cpu = strtoul(argv[1], NULL, 0);
103 if (cpu >= MCPU)
104 mode = 1;
105 }
106
107 if (mode)
108 decode(cpu);
109 else
110 decode_live(cpu);
111
112 return 0;
113}
diff --git a/tools/power/cpupower/debug/i386/dump_psb.c b/tools/power/cpupower/debug/i386/dump_psb.c
new file mode 100644
index 000000000000..8d6a47514253
--- /dev/null
+++ b/tools/power/cpupower/debug/i386/dump_psb.c
@@ -0,0 +1,196 @@
1/*
2 * dump_psb. (c) 2004, Dave Jones, Red Hat Inc.
3 * Licensed under the GPL v2.
4 */
5
6#include <fcntl.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <unistd.h>
11
12#define _GNU_SOURCE
13#include <getopt.h>
14
15#include <sys/mman.h>
16
17#define LEN (0x100000 - 0xc0000)
18#define OFFSET (0xc0000)
19
20#ifndef __packed
21#define __packed __attribute((packed))
22#endif
23
24static long relevant;
25
26static const int fid_to_mult[32] = {
27 110, 115, 120, 125, 50, 55, 60, 65,
28 70, 75, 80, 85, 90, 95, 100, 105,
29 30, 190, 40, 200, 130, 135, 140, 210,
30 150, 225, 160, 165, 170, 180, -1, -1,
31};
32
33static const int vid_to_voltage[32] = {
34 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
35 1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
36 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
37 1075, 1050, 1024, 1000, 975, 950, 925, 0,
38};
39
40struct psb_header {
41 char signature[10];
42 u_char version;
43 u_char flags;
44 u_short settlingtime;
45 u_char res1;
46 u_char numpst;
47} __packed;
48
49struct pst_header {
50 u_int32_t cpuid;
51 u_char fsb;
52 u_char maxfid;
53 u_char startvid;
54 u_char numpstates;
55} __packed;
56
57static u_int fsb;
58static u_int sgtc;
59
60static int
61decode_pst(char *p, int npstates)
62{
63 int i;
64 int freq, fid, vid;
65
66 for (i = 0; i < npstates; ++i) {
67 fid = *p++;
68 vid = *p++;
69 freq = 100 * fid_to_mult[fid] * fsb;
70
71 printf(" %2d %8dkHz FID %02x (%2d.%01d) VID %02x (%4dmV)\n",
72 i,
73 freq,
74 fid, fid_to_mult[fid]/10, fid_to_mult[fid]%10,
75 vid, vid_to_voltage[vid]);
76 }
77
78 return 0;
79}
80
81static
82void decode_psb(char *p, int numpst)
83{
84 int i;
85 struct psb_header *psb;
86 struct pst_header *pst;
87
88 psb = (struct psb_header*) p;
89
90 if (psb->version != 0x12)
91 return;
92
93 printf("PSB version: %hhx flags: %hhx settling time %hhuus res1 %hhx num pst %hhu\n",
94 psb->version,
95 psb->flags,
96 psb->settlingtime,
97 psb->res1,
98 psb->numpst);
99 sgtc = psb->settlingtime * 100;
100
101 if (sgtc < 10000)
102 sgtc = 10000;
103
104 p = ((char *) psb) + sizeof(struct psb_header);
105
106 if (numpst < 0)
107 numpst = psb->numpst;
108 else
109 printf("Overriding number of pst :%d\n", numpst);
110
111 for (i = 0; i < numpst; i++) {
112 pst = (struct pst_header*) p;
113
114 if (relevant != 0) {
115 if (relevant!= pst->cpuid)
116 goto next_one;
117 }
118
119 printf(" PST %d cpuid %.3x fsb %hhu mfid %hhx svid %hhx numberstates %hhu\n",
120 i+1,
121 pst->cpuid,
122 pst->fsb,
123 pst->maxfid,
124 pst->startvid,
125 pst->numpstates);
126
127 fsb = pst->fsb;
128 decode_pst(p + sizeof(struct pst_header), pst->numpstates);
129
130next_one:
131 p += sizeof(struct pst_header) + 2*pst->numpstates;
132 }
133
134}
135
136static struct option info_opts[] = {
137 {.name = "numpst", .has_arg=no_argument, .flag=NULL, .val='n'},
138};
139
140void print_help(void)
141{
142 printf ("Usage: dump_psb [options]\n");
143 printf ("Options:\n");
144 printf (" -n, --numpst Set number of PST tables to scan\n");
145 printf (" -r, --relevant Only display PSTs relevant to cpuid N\n");
146}
147
148int
149main(int argc, char *argv[])
150{
151 int fd;
152 int numpst=-1;
153 int ret=0, cont=1;
154 char *mem = NULL;
155 char *p;
156
157 do {
158 ret = getopt_long(argc, argv, "hr:n:", info_opts, NULL);
159 switch (ret){
160 case '?':
161 case 'h':
162 print_help();
163 cont = 0;
164 break;
165 case 'r':
166 relevant = strtol(optarg, NULL, 16);
167 break;
168 case 'n':
169 numpst = strtol(optarg, NULL, 10);
170 break;
171 case -1:
172 cont = 0;
173 break;
174 }
175
176 } while(cont);
177
178 fd = open("/dev/mem", O_RDONLY);
179 if (fd < 0) {
180 printf ("Couldn't open /dev/mem. Are you root?\n");
181 exit(1);
182 }
183
184 mem = mmap(mem, 0x100000 - 0xc0000, PROT_READ, MAP_SHARED, fd, 0xc0000);
185 close(fd);
186
187 for (p = mem; p - mem < LEN; p+=16) {
188 if (memcmp(p, "AMDK7PNOW!", 10) == 0) {
189 decode_psb(p, numpst);
190 break;
191 }
192 }
193
194 munmap(mem, LEN);
195 return 0;
196}
diff --git a/tools/power/cpupower/debug/i386/intel_gsic.c b/tools/power/cpupower/debug/i386/intel_gsic.c
new file mode 100644
index 000000000000..53f5293c9c9a
--- /dev/null
+++ b/tools/power/cpupower/debug/i386/intel_gsic.c
@@ -0,0 +1,78 @@
1/*
2 * (C) 2003 Bruno Ducrot
3 * (C) 2004 Dominik Brodowski <linux@dominikbrodowski.de>
4 *
5 * Licensed under the terms of the GNU GPL License version 2.
6 *
7 * Based on code found in
8 * linux/include/asm-i386/ist.h and linux/arch/i386/kernel/setup.c
9 * and originally developed by Andy Grover <andrew.grover@intel.com>
10 */
11
12#include <stdio.h>
13#include <string.h>
14#include <lrmi.h>
15
16int main (void)
17{
18 struct LRMI_regs r;
19 int retval;
20
21 if (!LRMI_init())
22 return 0;
23
24 memset(&r, 0, sizeof(r));
25
26 r.eax = 0x0000E980;
27 r.edx = 0x47534943;
28
29 retval = LRMI_int(0x15, &r);
30
31 if (!retval) {
32 printf("Failed!\n");
33 return 0;
34 }
35 if (r.eax == 0x47534943) {
36 printf("BIOS supports GSIC call:\n");
37 printf("\tsignature: %c%c%c%c\n",
38 (r.eax >> 24) & 0xff,
39 (r.eax >> 16) & 0xff,
40 (r.eax >> 8) & 0xff,
41 (r.eax) & 0xff);
42 printf("\tcommand port = 0x%.4x\n",
43 r.ebx & 0xffff);
44 printf("\tcommand = 0x%.4x\n",
45 (r.ebx >> 16) & 0xffff);
46 printf("\tevent port = 0x%.8x\n", r.ecx);
47 printf("\tflags = 0x%.8x\n", r.edx);
48 if (((r.ebx >> 16) & 0xffff) != 0x82) {
49 printf("non-default command value. If speedstep-smi "
50 "doesn't work out of the box,\nyou may want to "
51 "try out the default value by passing "
52 "smi_cmd=0x82 to the module\n ON YOUR OWN "
53 "RISK.\n");
54 }
55 if ((r.ebx & 0xffff) != 0xb2) {
56 printf("non-default command port. If speedstep-smi "
57 "doesn't work out of the box,\nyou may want to "
58 "try out the default value by passing "
59 "smi_port=0x82 to the module\n ON YOUR OWN "
60 "RISK.\n");
61 }
62 } else {
63 printf("BIOS DOES NOT support GSIC call. Dumping registers anyway:\n");
64 printf("eax = 0x%.8x\n", r.eax);
65 printf("ebx = 0x%.8x\n", r.ebx);
66 printf("ecx = 0x%.8x\n", r.ecx);
67 printf("edx = 0x%.8x\n", r.edx);
68 printf("Note also that some BIOS do not support the initial "
69 "GSIC call, but the newer\nspeeedstep-smi driver may "
70 "work.\nFor this, you need to pass some arguments to "
71 "the speedstep-smi driver:\n");
72 printf("\tsmi_cmd=0x?? smi_port=0x?? smi_sig=1\n");
73 printf("\nUnfortunately, you have to know what exactly are "
74 "smi_cmd and smi_port, and this\nis system "
75 "dependant.\n");
76 }
77 return 1;
78}
diff --git a/tools/power/cpupower/debug/i386/powernow-k8-decode.c b/tools/power/cpupower/debug/i386/powernow-k8-decode.c
new file mode 100644
index 000000000000..638a6b3bfd97
--- /dev/null
+++ b/tools/power/cpupower/debug/i386/powernow-k8-decode.c
@@ -0,0 +1,96 @@
1/*
2 * (C) 2004 Bruno Ducrot <ducrot@poupinou.org>
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 *
6 * Based on code found in
7 * linux/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
8 * and originally developed by Paul Devriendt
9 */
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <stdint.h>
14#include <unistd.h>
15#include <errno.h>
16#include <fcntl.h>
17
18#include <sys/types.h>
19#include <sys/stat.h>
20
21#define MCPU 32
22
23#define MSR_FIDVID_STATUS 0xc0010042
24
25#define MSR_S_HI_CURRENT_VID 0x0000001f
26#define MSR_S_LO_CURRENT_FID 0x0000003f
27
28static int get_fidvid(uint32_t cpu, uint32_t *fid, uint32_t *vid)
29{
30 int err = 1;
31 uint64_t msr = 0;
32 int fd;
33 char file[20];
34
35 if (cpu > MCPU)
36 goto out;
37
38 sprintf(file, "/dev/cpu/%d/msr", cpu);
39
40 fd = open(file, O_RDONLY);
41 if (fd < 0)
42 goto out;
43 lseek(fd, MSR_FIDVID_STATUS, SEEK_CUR);
44 if (read(fd, &msr, 8) != 8)
45 goto err1;
46
47 *fid = ((uint32_t )(msr & 0xffffffffull)) & MSR_S_LO_CURRENT_FID;
48 *vid = ((uint32_t )(msr>>32 & 0xffffffffull)) & MSR_S_HI_CURRENT_VID;
49 err = 0;
50err1:
51 close(fd);
52out:
53 return err;
54}
55
56
57/* Return a frequency in MHz, given an input fid */
58static uint32_t find_freq_from_fid(uint32_t fid)
59{
60 return 800 + (fid * 100);
61}
62
63/* Return a voltage in miliVolts, given an input vid */
64static uint32_t find_millivolts_from_vid(uint32_t vid)
65{
66 return 1550-vid*25;
67}
68
69int main (int argc, char *argv[])
70{
71 int err;
72 int cpu;
73 uint32_t fid, vid;
74
75 if (argc < 2)
76 cpu = 0;
77 else
78 cpu = strtoul(argv[1], NULL, 0);
79
80 err = get_fidvid(cpu, &fid, &vid);
81
82 if (err) {
83 printf("can't get fid, vid from MSR\n");
84 printf("Possible trouble: you don't run a powernow-k8 capable cpu\n");
85 printf("or you are not root, or the msr driver is not present\n");
86 exit(1);
87 }
88
89
90 printf("cpu %d currently at %d MHz and %d mV\n",
91 cpu,
92 find_freq_from_fid(fid),
93 find_millivolts_from_vid(vid));
94
95 return 0;
96}
diff --git a/tools/power/cpupower/debug/kernel/Makefile b/tools/power/cpupower/debug/kernel/Makefile
new file mode 100644
index 000000000000..96b146fe6f8d
--- /dev/null
+++ b/tools/power/cpupower/debug/kernel/Makefile
@@ -0,0 +1,23 @@
1obj-m :=
2
3KDIR := /lib/modules/$(shell uname -r)/build
4PWD := $(shell pwd)
5KMISC := /lib/modules/$(shell uname -r)/cpufrequtils/
6
7ifeq ("$(CONFIG_X86_TSC)", "y")
8 obj-m += cpufreq-test_tsc.o
9endif
10
11default:
12 $(MAKE) -C $(KDIR) M=$(PWD)
13
14clean:
15 - rm -rf *.o *.ko .tmp-versions .*.cmd .*.mod.* *.mod.c
16 - rm -rf .tmp_versions* Module.symvers modules.order
17
18install: default
19 install -d $(KMISC)
20 install -m 644 -c *.ko $(KMISC)
21 /sbin/depmod -a
22
23all: default
diff --git a/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c b/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c
new file mode 100644
index 000000000000..66cace601e57
--- /dev/null
+++ b/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c
@@ -0,0 +1,113 @@
1/*
2 * test module to check whether the TSC-based delay routine continues
3 * to work properly after cpufreq transitions. Needs ACPI to work
4 * properly.
5 *
6 * Based partly on the Power Management Timer (PMTMR) code to be found
7 * in arch/i386/kernel/timers/timer_pm.c on recent 2.6. kernels, especially
8 * code written by John Stultz. The read_pmtmr function was copied verbatim
9 * from that file.
10 *
11 * (C) 2004 Dominik Brodowski
12 *
13 * To use:
14 * 1.) pass clock=tsc to the kernel on your bootloader
15 * 2.) modprobe this module (it'll fail)
16 * 3.) change CPU frequency
17 * 4.) modprobe this module again
18 * 5.) if the third value, "diff_pmtmr", changes between 2. and 4., the
19 * TSC-based delay routine on the Linux kernel does not correctly
20 * handle the cpufreq transition. Please report this to
21 * cpufreq@vger.kernel.org
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28
29#include <asm/io.h>
30
31#include <acpi/acpi_bus.h>
32#include <acpi/acpi_drivers.h>
33
34static int pm_tmr_ioport = 0;
35
36/*helper function to safely read acpi pm timesource*/
37static u32 read_pmtmr(void)
38{
39 u32 v1=0,v2=0,v3=0;
40 /* It has been reported that because of various broken
41 * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM time
42 * source is not latched, so you must read it multiple
43 * times to insure a safe value is read.
44 */
45 do {
46 v1 = inl(pm_tmr_ioport);
47 v2 = inl(pm_tmr_ioport);
48 v3 = inl(pm_tmr_ioport);
49 } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
50 || (v3 > v1 && v3 < v2));
51
52 /* mask the output to 24 bits */
53 return (v2 & 0xFFFFFF);
54}
55
56static int __init cpufreq_test_tsc(void)
57{
58 u32 now, then, diff;
59 u64 now_tsc, then_tsc, diff_tsc;
60 int i;
61
62 /* the following code snipped is copied from arch/x86/kernel/acpi/boot.c
63 of Linux v2.6.25. */
64
65 /* detect the location of the ACPI PM Timer */
66 if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) {
67 /* FADT rev. 2 */
68 if (acpi_gbl_FADT.xpm_timer_block.space_id !=
69 ACPI_ADR_SPACE_SYSTEM_IO)
70 return 0;
71
72 pm_tmr_ioport = acpi_gbl_FADT.xpm_timer_block.address;
73 /*
74 * "X" fields are optional extensions to the original V1.0
75 * fields, so we must selectively expand V1.0 fields if the
76 * corresponding X field is zero.
77 */
78 if (!pm_tmr_ioport)
79 pm_tmr_ioport = acpi_gbl_FADT.pm_timer_block;
80 } else {
81 /* FADT rev. 1 */
82 pm_tmr_ioport = acpi_gbl_FADT.pm_timer_block;
83 }
84
85 printk(KERN_DEBUG "start--> \n");
86 then = read_pmtmr();
87 rdtscll(then_tsc);
88 for (i=0;i<20;i++) {
89 mdelay(100);
90 now = read_pmtmr();
91 rdtscll(now_tsc);
92 diff = (now - then) & 0xFFFFFF;
93 diff_tsc = now_tsc - then_tsc;
94 printk(KERN_DEBUG "t1: %08u t2: %08u diff_pmtmr: %08u diff_tsc: %016llu\n", then, now, diff, diff_tsc);
95 then = now;
96 then_tsc = now_tsc;
97 }
98 printk(KERN_DEBUG "<-- end \n");
99 return -ENODEV;
100}
101
102static void __exit cpufreq_none(void)
103{
104 return;
105}
106
107module_init(cpufreq_test_tsc)
108module_exit(cpufreq_none)
109
110
111MODULE_AUTHOR("Dominik Brodowski");
112MODULE_DESCRIPTION("Verify the TSC cpufreq notifier working correctly -- needs ACPI-enabled system");
113MODULE_LICENSE ("GPL");
diff --git a/tools/power/cpupower/debug/x86_64/Makefile b/tools/power/cpupower/debug/x86_64/Makefile
new file mode 100644
index 000000000000..dbf13998462a
--- /dev/null
+++ b/tools/power/cpupower/debug/x86_64/Makefile
@@ -0,0 +1,14 @@
1default: all
2
3centrino-decode: centrino-decode.c
4 $(CC) $(CFLAGS) -o centrino-decode centrino-decode.c
5
6powernow-k8-decode: powernow-k8-decode.c
7 $(CC) $(CFLAGS) -o powernow-k8-decode powernow-k8-decode.c
8
9all: centrino-decode powernow-k8-decode
10
11clean:
12 rm -rf centrino-decode powernow-k8-decode
13
14.PHONY: all default clean
diff --git a/tools/power/cpupower/debug/x86_64/centrino-decode.c b/tools/power/cpupower/debug/x86_64/centrino-decode.c
new file mode 120000
index 000000000000..26fb3f1d8fc7
--- /dev/null
+++ b/tools/power/cpupower/debug/x86_64/centrino-decode.c
@@ -0,0 +1 @@
../i386/centrino-decode.c \ No newline at end of file
diff --git a/tools/power/cpupower/debug/x86_64/powernow-k8-decode.c b/tools/power/cpupower/debug/x86_64/powernow-k8-decode.c
new file mode 120000
index 000000000000..eb30c79cf9df
--- /dev/null
+++ b/tools/power/cpupower/debug/x86_64/powernow-k8-decode.c
@@ -0,0 +1 @@
../i386/powernow-k8-decode.c \ No newline at end of file
diff --git a/tools/power/cpupower/lib/cpufreq.c b/tools/power/cpupower/lib/cpufreq.c
new file mode 100644
index 000000000000..d961101d1cea
--- /dev/null
+++ b/tools/power/cpupower/lib/cpufreq.c
@@ -0,0 +1,208 @@
1/*
2 * (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.de>
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 */
6
7
8#include <stdio.h>
9#include <errno.h>
10#include <stdlib.h>
11#include <string.h>
12
13#include "cpufreq.h"
14#include "sysfs.h"
15
16int cpufreq_cpu_exists(unsigned int cpu)
17{
18 return sysfs_cpu_exists(cpu);
19}
20
21unsigned long cpufreq_get_freq_kernel(unsigned int cpu)
22{
23 return sysfs_get_freq_kernel(cpu);
24}
25
26unsigned long cpufreq_get_freq_hardware(unsigned int cpu)
27{
28 return sysfs_get_freq_hardware(cpu);
29}
30
31unsigned long cpufreq_get_transition_latency(unsigned int cpu)
32{
33 return sysfs_get_freq_transition_latency(cpu);
34}
35
36int cpufreq_get_hardware_limits(unsigned int cpu,
37 unsigned long *min,
38 unsigned long *max)
39{
40 if ((!min) || (!max))
41 return -EINVAL;
42 return sysfs_get_freq_hardware_limits(cpu, min, max);
43}
44
45char *cpufreq_get_driver(unsigned int cpu)
46{
47 return sysfs_get_freq_driver(cpu);
48}
49
50void cpufreq_put_driver(char *ptr)
51{
52 if (!ptr)
53 return;
54 free(ptr);
55}
56
57struct cpufreq_policy *cpufreq_get_policy(unsigned int cpu)
58{
59 return sysfs_get_freq_policy(cpu);
60}
61
62void cpufreq_put_policy(struct cpufreq_policy *policy)
63{
64 if ((!policy) || (!policy->governor))
65 return;
66
67 free(policy->governor);
68 policy->governor = NULL;
69 free(policy);
70}
71
72struct cpufreq_available_governors *cpufreq_get_available_governors(unsigned
73 int cpu)
74{
75 return sysfs_get_freq_available_governors(cpu);
76}
77
78void cpufreq_put_available_governors(struct cpufreq_available_governors *any)
79{
80 struct cpufreq_available_governors *tmp, *next;
81
82 if (!any)
83 return;
84
85 tmp = any->first;
86 while (tmp) {
87 next = tmp->next;
88 if (tmp->governor)
89 free(tmp->governor);
90 free(tmp);
91 tmp = next;
92 }
93}
94
95
96struct cpufreq_available_frequencies
97*cpufreq_get_available_frequencies(unsigned int cpu)
98{
99 return sysfs_get_available_frequencies(cpu);
100}
101
102void cpufreq_put_available_frequencies(struct cpufreq_available_frequencies
103 *any) {
104 struct cpufreq_available_frequencies *tmp, *next;
105
106 if (!any)
107 return;
108
109 tmp = any->first;
110 while (tmp) {
111 next = tmp->next;
112 free(tmp);
113 tmp = next;
114 }
115}
116
117
118struct cpufreq_affected_cpus *cpufreq_get_affected_cpus(unsigned int cpu)
119{
120 return sysfs_get_freq_affected_cpus(cpu);
121}
122
123void cpufreq_put_affected_cpus(struct cpufreq_affected_cpus *any)
124{
125 struct cpufreq_affected_cpus *tmp, *next;
126
127 if (!any)
128 return;
129
130 tmp = any->first;
131 while (tmp) {
132 next = tmp->next;
133 free(tmp);
134 tmp = next;
135 }
136}
137
138
139struct cpufreq_affected_cpus *cpufreq_get_related_cpus(unsigned int cpu)
140{
141 return sysfs_get_freq_related_cpus(cpu);
142}
143
144void cpufreq_put_related_cpus(struct cpufreq_affected_cpus *any)
145{
146 cpufreq_put_affected_cpus(any);
147}
148
149
150int cpufreq_set_policy(unsigned int cpu, struct cpufreq_policy *policy)
151{
152 if (!policy || !(policy->governor))
153 return -EINVAL;
154
155 return sysfs_set_freq_policy(cpu, policy);
156}
157
158
159int cpufreq_modify_policy_min(unsigned int cpu, unsigned long min_freq)
160{
161 return sysfs_modify_freq_policy_min(cpu, min_freq);
162}
163
164
165int cpufreq_modify_policy_max(unsigned int cpu, unsigned long max_freq)
166{
167 return sysfs_modify_freq_policy_max(cpu, max_freq);
168}
169
170
171int cpufreq_modify_policy_governor(unsigned int cpu, char *governor)
172{
173 if ((!governor) || (strlen(governor) > 19))
174 return -EINVAL;
175
176 return sysfs_modify_freq_policy_governor(cpu, governor);
177}
178
179int cpufreq_set_frequency(unsigned int cpu, unsigned long target_frequency)
180{
181 return sysfs_set_frequency(cpu, target_frequency);
182}
183
184struct cpufreq_stats *cpufreq_get_stats(unsigned int cpu,
185 unsigned long long *total_time)
186{
187 return sysfs_get_freq_stats(cpu, total_time);
188}
189
190void cpufreq_put_stats(struct cpufreq_stats *any)
191{
192 struct cpufreq_stats *tmp, *next;
193
194 if (!any)
195 return;
196
197 tmp = any->first;
198 while (tmp) {
199 next = tmp->next;
200 free(tmp);
201 tmp = next;
202 }
203}
204
205unsigned long cpufreq_get_transitions(unsigned int cpu)
206{
207 return sysfs_get_freq_transitions(cpu);
208}
diff --git a/tools/power/cpupower/lib/cpufreq.h b/tools/power/cpupower/lib/cpufreq.h
new file mode 100644
index 000000000000..3aae8e7a0839
--- /dev/null
+++ b/tools/power/cpupower/lib/cpufreq.h
@@ -0,0 +1,223 @@
1/*
2 * cpufreq.h - definitions for libcpufreq
3 *
4 * Copyright (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#ifndef _CPUFREQ_H
21#define _CPUFREQ_H 1
22
23struct cpufreq_policy {
24 unsigned long min;
25 unsigned long max;
26 char *governor;
27};
28
29struct cpufreq_available_governors {
30 char *governor;
31 struct cpufreq_available_governors *next;
32 struct cpufreq_available_governors *first;
33};
34
35struct cpufreq_available_frequencies {
36 unsigned long frequency;
37 struct cpufreq_available_frequencies *next;
38 struct cpufreq_available_frequencies *first;
39};
40
41
42struct cpufreq_affected_cpus {
43 unsigned int cpu;
44 struct cpufreq_affected_cpus *next;
45 struct cpufreq_affected_cpus *first;
46};
47
48struct cpufreq_stats {
49 unsigned long frequency;
50 unsigned long long time_in_state;
51 struct cpufreq_stats *next;
52 struct cpufreq_stats *first;
53};
54
55
56
57#ifdef __cplusplus
58extern "C" {
59#endif
60
61/*
62 * returns 0 if the specified CPU is present (it doesn't say
63 * whether it is online!), and an error value if not.
64 */
65
66extern int cpufreq_cpu_exists(unsigned int cpu);
67
68/* determine current CPU frequency
69 * - _kernel variant means kernel's opinion of CPU frequency
70 * - _hardware variant means actual hardware CPU frequency,
71 * which is only available to root.
72 *
73 * returns 0 on failure, else frequency in kHz.
74 */
75
76extern unsigned long cpufreq_get_freq_kernel(unsigned int cpu);
77
78extern unsigned long cpufreq_get_freq_hardware(unsigned int cpu);
79
80#define cpufreq_get(cpu) cpufreq_get_freq_kernel(cpu);
81
82
83/* determine CPU transition latency
84 *
85 * returns 0 on failure, else transition latency in 10^(-9) s = nanoseconds
86 */
87extern unsigned long cpufreq_get_transition_latency(unsigned int cpu);
88
89
90/* determine hardware CPU frequency limits
91 *
92 * These may be limited further by thermal, energy or other
93 * considerations by cpufreq policy notifiers in the kernel.
94 */
95
96extern int cpufreq_get_hardware_limits(unsigned int cpu,
97 unsigned long *min,
98 unsigned long *max);
99
100
101/* determine CPUfreq driver used
102 *
103 * Remember to call cpufreq_put_driver when no longer needed
104 * to avoid memory leakage, please.
105 */
106
107extern char *cpufreq_get_driver(unsigned int cpu);
108
109extern void cpufreq_put_driver(char *ptr);
110
111
112/* determine CPUfreq policy currently used
113 *
114 * Remember to call cpufreq_put_policy when no longer needed
115 * to avoid memory leakage, please.
116 */
117
118
119extern struct cpufreq_policy *cpufreq_get_policy(unsigned int cpu);
120
121extern void cpufreq_put_policy(struct cpufreq_policy *policy);
122
123
124/* determine CPUfreq governors currently available
125 *
126 * may be modified by modprobe'ing or rmmod'ing other governors. Please
127 * free allocated memory by calling cpufreq_put_available_governors
128 * after use.
129 */
130
131
132extern struct cpufreq_available_governors
133*cpufreq_get_available_governors(unsigned int cpu);
134
135extern void cpufreq_put_available_governors(
136 struct cpufreq_available_governors *first);
137
138
139/* determine CPU frequency states available
140 *
141 * Only present on _some_ ->target() cpufreq drivers. For information purposes
142 * only. Please free allocated memory by calling
143 * cpufreq_put_available_frequencies after use.
144 */
145
146extern struct cpufreq_available_frequencies
147*cpufreq_get_available_frequencies(unsigned int cpu);
148
149extern void cpufreq_put_available_frequencies(
150 struct cpufreq_available_frequencies *first);
151
152
153/* determine affected CPUs
154 *
155 * Remember to call cpufreq_put_affected_cpus when no longer needed
156 * to avoid memory leakage, please.
157 */
158
159extern struct cpufreq_affected_cpus *cpufreq_get_affected_cpus(unsigned
160 int cpu);
161
162extern void cpufreq_put_affected_cpus(struct cpufreq_affected_cpus *first);
163
164
165/* determine related CPUs
166 *
167 * Remember to call cpufreq_put_related_cpus when no longer needed
168 * to avoid memory leakage, please.
169 */
170
171extern struct cpufreq_affected_cpus *cpufreq_get_related_cpus(unsigned
172 int cpu);
173
174extern void cpufreq_put_related_cpus(struct cpufreq_affected_cpus *first);
175
176
177/* determine stats for cpufreq subsystem
178 *
179 * This is not available in all kernel versions or configurations.
180 */
181
182extern struct cpufreq_stats *cpufreq_get_stats(unsigned int cpu,
183 unsigned long long *total_time);
184
185extern void cpufreq_put_stats(struct cpufreq_stats *stats);
186
187extern unsigned long cpufreq_get_transitions(unsigned int cpu);
188
189
190/* set new cpufreq policy
191 *
192 * Tries to set the passed policy as new policy as close as possible,
193 * but results may differ depending e.g. on governors being available.
194 */
195
196extern int cpufreq_set_policy(unsigned int cpu, struct cpufreq_policy *policy);
197
198
199/* modify a policy by only changing min/max freq or governor
200 *
201 * Does not check whether result is what was intended.
202 */
203
204extern int cpufreq_modify_policy_min(unsigned int cpu, unsigned long min_freq);
205extern int cpufreq_modify_policy_max(unsigned int cpu, unsigned long max_freq);
206extern int cpufreq_modify_policy_governor(unsigned int cpu, char *governor);
207
208
209/* set a specific frequency
210 *
211 * Does only work if userspace governor can be used and no external
212 * interference (other calls to this function or to set/modify_policy)
213 * occurs. Also does not work on ->range() cpufreq drivers.
214 */
215
216extern int cpufreq_set_frequency(unsigned int cpu,
217 unsigned long target_frequency);
218
219#ifdef __cplusplus
220}
221#endif
222
223#endif /* _CPUFREQ_H */
diff --git a/tools/power/cpupower/lib/sysfs.c b/tools/power/cpupower/lib/sysfs.c
new file mode 100644
index 000000000000..870713a75a81
--- /dev/null
+++ b/tools/power/cpupower/lib/sysfs.c
@@ -0,0 +1,672 @@
1/*
2 * (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.de>
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 */
6
7#include <stdio.h>
8#include <errno.h>
9#include <stdlib.h>
10#include <string.h>
11#include <limits.h>
12#include <sys/types.h>
13#include <sys/stat.h>
14#include <fcntl.h>
15#include <unistd.h>
16
17#include "cpufreq.h"
18
19#define PATH_TO_CPU "/sys/devices/system/cpu/"
20#define MAX_LINE_LEN 4096
21#define SYSFS_PATH_MAX 255
22
23
24static unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen)
25{
26 int fd;
27 ssize_t numread;
28
29 fd = open(path, O_RDONLY);
30 if (fd == -1)
31 return 0;
32
33 numread = read(fd, buf, buflen - 1);
34 if (numread < 1) {
35 close(fd);
36 return 0;
37 }
38
39 buf[numread] = '\0';
40 close(fd);
41
42 return (unsigned int) numread;
43}
44
45
46/* CPUFREQ sysfs access **************************************************/
47
48/* helper function to read file from /sys into given buffer */
49/* fname is a relative path under "cpuX/cpufreq" dir */
50static unsigned int sysfs_cpufreq_read_file(unsigned int cpu, const char *fname,
51 char *buf, size_t buflen)
52{
53 char path[SYSFS_PATH_MAX];
54
55 snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s",
56 cpu, fname);
57 return sysfs_read_file(path, buf, buflen);
58}
59
60/* helper function to write a new value to a /sys file */
61/* fname is a relative path under "cpuX/cpufreq" dir */
62static unsigned int sysfs_cpufreq_write_file(unsigned int cpu,
63 const char *fname,
64 const char *value, size_t len)
65{
66 char path[SYSFS_PATH_MAX];
67 int fd;
68 ssize_t numwrite;
69
70 snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s",
71 cpu, fname);
72
73 fd = open(path, O_WRONLY);
74 if (fd == -1)
75 return 0;
76
77 numwrite = write(fd, value, len);
78 if (numwrite < 1) {
79 close(fd);
80 return 0;
81 }
82
83 close(fd);
84
85 return (unsigned int) numwrite;
86}
87
88/* read access to files which contain one numeric value */
89
90enum cpufreq_value {
91 CPUINFO_CUR_FREQ,
92 CPUINFO_MIN_FREQ,
93 CPUINFO_MAX_FREQ,
94 CPUINFO_LATENCY,
95 SCALING_CUR_FREQ,
96 SCALING_MIN_FREQ,
97 SCALING_MAX_FREQ,
98 STATS_NUM_TRANSITIONS,
99 MAX_CPUFREQ_VALUE_READ_FILES
100};
101
102static const char *cpufreq_value_files[MAX_CPUFREQ_VALUE_READ_FILES] = {
103 [CPUINFO_CUR_FREQ] = "cpuinfo_cur_freq",
104 [CPUINFO_MIN_FREQ] = "cpuinfo_min_freq",
105 [CPUINFO_MAX_FREQ] = "cpuinfo_max_freq",
106 [CPUINFO_LATENCY] = "cpuinfo_transition_latency",
107 [SCALING_CUR_FREQ] = "scaling_cur_freq",
108 [SCALING_MIN_FREQ] = "scaling_min_freq",
109 [SCALING_MAX_FREQ] = "scaling_max_freq",
110 [STATS_NUM_TRANSITIONS] = "stats/total_trans"
111};
112
113
114static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu,
115 enum cpufreq_value which)
116{
117 unsigned long value;
118 unsigned int len;
119 char linebuf[MAX_LINE_LEN];
120 char *endp;
121
122 if (which >= MAX_CPUFREQ_VALUE_READ_FILES)
123 return 0;
124
125 len = sysfs_cpufreq_read_file(cpu, cpufreq_value_files[which],
126 linebuf, sizeof(linebuf));
127
128 if (len == 0)
129 return 0;
130
131 value = strtoul(linebuf, &endp, 0);
132
133 if (endp == linebuf || errno == ERANGE)
134 return 0;
135
136 return value;
137}
138
139/* read access to files which contain one string */
140
141enum cpufreq_string {
142 SCALING_DRIVER,
143 SCALING_GOVERNOR,
144 MAX_CPUFREQ_STRING_FILES
145};
146
147static const char *cpufreq_string_files[MAX_CPUFREQ_STRING_FILES] = {
148 [SCALING_DRIVER] = "scaling_driver",
149 [SCALING_GOVERNOR] = "scaling_governor",
150};
151
152
153static char *sysfs_cpufreq_get_one_string(unsigned int cpu,
154 enum cpufreq_string which)
155{
156 char linebuf[MAX_LINE_LEN];
157 char *result;
158 unsigned int len;
159
160 if (which >= MAX_CPUFREQ_STRING_FILES)
161 return NULL;
162
163 len = sysfs_cpufreq_read_file(cpu, cpufreq_string_files[which],
164 linebuf, sizeof(linebuf));
165 if (len == 0)
166 return NULL;
167
168 result = strdup(linebuf);
169 if (result == NULL)
170 return NULL;
171
172 if (result[strlen(result) - 1] == '\n')
173 result[strlen(result) - 1] = '\0';
174
175 return result;
176}
177
178/* write access */
179
180enum cpufreq_write {
181 WRITE_SCALING_MIN_FREQ,
182 WRITE_SCALING_MAX_FREQ,
183 WRITE_SCALING_GOVERNOR,
184 WRITE_SCALING_SET_SPEED,
185 MAX_CPUFREQ_WRITE_FILES
186};
187
188static const char *cpufreq_write_files[MAX_CPUFREQ_WRITE_FILES] = {
189 [WRITE_SCALING_MIN_FREQ] = "scaling_min_freq",
190 [WRITE_SCALING_MAX_FREQ] = "scaling_max_freq",
191 [WRITE_SCALING_GOVERNOR] = "scaling_governor",
192 [WRITE_SCALING_SET_SPEED] = "scaling_setspeed",
193};
194
195static int sysfs_cpufreq_write_one_value(unsigned int cpu,
196 enum cpufreq_write which,
197 const char *new_value, size_t len)
198{
199 if (which >= MAX_CPUFREQ_WRITE_FILES)
200 return 0;
201
202 if (sysfs_cpufreq_write_file(cpu, cpufreq_write_files[which],
203 new_value, len) != len)
204 return -ENODEV;
205
206 return 0;
207};
208
209unsigned long sysfs_get_freq_kernel(unsigned int cpu)
210{
211 return sysfs_cpufreq_get_one_value(cpu, SCALING_CUR_FREQ);
212}
213
214unsigned long sysfs_get_freq_hardware(unsigned int cpu)
215{
216 return sysfs_cpufreq_get_one_value(cpu, CPUINFO_CUR_FREQ);
217}
218
219unsigned long sysfs_get_freq_transition_latency(unsigned int cpu)
220{
221 return sysfs_cpufreq_get_one_value(cpu, CPUINFO_LATENCY);
222}
223
224int sysfs_get_freq_hardware_limits(unsigned int cpu,
225 unsigned long *min,
226 unsigned long *max)
227{
228 if ((!min) || (!max))
229 return -EINVAL;
230
231 *min = sysfs_cpufreq_get_one_value(cpu, CPUINFO_MIN_FREQ);
232 if (!*min)
233 return -ENODEV;
234
235 *max = sysfs_cpufreq_get_one_value(cpu, CPUINFO_MAX_FREQ);
236 if (!*max)
237 return -ENODEV;
238
239 return 0;
240}
241
242char *sysfs_get_freq_driver(unsigned int cpu)
243{
244 return sysfs_cpufreq_get_one_string(cpu, SCALING_DRIVER);
245}
246
247struct cpufreq_policy *sysfs_get_freq_policy(unsigned int cpu)
248{
249 struct cpufreq_policy *policy;
250
251 policy = malloc(sizeof(struct cpufreq_policy));
252 if (!policy)
253 return NULL;
254
255 policy->governor = sysfs_cpufreq_get_one_string(cpu, SCALING_GOVERNOR);
256 if (!policy->governor) {
257 free(policy);
258 return NULL;
259 }
260 policy->min = sysfs_cpufreq_get_one_value(cpu, SCALING_MIN_FREQ);
261 policy->max = sysfs_cpufreq_get_one_value(cpu, SCALING_MAX_FREQ);
262 if ((!policy->min) || (!policy->max)) {
263 free(policy->governor);
264 free(policy);
265 return NULL;
266 }
267
268 return policy;
269}
270
271struct cpufreq_available_governors *
272sysfs_get_freq_available_governors(unsigned int cpu) {
273 struct cpufreq_available_governors *first = NULL;
274 struct cpufreq_available_governors *current = NULL;
275 char linebuf[MAX_LINE_LEN];
276 unsigned int pos, i;
277 unsigned int len;
278
279 len = sysfs_cpufreq_read_file(cpu, "scaling_available_governors",
280 linebuf, sizeof(linebuf));
281 if (len == 0)
282 return NULL;
283
284 pos = 0;
285 for (i = 0; i < len; i++) {
286 if (linebuf[i] == ' ' || linebuf[i] == '\n') {
287 if (i - pos < 2)
288 continue;
289 if (current) {
290 current->next = malloc(sizeof(*current));
291 if (!current->next)
292 goto error_out;
293 current = current->next;
294 } else {
295 first = malloc(sizeof(*first));
296 if (!first)
297 goto error_out;
298 current = first;
299 }
300 current->first = first;
301 current->next = NULL;
302
303 current->governor = malloc(i - pos + 1);
304 if (!current->governor)
305 goto error_out;
306
307 memcpy(current->governor, linebuf + pos, i - pos);
308 current->governor[i - pos] = '\0';
309 pos = i + 1;
310 }
311 }
312
313 return first;
314
315 error_out:
316 while (first) {
317 current = first->next;
318 if (first->governor)
319 free(first->governor);
320 free(first);
321 first = current;
322 }
323 return NULL;
324}
325
326
327struct cpufreq_available_frequencies *
328sysfs_get_available_frequencies(unsigned int cpu) {
329 struct cpufreq_available_frequencies *first = NULL;
330 struct cpufreq_available_frequencies *current = NULL;
331 char one_value[SYSFS_PATH_MAX];
332 char linebuf[MAX_LINE_LEN];
333 unsigned int pos, i;
334 unsigned int len;
335
336 len = sysfs_cpufreq_read_file(cpu, "scaling_available_frequencies",
337 linebuf, sizeof(linebuf));
338 if (len == 0)
339 return NULL;
340
341 pos = 0;
342 for (i = 0; i < len; i++) {
343 if (linebuf[i] == ' ' || linebuf[i] == '\n') {
344 if (i - pos < 2)
345 continue;
346 if (i - pos >= SYSFS_PATH_MAX)
347 goto error_out;
348 if (current) {
349 current->next = malloc(sizeof(*current));
350 if (!current->next)
351 goto error_out;
352 current = current->next;
353 } else {
354 first = malloc(sizeof(*first));
355 if (!first)
356 goto error_out;
357 current = first;
358 }
359 current->first = first;
360 current->next = NULL;
361
362 memcpy(one_value, linebuf + pos, i - pos);
363 one_value[i - pos] = '\0';
364 if (sscanf(one_value, "%lu", &current->frequency) != 1)
365 goto error_out;
366
367 pos = i + 1;
368 }
369 }
370
371 return first;
372
373 error_out:
374 while (first) {
375 current = first->next;
376 free(first);
377 first = current;
378 }
379 return NULL;
380}
381
382static struct cpufreq_affected_cpus *sysfs_get_cpu_list(unsigned int cpu,
383 const char *file)
384{
385 struct cpufreq_affected_cpus *first = NULL;
386 struct cpufreq_affected_cpus *current = NULL;
387 char one_value[SYSFS_PATH_MAX];
388 char linebuf[MAX_LINE_LEN];
389 unsigned int pos, i;
390 unsigned int len;
391
392 len = sysfs_cpufreq_read_file(cpu, file, linebuf, sizeof(linebuf));
393 if (len == 0)
394 return NULL;
395
396 pos = 0;
397 for (i = 0; i < len; i++) {
398 if (i == len || linebuf[i] == ' ' || linebuf[i] == '\n') {
399 if (i - pos < 1)
400 continue;
401 if (i - pos >= SYSFS_PATH_MAX)
402 goto error_out;
403 if (current) {
404 current->next = malloc(sizeof(*current));
405 if (!current->next)
406 goto error_out;
407 current = current->next;
408 } else {
409 first = malloc(sizeof(*first));
410 if (!first)
411 goto error_out;
412 current = first;
413 }
414 current->first = first;
415 current->next = NULL;
416
417 memcpy(one_value, linebuf + pos, i - pos);
418 one_value[i - pos] = '\0';
419
420 if (sscanf(one_value, "%u", &current->cpu) != 1)
421 goto error_out;
422
423 pos = i + 1;
424 }
425 }
426
427 return first;
428
429 error_out:
430 while (first) {
431 current = first->next;
432 free(first);
433 first = current;
434 }
435 return NULL;
436}
437
438struct cpufreq_affected_cpus *sysfs_get_freq_affected_cpus(unsigned int cpu)
439{
440 return sysfs_get_cpu_list(cpu, "affected_cpus");
441}
442
443struct cpufreq_affected_cpus *sysfs_get_freq_related_cpus(unsigned int cpu)
444{
445 return sysfs_get_cpu_list(cpu, "related_cpus");
446}
447
448struct cpufreq_stats *sysfs_get_freq_stats(unsigned int cpu,
449 unsigned long long *total_time) {
450 struct cpufreq_stats *first = NULL;
451 struct cpufreq_stats *current = NULL;
452 char one_value[SYSFS_PATH_MAX];
453 char linebuf[MAX_LINE_LEN];
454 unsigned int pos, i;
455 unsigned int len;
456
457 len = sysfs_cpufreq_read_file(cpu, "stats/time_in_state",
458 linebuf, sizeof(linebuf));
459 if (len == 0)
460 return NULL;
461
462 *total_time = 0;
463 pos = 0;
464 for (i = 0; i < len; i++) {
465 if (i == strlen(linebuf) || linebuf[i] == '\n') {
466 if (i - pos < 2)
467 continue;
468 if ((i - pos) >= SYSFS_PATH_MAX)
469 goto error_out;
470 if (current) {
471 current->next = malloc(sizeof(*current));
472 if (!current->next)
473 goto error_out;
474 current = current->next;
475 } else {
476 first = malloc(sizeof(*first));
477 if (!first)
478 goto error_out;
479 current = first;
480 }
481 current->first = first;
482 current->next = NULL;
483
484 memcpy(one_value, linebuf + pos, i - pos);
485 one_value[i - pos] = '\0';
486 if (sscanf(one_value, "%lu %llu",
487 &current->frequency,
488 &current->time_in_state) != 2)
489 goto error_out;
490
491 *total_time = *total_time + current->time_in_state;
492 pos = i + 1;
493 }
494 }
495
496 return first;
497
498 error_out:
499 while (first) {
500 current = first->next;
501 free(first);
502 first = current;
503 }
504 return NULL;
505}
506
507unsigned long sysfs_get_freq_transitions(unsigned int cpu)
508{
509 return sysfs_cpufreq_get_one_value(cpu, STATS_NUM_TRANSITIONS);
510}
511
512static int verify_gov(char *new_gov, char *passed_gov)
513{
514 unsigned int i, j = 0;
515
516 if (!passed_gov || (strlen(passed_gov) > 19))
517 return -EINVAL;
518
519 strncpy(new_gov, passed_gov, 20);
520 for (i = 0; i < 20; i++) {
521 if (j) {
522 new_gov[i] = '\0';
523 continue;
524 }
525 if ((new_gov[i] >= 'a') && (new_gov[i] <= 'z'))
526 continue;
527
528 if ((new_gov[i] >= 'A') && (new_gov[i] <= 'Z'))
529 continue;
530
531 if (new_gov[i] == '-')
532 continue;
533
534 if (new_gov[i] == '_')
535 continue;
536
537 if (new_gov[i] == '\0') {
538 j = 1;
539 continue;
540 }
541 return -EINVAL;
542 }
543 new_gov[19] = '\0';
544 return 0;
545}
546
547int sysfs_modify_freq_policy_governor(unsigned int cpu, char *governor)
548{
549 char new_gov[SYSFS_PATH_MAX];
550
551 if (!governor)
552 return -EINVAL;
553
554 if (verify_gov(new_gov, governor))
555 return -EINVAL;
556
557 return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_GOVERNOR,
558 new_gov, strlen(new_gov));
559};
560
561int sysfs_modify_freq_policy_max(unsigned int cpu, unsigned long max_freq)
562{
563 char value[SYSFS_PATH_MAX];
564
565 snprintf(value, SYSFS_PATH_MAX, "%lu", max_freq);
566
567 return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MAX_FREQ,
568 value, strlen(value));
569};
570
571
572int sysfs_modify_freq_policy_min(unsigned int cpu, unsigned long min_freq)
573{
574 char value[SYSFS_PATH_MAX];
575
576 snprintf(value, SYSFS_PATH_MAX, "%lu", min_freq);
577
578 return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MIN_FREQ,
579 value, strlen(value));
580};
581
582
583int sysfs_set_freq_policy(unsigned int cpu, struct cpufreq_policy *policy)
584{
585 char min[SYSFS_PATH_MAX];
586 char max[SYSFS_PATH_MAX];
587 char gov[SYSFS_PATH_MAX];
588 int ret;
589 unsigned long old_min;
590 int write_max_first;
591
592 if (!policy || !(policy->governor))
593 return -EINVAL;
594
595 if (policy->max < policy->min)
596 return -EINVAL;
597
598 if (verify_gov(gov, policy->governor))
599 return -EINVAL;
600
601 snprintf(min, SYSFS_PATH_MAX, "%lu", policy->min);
602 snprintf(max, SYSFS_PATH_MAX, "%lu", policy->max);
603
604 old_min = sysfs_cpufreq_get_one_value(cpu, SCALING_MIN_FREQ);
605 write_max_first = (old_min && (policy->max < old_min) ? 0 : 1);
606
607 if (write_max_first) {
608 ret = sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MAX_FREQ,
609 max, strlen(max));
610 if (ret)
611 return ret;
612 }
613
614 ret = sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MIN_FREQ, min,
615 strlen(min));
616 if (ret)
617 return ret;
618
619 if (!write_max_first) {
620 ret = sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MAX_FREQ,
621 max, strlen(max));
622 if (ret)
623 return ret;
624 }
625
626 return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_GOVERNOR,
627 gov, strlen(gov));
628}
629
630int sysfs_set_frequency(unsigned int cpu, unsigned long target_frequency)
631{
632 struct cpufreq_policy *pol = sysfs_get_freq_policy(cpu);
633 char userspace_gov[] = "userspace";
634 char freq[SYSFS_PATH_MAX];
635 int ret;
636
637 if (!pol)
638 return -ENODEV;
639
640 if (strncmp(pol->governor, userspace_gov, 9) != 0) {
641 ret = sysfs_modify_freq_policy_governor(cpu, userspace_gov);
642 if (ret) {
643 cpufreq_put_policy(pol);
644 return ret;
645 }
646 }
647
648 cpufreq_put_policy(pol);
649
650 snprintf(freq, SYSFS_PATH_MAX, "%lu", target_frequency);
651
652 return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_SET_SPEED,
653 freq, strlen(freq));
654}
655
656/* CPUFREQ sysfs access **************************************************/
657
658/* General sysfs access **************************************************/
659int sysfs_cpu_exists(unsigned int cpu)
660{
661 char file[SYSFS_PATH_MAX];
662 struct stat statbuf;
663
664 snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/", cpu);
665
666 if (stat(file, &statbuf) != 0)
667 return -ENOSYS;
668
669 return S_ISDIR(statbuf.st_mode) ? 0 : -ENOSYS;
670}
671
672/* General sysfs access **************************************************/
diff --git a/tools/power/cpupower/lib/sysfs.h b/tools/power/cpupower/lib/sysfs.h
new file mode 100644
index 000000000000..c76a5e0af501
--- /dev/null
+++ b/tools/power/cpupower/lib/sysfs.h
@@ -0,0 +1,31 @@
1/* General */
2extern unsigned int sysfs_cpu_exists(unsigned int cpu);
3
4/* CPUfreq */
5extern unsigned long sysfs_get_freq_kernel(unsigned int cpu);
6extern unsigned long sysfs_get_freq_hardware(unsigned int cpu);
7extern unsigned long sysfs_get_freq_transition_latency(unsigned int cpu);
8extern int sysfs_get_freq_hardware_limits(unsigned int cpu,
9 unsigned long *min, unsigned long *max);
10extern char *sysfs_get_freq_driver(unsigned int cpu);
11extern struct cpufreq_policy *sysfs_get_freq_policy(unsigned int cpu);
12extern struct cpufreq_available_governors *sysfs_get_freq_available_governors(
13 unsigned int cpu);
14extern struct cpufreq_available_frequencies *sysfs_get_available_frequencies(
15 unsigned int cpu);
16extern struct cpufreq_affected_cpus *sysfs_get_freq_affected_cpus(
17 unsigned int cpu);
18extern struct cpufreq_affected_cpus *sysfs_get_freq_related_cpus(
19 unsigned int cpu);
20extern struct cpufreq_stats *sysfs_get_freq_stats(unsigned int cpu,
21 unsigned long long *total_time);
22extern unsigned long sysfs_get_freq_transitions(unsigned int cpu);
23extern int sysfs_set_freq_policy(unsigned int cpu,
24 struct cpufreq_policy *policy);
25extern int sysfs_modify_freq_policy_min(unsigned int cpu,
26 unsigned long min_freq);
27extern int sysfs_modify_freq_policy_max(unsigned int cpu,
28 unsigned long max_freq);
29extern int sysfs_modify_freq_policy_governor(unsigned int cpu, char *governor);
30extern int sysfs_set_frequency(unsigned int cpu,
31 unsigned long target_frequency);
diff --git a/tools/power/cpupower/man/cpupower-frequency-info.1 b/tools/power/cpupower/man/cpupower-frequency-info.1
new file mode 100644
index 000000000000..3194811d58f5
--- /dev/null
+++ b/tools/power/cpupower/man/cpupower-frequency-info.1
@@ -0,0 +1,76 @@
1.TH "cpufreq-info" "1" "0.1" "Mattia Dongili" ""
2.SH "NAME"
3.LP
4cpufreq\-info \- Utility to retrieve cpufreq kernel information
5.SH "SYNTAX"
6.LP
7cpufreq\-info [\fIoptions\fP]
8.SH "DESCRIPTION"
9.LP
10A small tool which prints out cpufreq information helpful to developers and interested users.
11.SH "OPTIONS"
12.LP
13.TP
14\fB\-e\fR \fB\-\-debug\fR
15Prints out debug information.
16.TP
17\fB\-f\fR \fB\-\-freq\fR
18Get frequency the CPU currently runs at, according to the cpufreq core.
19.TP
20\fB\-w\fR \fB\-\-hwfreq\fR
21Get frequency the CPU currently runs at, by reading it from hardware (only available to root).
22.TP
23\fB\-l\fR \fB\-\-hwlimits\fR
24Determine the minimum and maximum CPU frequency allowed.
25.TP
26\fB\-d\fR \fB\-\-driver\fR
27Determines the used cpufreq kernel driver.
28.TP
29\fB\-p\fR \fB\-\-policy\fR
30Gets the currently used cpufreq policy.
31.TP
32\fB\-g\fR \fB\-\-governors\fR
33Determines available cpufreq governors.
34.TP
35\fB\-a\fR \fB\-\-related\-cpus\fR
36Determines which CPUs run at the same hardware frequency.
37.TP
38\fB\-a\fR \fB\-\-affected\-cpus\fR
39Determines which CPUs need to have their frequency coordinated by software.
40.TP
41\fB\-s\fR \fB\-\-stats\fR
42Shows cpufreq statistics if available.
43.TP
44\fB\-y\fR \fB\-\-latency\fR
45Determines the maximum latency on CPU frequency changes.
46.TP
47\fB\-o\fR \fB\-\-proc\fR
48Prints out information like provided by the /proc/cpufreq interface in 2.4. and early 2.6. kernels.
49.TP
50\fB\-m\fR \fB\-\-human\fR
51human\-readable output for the \-f, \-w, \-s and \-y parameters.
52.TP
53\fB\-h\fR \fB\-\-help\fR
54Prints out the help screen.
55.SH "REMARKS"
56.LP
57By default only values of core zero are displayed. How to display settings of
58other cores is described in the cpupower(1) manpage in the \-\-cpu option section.
59.LP
60You can't specify more than one of the output specific options \-o \-e \-a \-g \-p \-d \-l \-w \-f \-y.
61.LP
62You also can't specify the \-o option combined with the \-c option.
63.SH "FILES"
64.nf
65\fI/sys/devices/system/cpu/cpu*/cpufreq/\fP
66\fI/proc/cpufreq\fP (deprecated)
67\fI/proc/sys/cpu/\fP (deprecated)
68.fi
69.SH "AUTHORS"
70.nf
71Dominik Brodowski <linux@brodo.de> \- author
72Mattia Dongili<malattia@gmail.com> \- first autolibtoolization
73.fi
74.SH "SEE ALSO"
75.LP
76cpupower\-frequency\-set(1), cpupower(1)
diff --git a/tools/power/cpupower/man/cpupower-frequency-set.1 b/tools/power/cpupower/man/cpupower-frequency-set.1
new file mode 100644
index 000000000000..26e3e13eee3b
--- /dev/null
+++ b/tools/power/cpupower/man/cpupower-frequency-set.1
@@ -0,0 +1,54 @@
1.TH "cpufreq-set" "1" "0.1" "Mattia Dongili" ""
2.SH "NAME"
3.LP
4cpufreq\-set \- A small tool which allows to modify cpufreq settings.
5.SH "SYNTAX"
6.LP
7cpufreq\-set [\fIoptions\fP]
8.SH "DESCRIPTION"
9.LP
10cpufreq\-set allows you to modify cpufreq settings without having to type e.g. "/sys/devices/system/cpu/cpu0/cpufreq/scaling_set_speed" all the time.
11.SH "OPTIONS"
12.LP
13.TP
14\fB\-d\fR \fB\-\-min\fR <FREQ>
15new minimum CPU frequency the governor may select.
16.TP
17\fB\-u\fR \fB\-\-max\fR <FREQ>
18new maximum CPU frequency the governor may select.
19.TP
20\fB\-g\fR \fB\-\-governor\fR <GOV>
21new cpufreq governor.
22.TP
23\fB\-f\fR \fB\-\-freq\fR <FREQ>
24specific frequency to be set. Requires userspace governor to be available and loaded.
25.TP
26\fB\-r\fR \fB\-\-related\fR
27modify all hardware-related CPUs at the same time
28.TP
29\fB\-h\fR \fB\-\-help\fR
30Prints out the help screen.
31.SH "REMARKS"
32.LP
33By default values are applied on all cores. How to modify single core
34configurations is described in the cpupower(1) manpage in the \-\-cpu option section.
35.LP
36The \-f FREQ, \-\-freq FREQ parameter cannot be combined with any other parameter.
37.LP
38FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz by postfixing the value with the wanted unit name, without any space (frequency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).
39.LP
40On Linux kernels up to 2.6.29, the \-r or \-\-related parameter is ignored.
41.SH "FILES"
42.nf
43\fI/sys/devices/system/cpu/cpu*/cpufreq/\fP
44\fI/proc/cpufreq\fP (deprecated)
45\fI/proc/sys/cpu/\fP (deprecated)
46.fi
47.SH "AUTHORS"
48.nf
49Dominik Brodowski <linux@brodo.de> \- author
50Mattia Dongili<malattia@gmail.com> \- first autolibtoolization
51.fi
52.SH "SEE ALSO"
53.LP
54cpupower\-frequency\-info(1), cpupower(1)
diff --git a/tools/power/cpupower/man/cpupower-info.1 b/tools/power/cpupower/man/cpupower-info.1
new file mode 100644
index 000000000000..58e21196f17f
--- /dev/null
+++ b/tools/power/cpupower/man/cpupower-info.1
@@ -0,0 +1,19 @@
1.TH CPUPOWER\-INFO "1" "22/02/2011" "" "cpupower Manual"
2.SH NAME
3cpupower\-info \- Shows processor power related kernel or hardware configurations
4.SH SYNOPSIS
5.ft B
6.B cpupower info [ \-b ] [ \-s ] [ \-m ]
7
8.SH DESCRIPTION
9\fBcpupower info \fP shows kernel configurations or processor hardware
10registers affecting processor power saving policies.
11
12Some options are platform wide, some affect single cores. By default values
13of core zero are displayed only. cpupower --cpu all cpuinfo will show the
14settings of all cores, see cpupower(1) how to choose specific cores.
15
16.SH "SEE ALSO"
17Options are described in detail in:
18
19cpupower(1), cpupower-set(1)
diff --git a/tools/power/cpupower/man/cpupower-monitor.1 b/tools/power/cpupower/man/cpupower-monitor.1
new file mode 100644
index 000000000000..d5cfa265c3d3
--- /dev/null
+++ b/tools/power/cpupower/man/cpupower-monitor.1
@@ -0,0 +1,179 @@
1.TH CPUPOWER\-MONITOR "1" "22/02/2011" "" "cpupower Manual"
2.SH NAME
3cpupower\-monitor \- Report processor frequency and idle statistics
4.SH SYNOPSIS
5.ft B
6.B cpupower monitor
7.RB "\-l"
8
9.B cpupower monitor
10.RB [ "\-m <mon1>," [ "<mon2>,..." ] ]
11.RB [ "\-i seconds" ]
12.br
13.B cpupower monitor
14.RB [ "\-m <mon1>," [ "<mon2>,..." ] ]
15.RB command
16.br
17.SH DESCRIPTION
18\fBcpupower-monitor \fP reports processor topology, frequency and idle power
19state statistics. Either \fBcommand\fP is forked and
20statistics are printed upon its completion, or statistics are printed periodically.
21
22\fBcpupower-monitor \fP implements independent processor sleep state and
23frequency counters. Some are retrieved from kernel statistics, some are
24directly reading out hardware registers. Use \-l to get an overview which are
25supported on your system.
26
27.SH Options
28.PP
29\-l
30.RS 4
31List available monitors on your system. Additional details about each monitor
32are shown:
33.RS 2
34.IP \(bu
35The name in quotation marks which can be passed to the \-m parameter.
36.IP \(bu
37The number of different counters the monitor supports in brackets.
38.IP \(bu
39The amount of time in seconds the counters might overflow, due to
40implementation constraints.
41.IP \(bu
42The name and a description of each counter and its processor hierarchy level
43coverage in square brackets:
44.RS 4
45.IP \(bu
46[T] \-> Thread
47.IP \(bu
48[C] \-> Core
49.IP \(bu
50[P] \-> Processor Package (Socket)
51.IP \(bu
52[M] \-> Machine/Platform wide counter
53.RE
54.RE
55.RE
56.PP
57\-m <mon1>,<mon2>,...
58.RS 4
59Only display specific monitors. Use the monitor string(s) provided by \-l option.
60.RE
61.PP
62\-i seconds
63.RS 4
64Measure intervall.
65.RE
66.PP
67command
68.RS 4
69Measure idle and frequency characteristics of an arbitrary command/workload.
70The executable \fBcommand\fP is forked and upon its exit, statistics gathered since it was
71forked are displayed.
72.RE
73.PP
74\-v
75.RS 4
76Increase verbosity if the binary was compiled with the DEBUG option set.
77.RE
78
79.SH MONITOR DESCRIPTIONS
80.SS "Idle_Stats"
81Shows statistics of the cpuidle kernel subsystem. Values are retrieved from
82/sys/devices/system/cpu/cpu*/cpuidle/state*/.
83The kernel updates these values every time an idle state is entered or
84left. Therefore there can be some inaccuracy when cores are in an idle
85state for some time when the measure starts or ends. In worst case it can happen
86that one core stayed in an idle state for the whole measure time and the idle
87state usage time as exported by the kernel did not get updated. In this case
88a state residency of 0 percent is shown while it was 100.
89
90.SS "Mperf"
91The name comes from the aperf/mperf (average and maximum) MSR registers used
92which are available on recent X86 processors. It shows the average frequency
93(including boost frequencies).
94The fact that on all recent hardware the mperf timer stops ticking in any idle
95state it is also used to show C0 (processor is active) and Cx (processor is in
96any sleep state) times. These counters do not have the inaccuracy restrictions
97the "Idle_Stats" counters may show.
98May work poorly on Linux-2.6.20 through 2.6.29, as the \fBacpi-cpufreq \fP
99kernel frequency driver periodically cleared aperf/mperf registers in those
100kernels.
101
102.SS "Nehalem" "SandyBridge"
103Intel Core and Package sleep state counters.
104Threads (hyperthreaded cores) may not be able to enter deeper core states if
105its sibling is utilized.
106Deepest package sleep states may in reality show up as machine/platform wide
107sleep states and can only be entered if all cores are idle. Look up Intel
108manuals (some are provided in the References section) for further details.
109
110.SS "Ontario" "Liano"
111AMD laptop and desktop processor (family 12h and 14h) sleep state counters.
112The registers are accessed via PCI and therefore can still be read out while
113cores have been offlined.
114
115There is one special counter: NBP1 (North Bridge P1).
116This one always returns 0 or 1, depending on whether the North Bridge P1
117power state got entered at least once during measure time.
118Being able to enter NBP1 state also depends on graphics power management.
119Therefore this counter can be used to verify whether the graphics' driver
120power management is working as expected.
121
122.SH EXAMPLES
123
124cpupower monitor -l" may show:
125.RS 4
126Monitor "Mperf" (3 states) \- Might overflow after 922000000 s
127
128 ...
129
130Monitor "Idle_Stats" (3 states) \- Might overflow after 4294967295 s
131
132 ...
133
134.RE
135cpupower monitor \-m "Idle_Stats,Mperf" scp /tmp/test /nfs/tmp
136
137Monitor the scp command, show both Mperf and Idle_Stats states counter
138statistics, but in exchanged order.
139
140
141
142.RE
143Be careful that the typical command to fully utilize one CPU by doing:
144
145cpupower monitor cat /dev/zero >/dev/null
146
147Does not work as expected, because the measured output is redirected to
148/dev/null. This could get workarounded by putting the line into an own, tiny
149shell script. Hit CTRL\-c to terminate the command and get the measure output
150displayed.
151
152.SH REFERENCES
153"BIOS and Kernel Developer’s Guide (BKDG) for AMD Family 14h Processors"
154http://support.amd.com/us/Processor_TechDocs/43170.pdf
155
156"Intel® Turbo Boost Technology
157in Intel® Core™ Microarchitecture (Nehalem) Based Processors"
158http://download.intel.com/design/processor/applnots/320354.pdf
159
160"Intel® 64 and IA-32 Architectures Software Developer's Manual
161Volume 3B: System Programming Guide"
162http://www.intel.com/products/processor/manuals
163
164.SH FILES
165.ta
166.nf
167/dev/cpu/*/msr
168/sys/devices/system/cpu/cpu*/cpuidle/state*/.
169.fi
170
171.SH "SEE ALSO"
172powertop(8), msr(4), vmstat(8)
173.PP
174.SH AUTHORS
175.nf
176Written by Thomas Renninger <trenn@suse.de>
177
178Nehalem, SandyBridge monitors and command passing
179based on turbostat.8 from Len Brown <len.brown@intel.com>
diff --git a/tools/power/cpupower/man/cpupower-set.1 b/tools/power/cpupower/man/cpupower-set.1
new file mode 100644
index 000000000000..c4954a9fe4e7
--- /dev/null
+++ b/tools/power/cpupower/man/cpupower-set.1
@@ -0,0 +1,103 @@
1.TH CPUPOWER\-SET "1" "22/02/2011" "" "cpupower Manual"
2.SH NAME
3cpupower\-set \- Set processor power related kernel or hardware configurations
4.SH SYNOPSIS
5.ft B
6.B cpupower set [ \-b VAL ] [ \-s VAL ] [ \-m VAL ]
7
8
9.SH DESCRIPTION
10\fBcpupower set \fP sets kernel configurations or directly accesses hardware
11registers affecting processor power saving policies.
12
13Some options are platform wide, some affect single cores. By default values
14are applied on all cores. How to modify single core configurations is
15described in the cpupower(1) manpage in the \-\-cpu option section. Whether an
16option affects the whole system or can be applied to individual cores is
17described in the Options sections.
18
19Use \fBcpupower info \fP to read out current settings and whether they are
20supported on the system at all.
21
22.SH Options
23.PP
24\-\-perf-bias, \-b
25.RS 4
26Sets a register on supported Intel processore which allows software to convey
27its policy for the relative importance of performance versus energy savings to
28the processor.
29
30The range of valid numbers is 0-15, where 0 is maximum
31performance and 15 is maximum energy efficiency.
32
33The processor uses this information in model-specific ways
34when it must select trade-offs between performance and
35energy efficiency.
36
37This policy hint does not supersede Processor Performance states
38(P-states) or CPU Idle power states (C-states), but allows
39software to have influence where it would otherwise be unable
40to express a preference.
41
42For example, this setting may tell the hardware how
43aggressively or conservatively to control frequency
44in the "turbo range" above the explicitly OS-controlled
45P-state frequency range. It may also tell the hardware
46how aggressively it should enter the OS requested C-states.
47
48This option can be applied to individual cores only via the \-\-cpu option,
49cpupower(1).
50
51Setting the performance bias value on one CPU can modify the setting on
52related CPUs as well (for example all CPUs on one socket), because of
53hardware restrictions.
54Use \fBcpupower -c all info -b\fP to verify.
55
56This options needs the msr kernel driver (CONFIG_X86_MSR) loaded.
57.RE
58.PP
59\-\-sched\-mc, \-m [ VAL ]
60.RE
61\-\-sched\-smt, \-s [ VAL ]
62.RS 4
63\-\-sched\-mc utilizes cores in one processor package/socket first before
64processes are scheduled to other processor packages/sockets.
65
66\-\-sched\-smt utilizes thread siblings of one processor core first before
67processes are scheduled to other cores.
68
69The impact on power consumption and performance (positiv or negativ) heavily
70depends on processor support for deep sleep states, frequency scaling and
71frequency boost modes and their dependencies between other thread siblings
72and processor cores.
73
74Taken over from kernel documentation:
75
76Adjust the kernel's multi-core scheduler support.
77
78Possible values are:
79.RS 2
800 - No power saving load balance (default value)
81
821 - Fill one thread/core/package first for long running threads
83
842 - Also bias task wakeups to semi-idle cpu package for power
85savings
86.RE
87
88sched_mc_power_savings is dependent upon SCHED_MC, which is
89itself architecture dependent.
90
91sched_smt_power_savings is dependent upon SCHED_SMT, which
92is itself architecture dependent.
93
94The two files are independent of each other. It is possible
95that one file may be present without the other.
96
97.SH "SEE ALSO"
98cpupower-info(1), cpupower-monitor(1), powertop(1)
99.PP
100.SH AUTHORS
101.nf
102\-\-perf\-bias parts written by Len Brown <len.brown@intel.com>
103Thomas Renninger <trenn@suse.de>
diff --git a/tools/power/cpupower/man/cpupower.1 b/tools/power/cpupower/man/cpupower.1
new file mode 100644
index 000000000000..78c20feab85c
--- /dev/null
+++ b/tools/power/cpupower/man/cpupower.1
@@ -0,0 +1,72 @@
1.TH CPUPOWER "1" "07/03/2011" "" "cpupower Manual"
2.SH NAME
3cpupower \- Shows and sets processor power related values
4.SH SYNOPSIS
5.ft B
6.B cpupower [ \-c cpulist ] subcommand [ARGS]
7
8.B cpupower \-v|\-\-version
9
10.B cpupower \-h|\-\-help
11
12.SH DESCRIPTION
13\fBcpupower \fP is a collection of tools to examine and tune power saving
14related features of your processor.
15
16The manpages of the subcommands (cpupower\-<subcommand>(1)) provide detailed
17descriptions of supported features. Run \fBcpupower help\fP to get an overview
18of supported subcommands.
19
20.SH Options
21.PP
22\-\-help, \-h
23.RS 4
24Shows supported subcommands and general usage.
25.RE
26.PP
27\-\-cpu cpulist, \-c cpulist
28.RS 4
29Only show or set values for specific cores.
30This option is not supported by all subcommands, details can be found in the
31manpages of the subcommands.
32
33Some subcommands access all cores (typically the *\-set commands), some only
34the first core (typically the *\-info commands) by default.
35
36The syntax for <cpulist> is based on how the kernel exports CPU bitmasks via
37sysfs files. Some examples:
38.RS 4
39.TP 16
40Input
41Equivalent to
42.TP
43all
44all cores
45.TP
460\-3
470,1,2,3
48.TP
490\-7:2
500,2,4,6
51.TP
521,3,5-7
531,3,5,6,7
54.TP
550\-3:2,8\-15:4
560,2,8,12
57.RE
58.RE
59.PP
60\-\-version, \-v
61.RS 4
62Print the package name and version number.
63
64.SH "SEE ALSO"
65cpupower-set(1), cpupower-info(1), cpupower-idle(1),
66cpupower-frequency-set(1), cpupower-frequency-info(1), cpupower-monitor(1),
67powertop(1)
68.PP
69.SH AUTHORS
70.nf
71\-\-perf\-bias parts written by Len Brown <len.brown@intel.com>
72Thomas Renninger <trenn@suse.de>
diff --git a/tools/power/cpupower/po/cs.po b/tools/power/cpupower/po/cs.po
new file mode 100644
index 000000000000..cb22c45c5069
--- /dev/null
+++ b/tools/power/cpupower/po/cs.po
@@ -0,0 +1,944 @@
1# translation of cs.po to Czech
2# Czech translation for cpufrequtils package
3# Czech messages for cpufrequtils.
4# Copyright (C) 2007 kavol
5# This file is distributed under the same license as the cpufrequtils package.
6#
7# Karel Volný <kavol@seznam.cz>, 2007, 2008.
8msgid ""
9msgstr ""
10"Project-Id-Version: cs\n"
11"Report-Msgid-Bugs-To: \n"
12"POT-Creation-Date: 2011-03-08 17:03+0100\n"
13"PO-Revision-Date: 2008-06-11 16:26+0200\n"
14"Last-Translator: Karel Volný <kavol@seznam.cz>\n"
15"Language-Team: Czech <diskuze@lists.l10n.cz>\n"
16"Language: cs\n"
17"MIME-Version: 1.0\n"
18"Content-Type: text/plain; charset=UTF-8\n"
19"Content-Transfer-Encoding: 8bit\n"
20"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
21"X-Generator: KBabel 1.11.4\n"
22
23#: utils/idle_monitor/nhm_idle.c:36
24msgid "Processor Core C3"
25msgstr ""
26
27#: utils/idle_monitor/nhm_idle.c:43
28msgid "Processor Core C6"
29msgstr ""
30
31#: utils/idle_monitor/nhm_idle.c:51
32msgid "Processor Package C3"
33msgstr ""
34
35#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70
36msgid "Processor Package C6"
37msgstr ""
38
39#: utils/idle_monitor/snb_idle.c:33
40msgid "Processor Core C7"
41msgstr ""
42
43#: utils/idle_monitor/snb_idle.c:40
44msgid "Processor Package C2"
45msgstr ""
46
47#: utils/idle_monitor/snb_idle.c:47
48msgid "Processor Package C7"
49msgstr ""
50
51#: utils/idle_monitor/amd_fam14h_idle.c:56
52msgid "Package in sleep state (PC1 or deeper)"
53msgstr ""
54
55#: utils/idle_monitor/amd_fam14h_idle.c:63
56msgid "Processor Package C1"
57msgstr ""
58
59#: utils/idle_monitor/amd_fam14h_idle.c:77
60msgid "North Bridge P1 boolean counter (returns 0 or 1)"
61msgstr ""
62
63#: utils/idle_monitor/mperf_monitor.c:35
64msgid "Processor Core not idle"
65msgstr ""
66
67#: utils/idle_monitor/mperf_monitor.c:42
68msgid "Processor Core in an idle state"
69msgstr ""
70
71#: utils/idle_monitor/mperf_monitor.c:50
72msgid "Average Frequency (including boost) in MHz"
73msgstr ""
74
75#: utils/idle_monitor/cpupower-monitor.c:66
76#, c-format
77msgid ""
78"cpupower monitor: [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
79"interval_sec | -c command ...]\n"
80msgstr ""
81
82#: utils/idle_monitor/cpupower-monitor.c:69
83#, c-format
84msgid ""
85"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
86"interval_sec | -c command ...]\n"
87msgstr ""
88
89#: utils/idle_monitor/cpupower-monitor.c:71
90#, c-format
91msgid "\t -v: be more verbose\n"
92msgstr ""
93
94#: utils/idle_monitor/cpupower-monitor.c:73
95#, c-format
96msgid "\t -h: print this help\n"
97msgstr ""
98
99#: utils/idle_monitor/cpupower-monitor.c:74
100#, c-format
101msgid "\t -i: time intervall to measure for in seconds (default 1)\n"
102msgstr ""
103
104#: utils/idle_monitor/cpupower-monitor.c:75
105#, c-format
106msgid "\t -t: show CPU topology/hierarchy\n"
107msgstr ""
108
109#: utils/idle_monitor/cpupower-monitor.c:76
110#, c-format
111msgid "\t -l: list available CPU sleep monitors (for use with -m)\n"
112msgstr ""
113
114#: utils/idle_monitor/cpupower-monitor.c:77
115#, c-format
116msgid "\t -m: show specific CPU sleep monitors only (in same order)\n"
117msgstr ""
118
119#: utils/idle_monitor/cpupower-monitor.c:79
120#, c-format
121msgid ""
122"only one of: -t, -l, -m are allowed\n"
123"If none of them is passed,"
124msgstr ""
125
126#: utils/idle_monitor/cpupower-monitor.c:80
127#, c-format
128msgid " all supported monitors are shown\n"
129msgstr ""
130
131#: utils/idle_monitor/cpupower-monitor.c:197
132#, c-format
133msgid "Monitor %s, Counter %s has no count function. Implementation error\n"
134msgstr ""
135
136#: utils/idle_monitor/cpupower-monitor.c:207
137#, c-format
138msgid " *is offline\n"
139msgstr ""
140
141#: utils/idle_monitor/cpupower-monitor.c:236
142#, c-format
143msgid "%s: max monitor name length (%d) exceeded\n"
144msgstr ""
145
146#: utils/idle_monitor/cpupower-monitor.c:250
147#, c-format
148msgid "No matching monitor found in %s, try -l option\n"
149msgstr ""
150
151#: utils/idle_monitor/cpupower-monitor.c:266
152#, c-format
153msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n"
154msgstr ""
155
156#: utils/idle_monitor/cpupower-monitor.c:319
157#, c-format
158msgid "%s took %.5f seconds and exited with status %d\n"
159msgstr ""
160
161#: utils/idle_monitor/cpupower-monitor.c:406
162#, c-format
163msgid "Cannot read number of available processors\n"
164msgstr ""
165
166#: utils/idle_monitor/cpupower-monitor.c:417
167#, c-format
168msgid "Available monitor %s needs root access\n"
169msgstr ""
170
171#: utils/idle_monitor/cpupower-monitor.c:428
172#, c-format
173msgid "No HW Cstate monitors found\n"
174msgstr ""
175
176#: utils/cpupower.c:78
177#, c-format
178msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n"
179msgstr ""
180
181#: utils/cpupower.c:79
182#, c-format
183msgid "cpupower --version\n"
184msgstr ""
185
186#: utils/cpupower.c:80
187#, c-format
188msgid "Supported subcommands are:\n"
189msgstr ""
190
191#: utils/cpupower.c:83
192#, c-format
193msgid ""
194"\n"
195"Some subcommands can make use of the -c cpulist option.\n"
196msgstr ""
197
198#: utils/cpupower.c:84
199#, c-format
200msgid "Look at the general cpupower manpage how to use it\n"
201msgstr ""
202
203#: utils/cpupower.c:85
204#, c-format
205msgid "and read up the subcommand's manpage whether it is supported.\n"
206msgstr ""
207
208#: utils/cpupower.c:86
209#, c-format
210msgid ""
211"\n"
212"Use cpupower help subcommand for getting help for above subcommands.\n"
213msgstr ""
214
215#: utils/cpupower.c:91
216#, c-format
217msgid "Report errors and bugs to %s, please.\n"
218msgstr ""
219"Chyby v programu prosím hlaste na %s (anglicky).\n"
220"Chyby v pÅ™ekladu prosím hlaste na kavol@seznam.cz (Äesky ;-)\n"
221
222#: utils/cpupower.c:114
223#, c-format
224msgid "Error parsing cpu list\n"
225msgstr ""
226
227#: utils/cpupower.c:172
228#, c-format
229msgid "Subcommand %s needs root privileges\n"
230msgstr ""
231
232#: utils/cpufreq-info.c:31
233#, c-format
234msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n"
235msgstr "Nelze zjistit poÄet CPU (%s: %s), pÅ™edpokládá se 1.\n"
236
237#: utils/cpufreq-info.c:63
238#, c-format
239msgid ""
240" minimum CPU frequency - maximum CPU frequency - governor\n"
241msgstr ""
242" minimální frekvence CPU - maximální frekvence CPU - regulátor\n"
243
244#: utils/cpufreq-info.c:151
245#, c-format
246msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n"
247msgstr ""
248
249#. P state changes via MSR are identified via cpuid 80000007
250#. on Intel and AMD, but we assume boost capable machines can do that
251#. if (cpuid_eax(0x80000000) >= 0x80000007
252#. && (cpuid_edx(0x80000007) & (1 << 7)))
253#.
254#: utils/cpufreq-info.c:161
255#, c-format
256msgid " boost state support: \n"
257msgstr ""
258
259#: utils/cpufreq-info.c:163
260#, c-format
261msgid " Supported: %s\n"
262msgstr ""
263
264#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
265msgid "yes"
266msgstr ""
267
268#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
269msgid "no"
270msgstr ""
271
272#: utils/cpufreq-info.c:164
273#, fuzzy, c-format
274msgid " Active: %s\n"
275msgstr " ovladaÄ: %s\n"
276
277#: utils/cpufreq-info.c:177
278#, c-format
279msgid " Boost States: %d\n"
280msgstr ""
281
282#: utils/cpufreq-info.c:178
283#, c-format
284msgid " Total States: %d\n"
285msgstr ""
286
287#: utils/cpufreq-info.c:181
288#, c-format
289msgid " Pstate-Pb%d: %luMHz (boost state)\n"
290msgstr ""
291
292#: utils/cpufreq-info.c:184
293#, c-format
294msgid " Pstate-P%d: %luMHz\n"
295msgstr ""
296
297#: utils/cpufreq-info.c:211
298#, c-format
299msgid " no or unknown cpufreq driver is active on this CPU\n"
300msgstr " pro tento CPU není aktivní žádný známý ovladaÄ cpufreq\n"
301
302#: utils/cpufreq-info.c:213
303#, c-format
304msgid " driver: %s\n"
305msgstr " ovladaÄ: %s\n"
306
307#: utils/cpufreq-info.c:219
308#, fuzzy, c-format
309msgid " CPUs which run at the same hardware frequency: "
310msgstr " CPU, které musí měnit frekvenci zároveň: "
311
312#: utils/cpufreq-info.c:230
313#, fuzzy, c-format
314msgid " CPUs which need to have their frequency coordinated by software: "
315msgstr " CPU, které musí měnit frekvenci zároveň: "
316
317#: utils/cpufreq-info.c:241
318#, c-format
319msgid " maximum transition latency: "
320msgstr ""
321
322#: utils/cpufreq-info.c:247
323#, c-format
324msgid " hardware limits: "
325msgstr " hardwarové meze: "
326
327#: utils/cpufreq-info.c:256
328#, c-format
329msgid " available frequency steps: "
330msgstr " dostupné frekvence: "
331
332#: utils/cpufreq-info.c:269
333#, c-format
334msgid " available cpufreq governors: "
335msgstr " dostupné regulátory: "
336
337#: utils/cpufreq-info.c:280
338#, c-format
339msgid " current policy: frequency should be within "
340msgstr " souÄasná taktika: frekvence by mÄ›la být mezi "
341
342#: utils/cpufreq-info.c:282
343#, c-format
344msgid " and "
345msgstr " a "
346
347#: utils/cpufreq-info.c:286
348#, c-format
349msgid ""
350"The governor \"%s\" may decide which speed to use\n"
351" within this range.\n"
352msgstr ""
353" Regulátor \"%s\" může rozhodnout jakou frekvenci použít\n"
354" v těchto mezích.\n"
355
356#: utils/cpufreq-info.c:293
357#, c-format
358msgid " current CPU frequency is "
359msgstr " souÄasná frekvence CPU je "
360
361#: utils/cpufreq-info.c:296
362#, c-format
363msgid " (asserted by call to hardware)"
364msgstr " (zjištěno hardwarovým voláním)"
365
366#: utils/cpufreq-info.c:304
367#, c-format
368msgid " cpufreq stats: "
369msgstr " statistika cpufreq: "
370
371#: utils/cpufreq-info.c:472
372#, fuzzy, c-format
373msgid "Usage: cpupower freqinfo [options]\n"
374msgstr "Užití: cpufreq-info [pÅ™epínaÄe]\n"
375
376#: utils/cpufreq-info.c:473 utils/cpufreq-set.c:26 utils/cpupower-set.c:23
377#: utils/cpupower-info.c:22 utils/cpuidle-info.c:148
378#, c-format
379msgid "Options:\n"
380msgstr "PÅ™epínaÄe:\n"
381
382#: utils/cpufreq-info.c:474
383#, fuzzy, c-format
384msgid " -e, --debug Prints out debug information [default]\n"
385msgstr " -e, --debug Vypíše ladicí informace\n"
386
387#: utils/cpufreq-info.c:475
388#, c-format
389msgid ""
390" -f, --freq Get frequency the CPU currently runs at, according\n"
391" to the cpufreq core *\n"
392msgstr ""
393" -f, --freq Zjistí aktuální frekvenci, na které CPU běží\n"
394" podle cpufreq *\n"
395
396#: utils/cpufreq-info.c:477
397#, c-format
398msgid ""
399" -w, --hwfreq Get frequency the CPU currently runs at, by reading\n"
400" it from hardware (only available to root) *\n"
401msgstr ""
402" -w, --hwfreq Zjistí aktuální frekvenci, na které CPU běží\n"
403" z hardware (dostupné jen uživateli root) *\n"
404
405#: utils/cpufreq-info.c:479
406#, c-format
407msgid ""
408" -l, --hwlimits Determine the minimum and maximum CPU frequency "
409"allowed *\n"
410msgstr ""
411" -l, --hwlimits Zjistí minimální a maximální dostupnou frekvenci CPU "
412"*\n"
413
414#: utils/cpufreq-info.c:480
415#, c-format
416msgid " -d, --driver Determines the used cpufreq kernel driver *\n"
417msgstr " -d, --driver Zjistí aktivní ovladaÄ cpufreq *\n"
418
419#: utils/cpufreq-info.c:481
420#, c-format
421msgid " -p, --policy Gets the currently used cpufreq policy *\n"
422msgstr " -p, --policy Zjistí aktuální taktiku cpufreq *\n"
423
424#: utils/cpufreq-info.c:482
425#, c-format
426msgid " -g, --governors Determines available cpufreq governors *\n"
427msgstr " -g, --governors Zjistí dostupné regulátory cpufreq *\n"
428
429#: utils/cpufreq-info.c:483
430#, fuzzy, c-format
431msgid ""
432" -r, --related-cpus Determines which CPUs run at the same hardware "
433"frequency *\n"
434msgstr ""
435" -a, --affected-cpus Zjistí, které CPU musí měnit frekvenci zároveň *\n"
436
437#: utils/cpufreq-info.c:484
438#, fuzzy, c-format
439msgid ""
440" -a, --affected-cpus Determines which CPUs need to have their frequency\n"
441" coordinated by software *\n"
442msgstr ""
443" -a, --affected-cpus Zjistí, které CPU musí měnit frekvenci zároveň *\n"
444
445#: utils/cpufreq-info.c:486
446#, c-format
447msgid " -s, --stats Shows cpufreq statistics if available\n"
448msgstr " -s, --stats Zobrazí statistiku cpufreq, je-li dostupná\n"
449
450#: utils/cpufreq-info.c:487
451#, fuzzy, c-format
452msgid ""
453" -y, --latency Determines the maximum latency on CPU frequency "
454"changes *\n"
455msgstr ""
456" -l, --hwlimits Zjistí minimální a maximální dostupnou frekvenci CPU "
457"*\n"
458
459#: utils/cpufreq-info.c:488
460#, c-format
461msgid " -b, --boost Checks for turbo or boost modes *\n"
462msgstr ""
463
464#: utils/cpufreq-info.c:489
465#, c-format
466msgid ""
467" -o, --proc Prints out information like provided by the /proc/"
468"cpufreq\n"
469" interface in 2.4. and early 2.6. kernels\n"
470msgstr ""
471" -o, --proc Vypíše informace ve formátu, jaký používalo rozhraní\n"
472" /proc/cpufreq v kernelech Å™ady 2.4 a Äasné 2.6\n"
473
474#: utils/cpufreq-info.c:491
475#, fuzzy, c-format
476msgid ""
477" -m, --human human-readable output for the -f, -w, -s and -y "
478"parameters\n"
479msgstr ""
480" -m, --human Výstup parametrů -f, -w a -s v „lidmi Äitelném“ "
481"formátu\n"
482
483#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152
484#, c-format
485msgid " -h, --help Prints out this screen\n"
486msgstr " -h, --help Vypíše tuto nápovědu\n"
487
488#: utils/cpufreq-info.c:495
489#, c-format
490msgid ""
491"If no argument or only the -c, --cpu parameter is given, debug output about\n"
492"cpufreq is printed which is useful e.g. for reporting bugs.\n"
493msgstr ""
494"Není-li zadán žádný parametr nebo je-li zadán pouze pÅ™epínaÄ -c, --cpu, "
495"jsou\n"
496"vypsány ladicí informace, což může být užiteÄné například pÅ™i hlášení chyb.\n"
497
498#: utils/cpufreq-info.c:497
499#, c-format
500msgid ""
501"For the arguments marked with *, omitting the -c or --cpu argument is\n"
502"equivalent to setting it to zero\n"
503msgstr ""
504"Není-li pÅ™i použití pÅ™epínaÄů oznaÄených * zadán parametr -c nebo --cpu,\n"
505"předpokládá se jeho hodnota 0.\n"
506
507#: utils/cpufreq-info.c:580
508#, c-format
509msgid ""
510"The argument passed to this tool can't be combined with passing a --cpu "
511"argument\n"
512msgstr "Zadaný parametr nemůže být použit zároveň s pÅ™epínaÄem -c nebo --cpu\n"
513
514#: utils/cpufreq-info.c:596
515#, c-format
516msgid ""
517"You can't specify more than one --cpu parameter and/or\n"
518"more than one output-specific argument\n"
519msgstr ""
520"Nelze zadat více než jeden parametr -c nebo --cpu\n"
521"anebo více než jeden parametr urÄující výstup\n"
522
523#: utils/cpufreq-info.c:600 utils/cpufreq-set.c:82 utils/cpupower-set.c:42
524#: utils/cpupower-info.c:42 utils/cpuidle-info.c:213
525#, c-format
526msgid "invalid or unknown argument\n"
527msgstr "neplatný nebo neznámý parametr\n"
528
529#: utils/cpufreq-info.c:617
530#, c-format
531msgid "couldn't analyze CPU %d as it doesn't seem to be present\n"
532msgstr "nelze analyzovat CPU %d, vypadá to, že není přítomen\n"
533
534#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142
535#, c-format
536msgid "analyzing CPU %d:\n"
537msgstr "analyzuji CPU %d:\n"
538
539#: utils/cpufreq-set.c:25
540#, fuzzy, c-format
541msgid "Usage: cpupower frequency-set [options]\n"
542msgstr "Užití: cpufreq-set [pÅ™epínaÄe]\n"
543
544#: utils/cpufreq-set.c:27
545#, c-format
546msgid ""
547" -d FREQ, --min FREQ new minimum CPU frequency the governor may "
548"select\n"
549msgstr ""
550" -d FREQ, --min FREQ Nová nejnižší frekvence, kterou může regulátor "
551"vybrat\n"
552
553#: utils/cpufreq-set.c:28
554#, c-format
555msgid ""
556" -u FREQ, --max FREQ new maximum CPU frequency the governor may "
557"select\n"
558msgstr ""
559" -u FREQ, --max FREQ Nová nejvyšší frekvence, kterou může regulátor "
560"zvolit\n"
561
562#: utils/cpufreq-set.c:29
563#, c-format
564msgid " -g GOV, --governor GOV new cpufreq governor\n"
565msgstr " -g GOV, --governors GOV Nový regulátor cpufreq\n"
566
567#: utils/cpufreq-set.c:30
568#, c-format
569msgid ""
570" -f FREQ, --freq FREQ specific frequency to be set. Requires userspace\n"
571" governor to be available and loaded\n"
572msgstr ""
573" -f FREQ, --freq FREQ Frekvence, která má být nastavena. Vyžaduje, aby "
574"byl\n"
575" v jádře nahrán regulátor ‚userspace‘.\n"
576
577#: utils/cpufreq-set.c:32
578#, c-format
579msgid " -r, --related Switches all hardware-related CPUs\n"
580msgstr ""
581
582#: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27
583#, fuzzy, c-format
584msgid " -h, --help Prints out this screen\n"
585msgstr " -h, --help Vypíše tuto nápovědu\n"
586
587#: utils/cpufreq-set.c:35
588#, fuzzy, c-format
589msgid ""
590"Notes:\n"
591"1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n"
592msgstr ""
593"Není-li pÅ™i použití pÅ™epínaÄů oznaÄených * zadán parametr -c nebo --cpu,\n"
594"předpokládá se jeho hodnota 0.\n"
595
596#: utils/cpufreq-set.c:37
597#, fuzzy, c-format
598msgid ""
599"2. The -f FREQ, --freq FREQ parameter cannot be combined with any other "
600"parameter\n"
601" except the -c CPU, --cpu CPU parameter\n"
602"3. FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz\n"
603" by postfixing the value with the wanted unit name, without any space\n"
604" (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
605msgstr ""
606"Poznámky:\n"
607"1. Vynechání parametru -c nebo --cpu je ekvivalentní jeho nastavení na 0\n"
608"2. PÅ™epínaÄ -f nebo --freq nemůže být použit zároveň s žádným jiným vyjma -"
609"c\n"
610" nebo --cpu\n"
611"3. Frekvence (FREQ) mohou být zadány v Hz, kHz (výchozí), MHz, GHz nebo THz\n"
612" pÅ™ipojením názvu jednotky bez mezery mezi Äíslem a jednotkou\n"
613" (FREQ v kHz =^ Hz * 0,001 = ^ MHz * 1000 =^ GHz * 1000000)\n"
614
615#: utils/cpufreq-set.c:57
616#, c-format
617msgid ""
618"Error setting new values. Common errors:\n"
619"- Do you have proper administration rights? (super-user?)\n"
620"- Is the governor you requested available and modprobed?\n"
621"- Trying to set an invalid policy?\n"
622"- Trying to set a specific frequency, but userspace governor is not "
623"available,\n"
624" for example because of hardware which cannot be set to a specific "
625"frequency\n"
626" or because the userspace governor isn't loaded?\n"
627msgstr ""
628"Chyba při nastavování nových hodnot. Obvyklé problémy:\n"
629"- Máte patÅ™iÄná administrátorská práva? (root?)\n"
630"- Je požadovaný regulátor dostupný v jádře? (modprobe?)\n"
631"- Snažíte se nastavit neplatnou taktiku?\n"
632"- Snažíte se nastavit urÄitou frekvenci, ale není dostupný\n"
633" regulátor ‚userspace‘, například protože není nahrán v jádře,\n"
634" nebo nelze na tomto hardware nastavit urÄitou frekvenci?\n"
635
636#: utils/cpufreq-set.c:170
637#, c-format
638msgid "wrong, unknown or unhandled CPU?\n"
639msgstr "neznámý nebo nepodporovaný CPU?\n"
640
641#: utils/cpufreq-set.c:302
642#, c-format
643msgid ""
644"the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n"
645"-g/--governor parameters\n"
646msgstr ""
647"pÅ™epínaÄ -f/--freq nemůže být použit zároveň\n"
648"s pÅ™epínaÄem -d/--min, -u/--max nebo -g/--governor\n"
649
650#: utils/cpufreq-set.c:308
651#, c-format
652msgid ""
653"At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n"
654"-g/--governor must be passed\n"
655msgstr ""
656"Musí být zadán alespoň jeden pÅ™epínaÄ\n"
657"-f/--freq, -d/--min, -u/--max nebo -g/--governor\n"
658
659#: utils/cpufreq-set.c:347
660#, c-format
661msgid "Setting cpu: %d\n"
662msgstr ""
663
664#: utils/cpupower-set.c:22
665#, c-format
666msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n"
667msgstr ""
668
669#: utils/cpupower-set.c:24
670#, c-format
671msgid ""
672" -b, --perf-bias [VAL] Sets CPU's power vs performance policy on some\n"
673" Intel models [0-15], see manpage for details\n"
674msgstr ""
675
676#: utils/cpupower-set.c:26
677#, c-format
678msgid ""
679" -m, --sched-mc [VAL] Sets the kernel's multi core scheduler policy.\n"
680msgstr ""
681
682#: utils/cpupower-set.c:27
683#, c-format
684msgid ""
685" -s, --sched-smt [VAL] Sets the kernel's thread sibling scheduler "
686"policy.\n"
687msgstr ""
688
689#: utils/cpupower-set.c:80
690#, c-format
691msgid "--perf-bias param out of range [0-%d]\n"
692msgstr ""
693
694#: utils/cpupower-set.c:91
695#, c-format
696msgid "--sched-mc param out of range [0-%d]\n"
697msgstr ""
698
699#: utils/cpupower-set.c:102
700#, c-format
701msgid "--sched-smt param out of range [0-%d]\n"
702msgstr ""
703
704#: utils/cpupower-set.c:121
705#, c-format
706msgid "Error setting sched-mc %s\n"
707msgstr ""
708
709#: utils/cpupower-set.c:127
710#, c-format
711msgid "Error setting sched-smt %s\n"
712msgstr ""
713
714#: utils/cpupower-set.c:146
715#, c-format
716msgid "Error setting perf-bias value on CPU %d\n"
717msgstr ""
718
719#: utils/cpupower-info.c:21
720#, c-format
721msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n"
722msgstr ""
723
724#: utils/cpupower-info.c:23
725#, c-format
726msgid ""
727" -b, --perf-bias Gets CPU's power vs performance policy on some\n"
728" Intel models [0-15], see manpage for details\n"
729msgstr ""
730
731#: utils/cpupower-info.c:25
732#, fuzzy, c-format
733msgid " -m, --sched-mc Gets the kernel's multi core scheduler policy.\n"
734msgstr " -p, --policy Zjistí aktuální taktiku cpufreq *\n"
735
736#: utils/cpupower-info.c:26
737#, c-format
738msgid ""
739" -s, --sched-smt Gets the kernel's thread sibling scheduler policy.\n"
740msgstr ""
741
742#: utils/cpupower-info.c:28
743#, c-format
744msgid ""
745"\n"
746"Passing no option will show all info, by default only on core 0\n"
747msgstr ""
748
749#: utils/cpupower-info.c:102
750#, c-format
751msgid "System's multi core scheduler setting: "
752msgstr ""
753
754#. if sysfs file is missing it's: errno == ENOENT
755#: utils/cpupower-info.c:105 utils/cpupower-info.c:114
756#, c-format
757msgid "not supported\n"
758msgstr ""
759
760#: utils/cpupower-info.c:111
761#, c-format
762msgid "System's thread sibling scheduler setting: "
763msgstr ""
764
765#: utils/cpupower-info.c:126
766#, c-format
767msgid "Intel's performance bias setting needs root privileges\n"
768msgstr ""
769
770#: utils/cpupower-info.c:128
771#, c-format
772msgid "System does not support Intel's performance bias setting\n"
773msgstr ""
774
775#: utils/cpupower-info.c:147
776#, c-format
777msgid "Could not read perf-bias value\n"
778msgstr ""
779
780#: utils/cpupower-info.c:150
781#, c-format
782msgid "perf-bias: %d\n"
783msgstr ""
784
785#: utils/cpuidle-info.c:28
786#, fuzzy, c-format
787msgid "Analyzing CPU %d:\n"
788msgstr "analyzuji CPU %d:\n"
789
790#: utils/cpuidle-info.c:32
791#, c-format
792msgid "CPU %u: No idle states\n"
793msgstr ""
794
795#: utils/cpuidle-info.c:36
796#, c-format
797msgid "CPU %u: Can't read idle state info\n"
798msgstr ""
799
800#: utils/cpuidle-info.c:41
801#, c-format
802msgid "Could not determine max idle state %u\n"
803msgstr ""
804
805#: utils/cpuidle-info.c:46
806#, c-format
807msgid "Number of idle states: %d\n"
808msgstr ""
809
810#: utils/cpuidle-info.c:48
811#, fuzzy, c-format
812msgid "Available idle states:"
813msgstr " dostupné frekvence: "
814
815#: utils/cpuidle-info.c:71
816#, c-format
817msgid "Flags/Description: %s\n"
818msgstr ""
819
820#: utils/cpuidle-info.c:74
821#, c-format
822msgid "Latency: %lu\n"
823msgstr ""
824
825#: utils/cpuidle-info.c:76
826#, c-format
827msgid "Usage: %lu\n"
828msgstr ""
829
830#: utils/cpuidle-info.c:78
831#, c-format
832msgid "Duration: %llu\n"
833msgstr ""
834
835#: utils/cpuidle-info.c:90
836#, c-format
837msgid "Could not determine cpuidle driver\n"
838msgstr ""
839
840#: utils/cpuidle-info.c:94
841#, fuzzy, c-format
842msgid "CPUidle driver: %s\n"
843msgstr " ovladaÄ: %s\n"
844
845#: utils/cpuidle-info.c:99
846#, c-format
847msgid "Could not determine cpuidle governor\n"
848msgstr ""
849
850#: utils/cpuidle-info.c:103
851#, c-format
852msgid "CPUidle governor: %s\n"
853msgstr ""
854
855#: utils/cpuidle-info.c:122
856#, c-format
857msgid "CPU %u: Can't read C-state info\n"
858msgstr ""
859
860#. printf("Cstates: %d\n", cstates);
861#: utils/cpuidle-info.c:127
862#, c-format
863msgid "active state: C0\n"
864msgstr ""
865
866#: utils/cpuidle-info.c:128
867#, c-format
868msgid "max_cstate: C%u\n"
869msgstr ""
870
871#: utils/cpuidle-info.c:129
872#, c-format
873msgid "maximum allowed latency: %lu usec\n"
874msgstr ""
875
876#: utils/cpuidle-info.c:130
877#, c-format
878msgid "states:\t\n"
879msgstr ""
880
881#: utils/cpuidle-info.c:132
882#, c-format
883msgid " C%d: type[C%d] "
884msgstr ""
885
886#: utils/cpuidle-info.c:134
887#, c-format
888msgid "promotion[--] demotion[--] "
889msgstr ""
890
891#: utils/cpuidle-info.c:135
892#, c-format
893msgid "latency[%03lu] "
894msgstr ""
895
896#: utils/cpuidle-info.c:137
897#, c-format
898msgid "usage[%08lu] "
899msgstr ""
900
901#: utils/cpuidle-info.c:139
902#, c-format
903msgid "duration[%020Lu] \n"
904msgstr ""
905
906#: utils/cpuidle-info.c:147
907#, fuzzy, c-format
908msgid "Usage: cpupower idleinfo [options]\n"
909msgstr "Užití: cpufreq-info [pÅ™epínaÄe]\n"
910
911#: utils/cpuidle-info.c:149
912#, fuzzy, c-format
913msgid " -s, --silent Only show general C-state information\n"
914msgstr " -e, --debug Vypíše ladicí informace\n"
915
916#: utils/cpuidle-info.c:150
917#, fuzzy, c-format
918msgid ""
919" -o, --proc Prints out information like provided by the /proc/"
920"acpi/processor/*/power\n"
921" interface in older kernels\n"
922msgstr ""
923" -o, --proc Vypíše informace ve formátu, jaký používalo rozhraní\n"
924" /proc/cpufreq v kernelech Å™ady 2.4 a Äasné 2.6\n"
925
926#: utils/cpuidle-info.c:209
927#, fuzzy, c-format
928msgid "You can't specify more than one output-specific argument\n"
929msgstr ""
930"Nelze zadat více než jeden parametr -c nebo --cpu\n"
931"anebo více než jeden parametr urÄující výstup\n"
932
933#~ msgid ""
934#~ " -c CPU, --cpu CPU CPU number which information shall be determined "
935#~ "about\n"
936#~ msgstr ""
937#~ " -c CPU, --cpu CPU Číslo CPU, o kterém se mají zjistit informace\n"
938
939#~ msgid ""
940#~ " -c CPU, --cpu CPU number of CPU where cpufreq settings shall be "
941#~ "modified\n"
942#~ msgstr ""
943#~ " -c CPU, --cpu CPU Číslo CPU pro který se má provést nastavení "
944#~ "cpufreq\n"
diff --git a/tools/power/cpupower/po/de.po b/tools/power/cpupower/po/de.po
new file mode 100644
index 000000000000..78c09e51663a
--- /dev/null
+++ b/tools/power/cpupower/po/de.po
@@ -0,0 +1,961 @@
1# German translations for cpufrequtils package
2# German messages for cpufrequtils.
3# Copyright (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.net>
4# This file is distributed under the same license as the cpufrequtils package.
5#
6msgid ""
7msgstr ""
8"Project-Id-Version: cpufrequtils 006\n"
9"Report-Msgid-Bugs-To: \n"
10"POT-Creation-Date: 2011-03-08 17:03+0100\n"
11"PO-Revision-Date: 2009-08-08 17:18+0100\n"
12"Last-Translator: <linux@dominikbrodowski.net>\n"
13"Language-Team: NONE\n"
14"Language: \n"
15"MIME-Version: 1.0\n"
16"Content-Type: text/plain; charset=ISO-8859-1\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=(n != 1);\n"
19
20#: utils/idle_monitor/nhm_idle.c:36
21msgid "Processor Core C3"
22msgstr ""
23
24#: utils/idle_monitor/nhm_idle.c:43
25msgid "Processor Core C6"
26msgstr ""
27
28#: utils/idle_monitor/nhm_idle.c:51
29msgid "Processor Package C3"
30msgstr ""
31
32#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70
33msgid "Processor Package C6"
34msgstr ""
35
36#: utils/idle_monitor/snb_idle.c:33
37msgid "Processor Core C7"
38msgstr ""
39
40#: utils/idle_monitor/snb_idle.c:40
41msgid "Processor Package C2"
42msgstr ""
43
44#: utils/idle_monitor/snb_idle.c:47
45msgid "Processor Package C7"
46msgstr ""
47
48#: utils/idle_monitor/amd_fam14h_idle.c:56
49msgid "Package in sleep state (PC1 or deeper)"
50msgstr ""
51
52#: utils/idle_monitor/amd_fam14h_idle.c:63
53msgid "Processor Package C1"
54msgstr ""
55
56#: utils/idle_monitor/amd_fam14h_idle.c:77
57msgid "North Bridge P1 boolean counter (returns 0 or 1)"
58msgstr ""
59
60#: utils/idle_monitor/mperf_monitor.c:35
61msgid "Processor Core not idle"
62msgstr ""
63
64#: utils/idle_monitor/mperf_monitor.c:42
65msgid "Processor Core in an idle state"
66msgstr ""
67
68#: utils/idle_monitor/mperf_monitor.c:50
69msgid "Average Frequency (including boost) in MHz"
70msgstr ""
71
72#: utils/idle_monitor/cpupower-monitor.c:66
73#, c-format
74msgid ""
75"cpupower monitor: [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
76"interval_sec | -c command ...]\n"
77msgstr ""
78
79#: utils/idle_monitor/cpupower-monitor.c:69
80#, c-format
81msgid ""
82"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
83"interval_sec | -c command ...]\n"
84msgstr ""
85
86#: utils/idle_monitor/cpupower-monitor.c:71
87#, c-format
88msgid "\t -v: be more verbose\n"
89msgstr ""
90
91#: utils/idle_monitor/cpupower-monitor.c:73
92#, c-format
93msgid "\t -h: print this help\n"
94msgstr ""
95
96#: utils/idle_monitor/cpupower-monitor.c:74
97#, c-format
98msgid "\t -i: time intervall to measure for in seconds (default 1)\n"
99msgstr ""
100
101#: utils/idle_monitor/cpupower-monitor.c:75
102#, c-format
103msgid "\t -t: show CPU topology/hierarchy\n"
104msgstr ""
105
106#: utils/idle_monitor/cpupower-monitor.c:76
107#, c-format
108msgid "\t -l: list available CPU sleep monitors (for use with -m)\n"
109msgstr ""
110
111#: utils/idle_monitor/cpupower-monitor.c:77
112#, c-format
113msgid "\t -m: show specific CPU sleep monitors only (in same order)\n"
114msgstr ""
115
116#: utils/idle_monitor/cpupower-monitor.c:79
117#, c-format
118msgid ""
119"only one of: -t, -l, -m are allowed\n"
120"If none of them is passed,"
121msgstr ""
122
123#: utils/idle_monitor/cpupower-monitor.c:80
124#, c-format
125msgid " all supported monitors are shown\n"
126msgstr ""
127
128#: utils/idle_monitor/cpupower-monitor.c:197
129#, c-format
130msgid "Monitor %s, Counter %s has no count function. Implementation error\n"
131msgstr ""
132
133#: utils/idle_monitor/cpupower-monitor.c:207
134#, c-format
135msgid " *is offline\n"
136msgstr ""
137
138#: utils/idle_monitor/cpupower-monitor.c:236
139#, c-format
140msgid "%s: max monitor name length (%d) exceeded\n"
141msgstr ""
142
143#: utils/idle_monitor/cpupower-monitor.c:250
144#, c-format
145msgid "No matching monitor found in %s, try -l option\n"
146msgstr ""
147
148#: utils/idle_monitor/cpupower-monitor.c:266
149#, c-format
150msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n"
151msgstr ""
152
153#: utils/idle_monitor/cpupower-monitor.c:319
154#, c-format
155msgid "%s took %.5f seconds and exited with status %d\n"
156msgstr ""
157
158#: utils/idle_monitor/cpupower-monitor.c:406
159#, c-format
160msgid "Cannot read number of available processors\n"
161msgstr ""
162
163#: utils/idle_monitor/cpupower-monitor.c:417
164#, c-format
165msgid "Available monitor %s needs root access\n"
166msgstr ""
167
168#: utils/idle_monitor/cpupower-monitor.c:428
169#, c-format
170msgid "No HW Cstate monitors found\n"
171msgstr ""
172
173#: utils/cpupower.c:78
174#, c-format
175msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n"
176msgstr ""
177
178#: utils/cpupower.c:79
179#, c-format
180msgid "cpupower --version\n"
181msgstr ""
182
183#: utils/cpupower.c:80
184#, c-format
185msgid "Supported subcommands are:\n"
186msgstr ""
187
188#: utils/cpupower.c:83
189#, c-format
190msgid ""
191"\n"
192"Some subcommands can make use of the -c cpulist option.\n"
193msgstr ""
194
195#: utils/cpupower.c:84
196#, c-format
197msgid "Look at the general cpupower manpage how to use it\n"
198msgstr ""
199
200#: utils/cpupower.c:85
201#, c-format
202msgid "and read up the subcommand's manpage whether it is supported.\n"
203msgstr ""
204
205#: utils/cpupower.c:86
206#, c-format
207msgid ""
208"\n"
209"Use cpupower help subcommand for getting help for above subcommands.\n"
210msgstr ""
211
212#: utils/cpupower.c:91
213#, c-format
214msgid "Report errors and bugs to %s, please.\n"
215msgstr "Bitte melden Sie Fehler an %s.\n"
216
217#: utils/cpupower.c:114
218#, c-format
219msgid "Error parsing cpu list\n"
220msgstr ""
221
222#: utils/cpupower.c:172
223#, c-format
224msgid "Subcommand %s needs root privileges\n"
225msgstr ""
226
227#: utils/cpufreq-info.c:31
228#, c-format
229msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n"
230msgstr ""
231"Konnte nicht die Anzahl der CPUs herausfinden (%s : %s), nehme daher 1 an.\n"
232
233#: utils/cpufreq-info.c:63
234#, c-format
235msgid ""
236" minimum CPU frequency - maximum CPU frequency - governor\n"
237msgstr ""
238" minimale CPU-Taktfreq. - maximale CPU-Taktfreq. - Regler \n"
239
240#: utils/cpufreq-info.c:151
241#, c-format
242msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n"
243msgstr ""
244
245#. P state changes via MSR are identified via cpuid 80000007
246#. on Intel and AMD, but we assume boost capable machines can do that
247#. if (cpuid_eax(0x80000000) >= 0x80000007
248#. && (cpuid_edx(0x80000007) & (1 << 7)))
249#.
250#: utils/cpufreq-info.c:161
251#, c-format
252msgid " boost state support: \n"
253msgstr ""
254
255#: utils/cpufreq-info.c:163
256#, c-format
257msgid " Supported: %s\n"
258msgstr ""
259
260#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
261msgid "yes"
262msgstr ""
263
264#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
265msgid "no"
266msgstr ""
267
268#: utils/cpufreq-info.c:164
269#, fuzzy, c-format
270msgid " Active: %s\n"
271msgstr " Treiber: %s\n"
272
273#: utils/cpufreq-info.c:177
274#, c-format
275msgid " Boost States: %d\n"
276msgstr ""
277
278#: utils/cpufreq-info.c:178
279#, c-format
280msgid " Total States: %d\n"
281msgstr ""
282
283#: utils/cpufreq-info.c:181
284#, c-format
285msgid " Pstate-Pb%d: %luMHz (boost state)\n"
286msgstr ""
287
288#: utils/cpufreq-info.c:184
289#, c-format
290msgid " Pstate-P%d: %luMHz\n"
291msgstr ""
292
293#: utils/cpufreq-info.c:211
294#, c-format
295msgid " no or unknown cpufreq driver is active on this CPU\n"
296msgstr " kein oder nicht bestimmbarer cpufreq-Treiber aktiv\n"
297
298#: utils/cpufreq-info.c:213
299#, c-format
300msgid " driver: %s\n"
301msgstr " Treiber: %s\n"
302
303#: utils/cpufreq-info.c:219
304#, c-format
305msgid " CPUs which run at the same hardware frequency: "
306msgstr " Folgende CPUs laufen mit der gleichen Hardware-Taktfrequenz: "
307
308#: utils/cpufreq-info.c:230
309#, c-format
310msgid " CPUs which need to have their frequency coordinated by software: "
311msgstr " Die Taktfrequenz folgender CPUs werden per Software koordiniert: "
312
313#: utils/cpufreq-info.c:241
314#, c-format
315msgid " maximum transition latency: "
316msgstr " Maximale Dauer eines Taktfrequenzwechsels: "
317
318#: utils/cpufreq-info.c:247
319#, c-format
320msgid " hardware limits: "
321msgstr " Hardwarebedingte Grenzen der Taktfrequenz: "
322
323#: utils/cpufreq-info.c:256
324#, c-format
325msgid " available frequency steps: "
326msgstr " mögliche Taktfrequenzen: "
327
328#: utils/cpufreq-info.c:269
329#, c-format
330msgid " available cpufreq governors: "
331msgstr " mögliche Regler: "
332
333#: utils/cpufreq-info.c:280
334#, c-format
335msgid " current policy: frequency should be within "
336msgstr " momentane Taktik: die Frequenz soll innerhalb "
337
338#: utils/cpufreq-info.c:282
339#, c-format
340msgid " and "
341msgstr " und "
342
343#: utils/cpufreq-info.c:286
344#, c-format
345msgid ""
346"The governor \"%s\" may decide which speed to use\n"
347" within this range.\n"
348msgstr ""
349" liegen. Der Regler \"%s\" kann frei entscheiden,\n"
350" welche Taktfrequenz innerhalb dieser Grenze verwendet "
351"wird.\n"
352
353#: utils/cpufreq-info.c:293
354#, c-format
355msgid " current CPU frequency is "
356msgstr " momentane Taktfrequenz ist "
357
358#: utils/cpufreq-info.c:296
359#, c-format
360msgid " (asserted by call to hardware)"
361msgstr " (verifiziert durch Nachfrage bei der Hardware)"
362
363#: utils/cpufreq-info.c:304
364#, c-format
365msgid " cpufreq stats: "
366msgstr " Statistik:"
367
368#: utils/cpufreq-info.c:472
369#, fuzzy, c-format
370msgid "Usage: cpupower freqinfo [options]\n"
371msgstr "Aufruf: cpufreq-info [Optionen]\n"
372
373#: utils/cpufreq-info.c:473 utils/cpufreq-set.c:26 utils/cpupower-set.c:23
374#: utils/cpupower-info.c:22 utils/cpuidle-info.c:148
375#, c-format
376msgid "Options:\n"
377msgstr "Optionen:\n"
378
379#: utils/cpufreq-info.c:474
380#, fuzzy, c-format
381msgid " -e, --debug Prints out debug information [default]\n"
382msgstr ""
383" -e, --debug Erzeugt detaillierte Informationen, hilfreich\n"
384" zum Aufspüren von Fehlern\n"
385
386#: utils/cpufreq-info.c:475
387#, c-format
388msgid ""
389" -f, --freq Get frequency the CPU currently runs at, according\n"
390" to the cpufreq core *\n"
391msgstr ""
392" -f, --freq Findet die momentane CPU-Taktfrquenz heraus (nach\n"
393" Meinung des Betriebssystems) *\n"
394
395#: utils/cpufreq-info.c:477
396#, c-format
397msgid ""
398" -w, --hwfreq Get frequency the CPU currently runs at, by reading\n"
399" it from hardware (only available to root) *\n"
400msgstr ""
401" -w, --hwfreq Findet die momentane CPU-Taktfrequenz heraus\n"
402" (verifiziert durch Nachfrage bei der Hardware)\n"
403" [nur der Administrator kann dies tun] *\n"
404
405#: utils/cpufreq-info.c:479
406#, c-format
407msgid ""
408" -l, --hwlimits Determine the minimum and maximum CPU frequency "
409"allowed *\n"
410msgstr ""
411" -l, --hwlimits Findet die minimale und maximale Taktfrequenz heraus "
412"*\n"
413
414#: utils/cpufreq-info.c:480
415#, c-format
416msgid " -d, --driver Determines the used cpufreq kernel driver *\n"
417msgstr " -d, --driver Findet den momentanen Treiber heraus *\n"
418
419#: utils/cpufreq-info.c:481
420#, c-format
421msgid " -p, --policy Gets the currently used cpufreq policy *\n"
422msgstr " -p, --policy Findet die momentane Taktik heraus *\n"
423
424#: utils/cpufreq-info.c:482
425#, c-format
426msgid " -g, --governors Determines available cpufreq governors *\n"
427msgstr " -g, --governors Erzeugt eine Liste mit verfügbaren Reglern *\n"
428
429#: utils/cpufreq-info.c:483
430#, c-format
431msgid ""
432" -r, --related-cpus Determines which CPUs run at the same hardware "
433"frequency *\n"
434msgstr ""
435" -r, --related-cpus Findet heraus, welche CPUs mit derselben "
436"physikalischen\n"
437" Taktfrequenz laufen *\n"
438
439#: utils/cpufreq-info.c:484
440#, c-format
441msgid ""
442" -a, --affected-cpus Determines which CPUs need to have their frequency\n"
443" coordinated by software *\n"
444msgstr ""
445" -a, --affected-cpus Findet heraus, von welchen CPUs die Taktfrequenz "
446"durch\n"
447" Software koordiniert werden muss *\n"
448
449#: utils/cpufreq-info.c:486
450#, c-format
451msgid " -s, --stats Shows cpufreq statistics if available\n"
452msgstr ""
453" -s, --stats Zeigt, sofern möglich, Statistiken über cpufreq an.\n"
454
455#: utils/cpufreq-info.c:487
456#, c-format
457msgid ""
458" -y, --latency Determines the maximum latency on CPU frequency "
459"changes *\n"
460msgstr ""
461" -y, --latency Findet die maximale Dauer eines Taktfrequenzwechsels "
462"heraus *\n"
463
464#: utils/cpufreq-info.c:488
465#, c-format
466msgid " -b, --boost Checks for turbo or boost modes *\n"
467msgstr ""
468
469#: utils/cpufreq-info.c:489
470#, c-format
471msgid ""
472" -o, --proc Prints out information like provided by the /proc/"
473"cpufreq\n"
474" interface in 2.4. and early 2.6. kernels\n"
475msgstr ""
476" -o, --proc Erzeugt Informationen in einem ähnlichem Format zu "
477"dem\n"
478" der /proc/cpufreq-Datei in 2.4. und frühen 2.6.\n"
479" Kernel-Versionen\n"
480
481#: utils/cpufreq-info.c:491
482#, c-format
483msgid ""
484" -m, --human human-readable output for the -f, -w, -s and -y "
485"parameters\n"
486msgstr ""
487" -m, --human Formatiert Taktfrequenz- und Zeitdauerangaben in "
488"besser\n"
489" lesbarer Form (MHz, GHz; us, ms)\n"
490
491#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152
492#, c-format
493msgid " -h, --help Prints out this screen\n"
494msgstr " -h, --help Gibt diese Kurzübersicht aus\n"
495
496#: utils/cpufreq-info.c:495
497#, c-format
498msgid ""
499"If no argument or only the -c, --cpu parameter is given, debug output about\n"
500"cpufreq is printed which is useful e.g. for reporting bugs.\n"
501msgstr ""
502"Sofern kein anderer Parameter als '-c, --cpu' angegeben wird, liefert "
503"dieses\n"
504"Programm Informationen, die z.B. zum Berichten von Fehlern nützlich sind.\n"
505
506#: utils/cpufreq-info.c:497
507#, c-format
508msgid ""
509"For the arguments marked with *, omitting the -c or --cpu argument is\n"
510"equivalent to setting it to zero\n"
511msgstr ""
512"Bei den mit * markierten Parametern wird '--cpu 0' angenommen, soweit nicht\n"
513"mittels -c oder --cpu etwas anderes angegeben wird\n"
514
515#: utils/cpufreq-info.c:580
516#, c-format
517msgid ""
518"The argument passed to this tool can't be combined with passing a --cpu "
519"argument\n"
520msgstr "Diese Option kann nicht mit der --cpu-Option kombiniert werden\n"
521
522#: utils/cpufreq-info.c:596
523#, c-format
524msgid ""
525"You can't specify more than one --cpu parameter and/or\n"
526"more than one output-specific argument\n"
527msgstr ""
528"Man kann nicht mehr als einen --cpu-Parameter und/oder mehr als einen\n"
529"informationsspezifischen Parameter gleichzeitig angeben\n"
530
531#: utils/cpufreq-info.c:600 utils/cpufreq-set.c:82 utils/cpupower-set.c:42
532#: utils/cpupower-info.c:42 utils/cpuidle-info.c:213
533#, c-format
534msgid "invalid or unknown argument\n"
535msgstr "unbekannter oder falscher Parameter\n"
536
537#: utils/cpufreq-info.c:617
538#, c-format
539msgid "couldn't analyze CPU %d as it doesn't seem to be present\n"
540msgstr ""
541"Konnte nicht die CPU %d analysieren, da sie (scheinbar?) nicht existiert.\n"
542
543#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142
544#, c-format
545msgid "analyzing CPU %d:\n"
546msgstr "analysiere CPU %d:\n"
547
548#: utils/cpufreq-set.c:25
549#, fuzzy, c-format
550msgid "Usage: cpupower frequency-set [options]\n"
551msgstr "Aufruf: cpufreq-set [Optionen]\n"
552
553#: utils/cpufreq-set.c:27
554#, c-format
555msgid ""
556" -d FREQ, --min FREQ new minimum CPU frequency the governor may "
557"select\n"
558msgstr ""
559" -d FREQ, --min FREQ neue minimale Taktfrequenz, die der Regler\n"
560" auswählen darf\n"
561
562#: utils/cpufreq-set.c:28
563#, c-format
564msgid ""
565" -u FREQ, --max FREQ new maximum CPU frequency the governor may "
566"select\n"
567msgstr ""
568" -u FREQ, --max FREQ neue maximale Taktfrequenz, die der Regler\n"
569" auswählen darf\n"
570
571#: utils/cpufreq-set.c:29
572#, c-format
573msgid " -g GOV, --governor GOV new cpufreq governor\n"
574msgstr " -g GOV, --governors GOV wechsle zu Regler GOV\n"
575
576#: utils/cpufreq-set.c:30
577#, c-format
578msgid ""
579" -f FREQ, --freq FREQ specific frequency to be set. Requires userspace\n"
580" governor to be available and loaded\n"
581msgstr ""
582" -f FREQ, --freq FREQ setze exakte Taktfrequenz. Benötigt den Regler\n"
583" 'userspace'.\n"
584
585#: utils/cpufreq-set.c:32
586#, c-format
587msgid " -r, --related Switches all hardware-related CPUs\n"
588msgstr ""
589" -r, --related Setze Werte für alle CPUs, deren Taktfrequenz\n"
590" hardwarebedingt identisch ist.\n"
591
592#: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27
593#, c-format
594msgid " -h, --help Prints out this screen\n"
595msgstr " -h, --help Gibt diese Kurzübersicht aus\n"
596
597#: utils/cpufreq-set.c:35
598#, fuzzy, c-format
599msgid ""
600"Notes:\n"
601"1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n"
602msgstr ""
603"Bei den mit * markierten Parametern wird '--cpu 0' angenommen, soweit nicht\n"
604"mittels -c oder --cpu etwas anderes angegeben wird\n"
605
606#: utils/cpufreq-set.c:37
607#, fuzzy, c-format
608msgid ""
609"2. The -f FREQ, --freq FREQ parameter cannot be combined with any other "
610"parameter\n"
611" except the -c CPU, --cpu CPU parameter\n"
612"3. FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz\n"
613" by postfixing the value with the wanted unit name, without any space\n"
614" (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
615msgstr ""
616"Hinweise:\n"
617"1. Sofern kein -c oder --cpu-Parameter angegeben ist, wird '--cpu 0'\n"
618" angenommen\n"
619"2. Der Parameter -f bzw. --freq kann mit keinem anderen als dem Parameter\n"
620" -c bzw. --cpu kombiniert werden\n"
621"3. FREQuenzen können in Hz, kHz (Standard), MHz, GHz oder THz eingegeben\n"
622" werden, indem der Wert und unmittelbar anschließend (ohne Leerzeichen!)\n"
623" die Einheit angegeben werden. (Bsp: 1GHz )\n"
624" (FREQuenz in kHz =^ MHz * 1000 =^ GHz * 1000000).\n"
625
626#: utils/cpufreq-set.c:57
627#, c-format
628msgid ""
629"Error setting new values. Common errors:\n"
630"- Do you have proper administration rights? (super-user?)\n"
631"- Is the governor you requested available and modprobed?\n"
632"- Trying to set an invalid policy?\n"
633"- Trying to set a specific frequency, but userspace governor is not "
634"available,\n"
635" for example because of hardware which cannot be set to a specific "
636"frequency\n"
637" or because the userspace governor isn't loaded?\n"
638msgstr ""
639"Beim Einstellen ist ein Fehler aufgetreten. Typische Fehlerquellen sind:\n"
640"- nicht ausreichende Rechte (Administrator)\n"
641"- der Regler ist nicht verfügbar bzw. nicht geladen\n"
642"- die angegebene Taktik ist inkorrekt\n"
643"- eine spezifische Frequenz wurde angegeben, aber der Regler 'userspace'\n"
644" kann entweder hardwarebedingt nicht genutzt werden oder ist nicht geladen\n"
645
646#: utils/cpufreq-set.c:170
647#, c-format
648msgid "wrong, unknown or unhandled CPU?\n"
649msgstr "unbekannte oder nicht regelbare CPU\n"
650
651#: utils/cpufreq-set.c:302
652#, c-format
653msgid ""
654"the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n"
655"-g/--governor parameters\n"
656msgstr ""
657"Der -f bzw. --freq-Parameter kann nicht mit den Parametern -d/--min, -u/--"
658"max\n"
659"oder -g/--governor kombiniert werden\n"
660
661#: utils/cpufreq-set.c:308
662#, c-format
663msgid ""
664"At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n"
665"-g/--governor must be passed\n"
666msgstr ""
667"Es muss mindestens ein Parameter aus -f/--freq, -d/--min, -u/--max oder\n"
668"-g/--governor angegeben werden.\n"
669
670#: utils/cpufreq-set.c:347
671#, c-format
672msgid "Setting cpu: %d\n"
673msgstr ""
674
675#: utils/cpupower-set.c:22
676#, c-format
677msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n"
678msgstr ""
679
680#: utils/cpupower-set.c:24
681#, c-format
682msgid ""
683" -b, --perf-bias [VAL] Sets CPU's power vs performance policy on some\n"
684" Intel models [0-15], see manpage for details\n"
685msgstr ""
686
687#: utils/cpupower-set.c:26
688#, c-format
689msgid ""
690" -m, --sched-mc [VAL] Sets the kernel's multi core scheduler policy.\n"
691msgstr ""
692
693#: utils/cpupower-set.c:27
694#, c-format
695msgid ""
696" -s, --sched-smt [VAL] Sets the kernel's thread sibling scheduler "
697"policy.\n"
698msgstr ""
699
700#: utils/cpupower-set.c:80
701#, c-format
702msgid "--perf-bias param out of range [0-%d]\n"
703msgstr ""
704
705#: utils/cpupower-set.c:91
706#, c-format
707msgid "--sched-mc param out of range [0-%d]\n"
708msgstr ""
709
710#: utils/cpupower-set.c:102
711#, c-format
712msgid "--sched-smt param out of range [0-%d]\n"
713msgstr ""
714
715#: utils/cpupower-set.c:121
716#, c-format
717msgid "Error setting sched-mc %s\n"
718msgstr ""
719
720#: utils/cpupower-set.c:127
721#, c-format
722msgid "Error setting sched-smt %s\n"
723msgstr ""
724
725#: utils/cpupower-set.c:146
726#, c-format
727msgid "Error setting perf-bias value on CPU %d\n"
728msgstr ""
729
730#: utils/cpupower-info.c:21
731#, c-format
732msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n"
733msgstr ""
734
735#: utils/cpupower-info.c:23
736#, c-format
737msgid ""
738" -b, --perf-bias Gets CPU's power vs performance policy on some\n"
739" Intel models [0-15], see manpage for details\n"
740msgstr ""
741
742#: utils/cpupower-info.c:25
743#, fuzzy, c-format
744msgid " -m, --sched-mc Gets the kernel's multi core scheduler policy.\n"
745msgstr " -p, --policy Findet die momentane Taktik heraus *\n"
746
747#: utils/cpupower-info.c:26
748#, c-format
749msgid ""
750" -s, --sched-smt Gets the kernel's thread sibling scheduler policy.\n"
751msgstr ""
752
753#: utils/cpupower-info.c:28
754#, c-format
755msgid ""
756"\n"
757"Passing no option will show all info, by default only on core 0\n"
758msgstr ""
759
760#: utils/cpupower-info.c:102
761#, c-format
762msgid "System's multi core scheduler setting: "
763msgstr ""
764
765#. if sysfs file is missing it's: errno == ENOENT
766#: utils/cpupower-info.c:105 utils/cpupower-info.c:114
767#, c-format
768msgid "not supported\n"
769msgstr ""
770
771#: utils/cpupower-info.c:111
772#, c-format
773msgid "System's thread sibling scheduler setting: "
774msgstr ""
775
776#: utils/cpupower-info.c:126
777#, c-format
778msgid "Intel's performance bias setting needs root privileges\n"
779msgstr ""
780
781#: utils/cpupower-info.c:128
782#, c-format
783msgid "System does not support Intel's performance bias setting\n"
784msgstr ""
785
786#: utils/cpupower-info.c:147
787#, c-format
788msgid "Could not read perf-bias value\n"
789msgstr ""
790
791#: utils/cpupower-info.c:150
792#, c-format
793msgid "perf-bias: %d\n"
794msgstr ""
795
796#: utils/cpuidle-info.c:28
797#, fuzzy, c-format
798msgid "Analyzing CPU %d:\n"
799msgstr "analysiere CPU %d:\n"
800
801#: utils/cpuidle-info.c:32
802#, c-format
803msgid "CPU %u: No idle states\n"
804msgstr ""
805
806#: utils/cpuidle-info.c:36
807#, c-format
808msgid "CPU %u: Can't read idle state info\n"
809msgstr ""
810
811#: utils/cpuidle-info.c:41
812#, c-format
813msgid "Could not determine max idle state %u\n"
814msgstr ""
815
816#: utils/cpuidle-info.c:46
817#, c-format
818msgid "Number of idle states: %d\n"
819msgstr ""
820
821#: utils/cpuidle-info.c:48
822#, fuzzy, c-format
823msgid "Available idle states:"
824msgstr " mögliche Taktfrequenzen: "
825
826#: utils/cpuidle-info.c:71
827#, c-format
828msgid "Flags/Description: %s\n"
829msgstr ""
830
831#: utils/cpuidle-info.c:74
832#, c-format
833msgid "Latency: %lu\n"
834msgstr ""
835
836#: utils/cpuidle-info.c:76
837#, c-format
838msgid "Usage: %lu\n"
839msgstr ""
840
841#: utils/cpuidle-info.c:78
842#, c-format
843msgid "Duration: %llu\n"
844msgstr ""
845
846#: utils/cpuidle-info.c:90
847#, c-format
848msgid "Could not determine cpuidle driver\n"
849msgstr ""
850
851#: utils/cpuidle-info.c:94
852#, fuzzy, c-format
853msgid "CPUidle driver: %s\n"
854msgstr " Treiber: %s\n"
855
856#: utils/cpuidle-info.c:99
857#, c-format
858msgid "Could not determine cpuidle governor\n"
859msgstr ""
860
861#: utils/cpuidle-info.c:103
862#, c-format
863msgid "CPUidle governor: %s\n"
864msgstr ""
865
866#: utils/cpuidle-info.c:122
867#, c-format
868msgid "CPU %u: Can't read C-state info\n"
869msgstr ""
870
871#. printf("Cstates: %d\n", cstates);
872#: utils/cpuidle-info.c:127
873#, c-format
874msgid "active state: C0\n"
875msgstr ""
876
877#: utils/cpuidle-info.c:128
878#, c-format
879msgid "max_cstate: C%u\n"
880msgstr ""
881
882#: utils/cpuidle-info.c:129
883#, fuzzy, c-format
884msgid "maximum allowed latency: %lu usec\n"
885msgstr " Maximale Dauer eines Taktfrequenzwechsels: "
886
887#: utils/cpuidle-info.c:130
888#, c-format
889msgid "states:\t\n"
890msgstr ""
891
892#: utils/cpuidle-info.c:132
893#, c-format
894msgid " C%d: type[C%d] "
895msgstr ""
896
897#: utils/cpuidle-info.c:134
898#, c-format
899msgid "promotion[--] demotion[--] "
900msgstr ""
901
902#: utils/cpuidle-info.c:135
903#, c-format
904msgid "latency[%03lu] "
905msgstr ""
906
907#: utils/cpuidle-info.c:137
908#, c-format
909msgid "usage[%08lu] "
910msgstr ""
911
912#: utils/cpuidle-info.c:139
913#, c-format
914msgid "duration[%020Lu] \n"
915msgstr ""
916
917#: utils/cpuidle-info.c:147
918#, fuzzy, c-format
919msgid "Usage: cpupower idleinfo [options]\n"
920msgstr "Aufruf: cpufreq-info [Optionen]\n"
921
922#: utils/cpuidle-info.c:149
923#, fuzzy, c-format
924msgid " -s, --silent Only show general C-state information\n"
925msgstr ""
926" -e, --debug Erzeugt detaillierte Informationen, hilfreich\n"
927" zum Aufspüren von Fehlern\n"
928
929#: utils/cpuidle-info.c:150
930#, fuzzy, c-format
931msgid ""
932" -o, --proc Prints out information like provided by the /proc/"
933"acpi/processor/*/power\n"
934" interface in older kernels\n"
935msgstr ""
936" -o, --proc Erzeugt Informationen in einem ähnlichem Format zu "
937"dem\n"
938" der /proc/cpufreq-Datei in 2.4. und frühen 2.6.\n"
939" Kernel-Versionen\n"
940
941#: utils/cpuidle-info.c:209
942#, fuzzy, c-format
943msgid "You can't specify more than one output-specific argument\n"
944msgstr ""
945"Man kann nicht mehr als einen --cpu-Parameter und/oder mehr als einen\n"
946"informationsspezifischen Parameter gleichzeitig angeben\n"
947
948#~ msgid ""
949#~ " -c CPU, --cpu CPU CPU number which information shall be determined "
950#~ "about\n"
951#~ msgstr ""
952#~ " -c CPU, --cpu CPU Nummer der CPU, über die Informationen "
953#~ "herausgefunden werden sollen\n"
954
955#~ msgid ""
956#~ " -c CPU, --cpu CPU number of CPU where cpufreq settings shall be "
957#~ "modified\n"
958#~ msgstr ""
959#~ " -c CPU, --cpu CPU Nummer der CPU, deren Taktfrequenz-"
960#~ "Einstellung\n"
961#~ " werden soll\n"
diff --git a/tools/power/cpupower/po/fr.po b/tools/power/cpupower/po/fr.po
new file mode 100644
index 000000000000..245ad20a9bf9
--- /dev/null
+++ b/tools/power/cpupower/po/fr.po
@@ -0,0 +1,947 @@
1# French translations for cpufrequtils package
2# Copyright (C) 2004 THE PACKAGE'S COPYRIGHT HOLDER
3# This file is distributed under the same license as the cpufrequtils package.
4# Ducrot Bruno <ducrot@poupinou.org>, 2004.
5#
6#, fuzzy
7msgid ""
8msgstr ""
9"Project-Id-Version: cpufrequtils 0.1-pre2\n"
10"Report-Msgid-Bugs-To: \n"
11"POT-Creation-Date: 2011-03-08 17:03+0100\n"
12"PO-Revision-Date: 2004-11-17 15:53+1000\n"
13"Last-Translator: Bruno Ducrot <ducrot@poupinou.org>\n"
14"Language-Team: NONE\n"
15"Language: \n"
16"MIME-Version: 1.0\n"
17"Content-Type: text/plain; charset=ISO-8859-1\n"
18"Content-Transfer-Encoding: 8bit\n"
19
20#: utils/idle_monitor/nhm_idle.c:36
21msgid "Processor Core C3"
22msgstr ""
23
24#: utils/idle_monitor/nhm_idle.c:43
25msgid "Processor Core C6"
26msgstr ""
27
28#: utils/idle_monitor/nhm_idle.c:51
29msgid "Processor Package C3"
30msgstr ""
31
32#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70
33msgid "Processor Package C6"
34msgstr ""
35
36#: utils/idle_monitor/snb_idle.c:33
37msgid "Processor Core C7"
38msgstr ""
39
40#: utils/idle_monitor/snb_idle.c:40
41msgid "Processor Package C2"
42msgstr ""
43
44#: utils/idle_monitor/snb_idle.c:47
45msgid "Processor Package C7"
46msgstr ""
47
48#: utils/idle_monitor/amd_fam14h_idle.c:56
49msgid "Package in sleep state (PC1 or deeper)"
50msgstr ""
51
52#: utils/idle_monitor/amd_fam14h_idle.c:63
53msgid "Processor Package C1"
54msgstr ""
55
56#: utils/idle_monitor/amd_fam14h_idle.c:77
57msgid "North Bridge P1 boolean counter (returns 0 or 1)"
58msgstr ""
59
60#: utils/idle_monitor/mperf_monitor.c:35
61msgid "Processor Core not idle"
62msgstr ""
63
64#: utils/idle_monitor/mperf_monitor.c:42
65msgid "Processor Core in an idle state"
66msgstr ""
67
68#: utils/idle_monitor/mperf_monitor.c:50
69msgid "Average Frequency (including boost) in MHz"
70msgstr ""
71
72#: utils/idle_monitor/cpupower-monitor.c:66
73#, c-format
74msgid ""
75"cpupower monitor: [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
76"interval_sec | -c command ...]\n"
77msgstr ""
78
79#: utils/idle_monitor/cpupower-monitor.c:69
80#, c-format
81msgid ""
82"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
83"interval_sec | -c command ...]\n"
84msgstr ""
85
86#: utils/idle_monitor/cpupower-monitor.c:71
87#, c-format
88msgid "\t -v: be more verbose\n"
89msgstr ""
90
91#: utils/idle_monitor/cpupower-monitor.c:73
92#, c-format
93msgid "\t -h: print this help\n"
94msgstr ""
95
96#: utils/idle_monitor/cpupower-monitor.c:74
97#, c-format
98msgid "\t -i: time intervall to measure for in seconds (default 1)\n"
99msgstr ""
100
101#: utils/idle_monitor/cpupower-monitor.c:75
102#, c-format
103msgid "\t -t: show CPU topology/hierarchy\n"
104msgstr ""
105
106#: utils/idle_monitor/cpupower-monitor.c:76
107#, c-format
108msgid "\t -l: list available CPU sleep monitors (for use with -m)\n"
109msgstr ""
110
111#: utils/idle_monitor/cpupower-monitor.c:77
112#, c-format
113msgid "\t -m: show specific CPU sleep monitors only (in same order)\n"
114msgstr ""
115
116#: utils/idle_monitor/cpupower-monitor.c:79
117#, c-format
118msgid ""
119"only one of: -t, -l, -m are allowed\n"
120"If none of them is passed,"
121msgstr ""
122
123#: utils/idle_monitor/cpupower-monitor.c:80
124#, c-format
125msgid " all supported monitors are shown\n"
126msgstr ""
127
128#: utils/idle_monitor/cpupower-monitor.c:197
129#, c-format
130msgid "Monitor %s, Counter %s has no count function. Implementation error\n"
131msgstr ""
132
133#: utils/idle_monitor/cpupower-monitor.c:207
134#, c-format
135msgid " *is offline\n"
136msgstr ""
137
138#: utils/idle_monitor/cpupower-monitor.c:236
139#, c-format
140msgid "%s: max monitor name length (%d) exceeded\n"
141msgstr ""
142
143#: utils/idle_monitor/cpupower-monitor.c:250
144#, c-format
145msgid "No matching monitor found in %s, try -l option\n"
146msgstr ""
147
148#: utils/idle_monitor/cpupower-monitor.c:266
149#, c-format
150msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n"
151msgstr ""
152
153#: utils/idle_monitor/cpupower-monitor.c:319
154#, c-format
155msgid "%s took %.5f seconds and exited with status %d\n"
156msgstr ""
157
158#: utils/idle_monitor/cpupower-monitor.c:406
159#, c-format
160msgid "Cannot read number of available processors\n"
161msgstr ""
162
163#: utils/idle_monitor/cpupower-monitor.c:417
164#, c-format
165msgid "Available monitor %s needs root access\n"
166msgstr ""
167
168#: utils/idle_monitor/cpupower-monitor.c:428
169#, c-format
170msgid "No HW Cstate monitors found\n"
171msgstr ""
172
173#: utils/cpupower.c:78
174#, c-format
175msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n"
176msgstr ""
177
178#: utils/cpupower.c:79
179#, c-format
180msgid "cpupower --version\n"
181msgstr ""
182
183#: utils/cpupower.c:80
184#, c-format
185msgid "Supported subcommands are:\n"
186msgstr ""
187
188#: utils/cpupower.c:83
189#, c-format
190msgid ""
191"\n"
192"Some subcommands can make use of the -c cpulist option.\n"
193msgstr ""
194
195#: utils/cpupower.c:84
196#, c-format
197msgid "Look at the general cpupower manpage how to use it\n"
198msgstr ""
199
200#: utils/cpupower.c:85
201#, c-format
202msgid "and read up the subcommand's manpage whether it is supported.\n"
203msgstr ""
204
205#: utils/cpupower.c:86
206#, c-format
207msgid ""
208"\n"
209"Use cpupower help subcommand for getting help for above subcommands.\n"
210msgstr ""
211
212#: utils/cpupower.c:91
213#, c-format
214msgid "Report errors and bugs to %s, please.\n"
215msgstr "Veuillez rapportez les erreurs et les bogues à %s, s'il vous plait.\n"
216
217#: utils/cpupower.c:114
218#, c-format
219msgid "Error parsing cpu list\n"
220msgstr ""
221
222#: utils/cpupower.c:172
223#, c-format
224msgid "Subcommand %s needs root privileges\n"
225msgstr ""
226
227#: utils/cpufreq-info.c:31
228#, c-format
229msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n"
230msgstr "Détermination du nombre de CPUs (%s : %s) impossible. Assume 1\n"
231
232#: utils/cpufreq-info.c:63
233#, c-format
234msgid ""
235" minimum CPU frequency - maximum CPU frequency - governor\n"
236msgstr ""
237" Fréquence CPU minimale - Fréquence CPU maximale - régulateur\n"
238
239#: utils/cpufreq-info.c:151
240#, c-format
241msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n"
242msgstr ""
243
244#. P state changes via MSR are identified via cpuid 80000007
245#. on Intel and AMD, but we assume boost capable machines can do that
246#. if (cpuid_eax(0x80000000) >= 0x80000007
247#. && (cpuid_edx(0x80000007) & (1 << 7)))
248#.
249#: utils/cpufreq-info.c:161
250#, c-format
251msgid " boost state support: \n"
252msgstr ""
253
254#: utils/cpufreq-info.c:163
255#, c-format
256msgid " Supported: %s\n"
257msgstr ""
258
259#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
260msgid "yes"
261msgstr ""
262
263#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
264msgid "no"
265msgstr ""
266
267#: utils/cpufreq-info.c:164
268#, fuzzy, c-format
269msgid " Active: %s\n"
270msgstr " pilote : %s\n"
271
272#: utils/cpufreq-info.c:177
273#, c-format
274msgid " Boost States: %d\n"
275msgstr ""
276
277#: utils/cpufreq-info.c:178
278#, c-format
279msgid " Total States: %d\n"
280msgstr ""
281
282#: utils/cpufreq-info.c:181
283#, c-format
284msgid " Pstate-Pb%d: %luMHz (boost state)\n"
285msgstr ""
286
287#: utils/cpufreq-info.c:184
288#, c-format
289msgid " Pstate-P%d: %luMHz\n"
290msgstr ""
291
292#: utils/cpufreq-info.c:211
293#, c-format
294msgid " no or unknown cpufreq driver is active on this CPU\n"
295msgstr " pas de pilotes cpufreq reconnu pour ce CPU\n"
296
297#: utils/cpufreq-info.c:213
298#, c-format
299msgid " driver: %s\n"
300msgstr " pilote : %s\n"
301
302#: utils/cpufreq-info.c:219
303#, fuzzy, c-format
304msgid " CPUs which run at the same hardware frequency: "
305msgstr " CPUs qui doivent changer de fréquences en même temps : "
306
307#: utils/cpufreq-info.c:230
308#, fuzzy, c-format
309msgid " CPUs which need to have their frequency coordinated by software: "
310msgstr " CPUs qui doivent changer de fréquences en même temps : "
311
312#: utils/cpufreq-info.c:241
313#, c-format
314msgid " maximum transition latency: "
315msgstr ""
316
317#: utils/cpufreq-info.c:247
318#, c-format
319msgid " hardware limits: "
320msgstr " limitation matérielle : "
321
322#: utils/cpufreq-info.c:256
323#, c-format
324msgid " available frequency steps: "
325msgstr " plage de fréquence : "
326
327#: utils/cpufreq-info.c:269
328#, c-format
329msgid " available cpufreq governors: "
330msgstr " régulateurs disponibles : "
331
332#: utils/cpufreq-info.c:280
333#, c-format
334msgid " current policy: frequency should be within "
335msgstr " tactique actuelle : la fréquence doit être comprise entre "
336
337#: utils/cpufreq-info.c:282
338#, c-format
339msgid " and "
340msgstr " et "
341
342#: utils/cpufreq-info.c:286
343#, c-format
344msgid ""
345"The governor \"%s\" may decide which speed to use\n"
346" within this range.\n"
347msgstr ""
348"Le régulateur \"%s\" est libre de choisir la vitesse\n"
349" dans cette plage de fréquences.\n"
350
351#: utils/cpufreq-info.c:293
352#, c-format
353msgid " current CPU frequency is "
354msgstr " la fréquence actuelle de ce CPU est "
355
356#: utils/cpufreq-info.c:296
357#, c-format
358msgid " (asserted by call to hardware)"
359msgstr " (vérifié par un appel direct du matériel)"
360
361#: utils/cpufreq-info.c:304
362#, c-format
363msgid " cpufreq stats: "
364msgstr " des statistique concernant cpufreq:"
365
366#: utils/cpufreq-info.c:472
367#, fuzzy, c-format
368msgid "Usage: cpupower freqinfo [options]\n"
369msgstr "Usage : cpufreq-info [options]\n"
370
371#: utils/cpufreq-info.c:473 utils/cpufreq-set.c:26 utils/cpupower-set.c:23
372#: utils/cpupower-info.c:22 utils/cpuidle-info.c:148
373#, c-format
374msgid "Options:\n"
375msgstr "Options :\n"
376
377#: utils/cpufreq-info.c:474
378#, fuzzy, c-format
379msgid " -e, --debug Prints out debug information [default]\n"
380msgstr " -e, --debug Afficher les informations de déboguage\n"
381
382#: utils/cpufreq-info.c:475
383#, c-format
384msgid ""
385" -f, --freq Get frequency the CPU currently runs at, according\n"
386" to the cpufreq core *\n"
387msgstr ""
388" -f, --freq Obtenir la fréquence actuelle du CPU selon le point\n"
389" de vue du coeur du système de cpufreq *\n"
390
391#: utils/cpufreq-info.c:477
392#, c-format
393msgid ""
394" -w, --hwfreq Get frequency the CPU currently runs at, by reading\n"
395" it from hardware (only available to root) *\n"
396msgstr ""
397" -w, --hwfreq Obtenir la fréquence actuelle du CPU directement par\n"
398" le matériel (doit être root) *\n"
399
400#: utils/cpufreq-info.c:479
401#, c-format
402msgid ""
403" -l, --hwlimits Determine the minimum and maximum CPU frequency "
404"allowed *\n"
405msgstr ""
406" -l, --hwlimits Affiche les fréquences minimales et maximales du CPU "
407"*\n"
408
409#: utils/cpufreq-info.c:480
410#, c-format
411msgid " -d, --driver Determines the used cpufreq kernel driver *\n"
412msgstr " -d, --driver Affiche le pilote cpufreq utilisé *\n"
413
414#: utils/cpufreq-info.c:481
415#, c-format
416msgid " -p, --policy Gets the currently used cpufreq policy *\n"
417msgstr " -p, --policy Affiche la tactique actuelle de cpufreq *\n"
418
419#: utils/cpufreq-info.c:482
420#, c-format
421msgid " -g, --governors Determines available cpufreq governors *\n"
422msgstr ""
423" -g, --governors Affiche les régulateurs disponibles de cpufreq *\n"
424
425#: utils/cpufreq-info.c:483
426#, fuzzy, c-format
427msgid ""
428" -r, --related-cpus Determines which CPUs run at the same hardware "
429"frequency *\n"
430msgstr ""
431" -a, --affected-cpus Affiche quels sont les CPUs qui doivent changer de\n"
432" fréquences en même temps *\n"
433
434#: utils/cpufreq-info.c:484
435#, fuzzy, c-format
436msgid ""
437" -a, --affected-cpus Determines which CPUs need to have their frequency\n"
438" coordinated by software *\n"
439msgstr ""
440" -a, --affected-cpus Affiche quels sont les CPUs qui doivent changer de\n"
441" fréquences en même temps *\n"
442
443#: utils/cpufreq-info.c:486
444#, c-format
445msgid " -s, --stats Shows cpufreq statistics if available\n"
446msgstr ""
447" -s, --stats Indique des statistiques concernant cpufreq, si\n"
448" disponibles\n"
449
450#: utils/cpufreq-info.c:487
451#, fuzzy, c-format
452msgid ""
453" -y, --latency Determines the maximum latency on CPU frequency "
454"changes *\n"
455msgstr ""
456" -l, --hwlimits Affiche les fréquences minimales et maximales du CPU "
457"*\n"
458
459#: utils/cpufreq-info.c:488
460#, c-format
461msgid " -b, --boost Checks for turbo or boost modes *\n"
462msgstr ""
463
464#: utils/cpufreq-info.c:489
465#, c-format
466msgid ""
467" -o, --proc Prints out information like provided by the /proc/"
468"cpufreq\n"
469" interface in 2.4. and early 2.6. kernels\n"
470msgstr ""
471" -o, --proc Affiche les informations en utilisant l'interface\n"
472" fournie par /proc/cpufreq, présente dans les "
473"versions\n"
474" 2.4 et les anciennes versions 2.6 du noyau\n"
475
476#: utils/cpufreq-info.c:491
477#, fuzzy, c-format
478msgid ""
479" -m, --human human-readable output for the -f, -w, -s and -y "
480"parameters\n"
481msgstr ""
482" -m, --human affiche dans un format lisible pour un humain\n"
483" pour les options -f, -w et -s (MHz, GHz)\n"
484
485#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152
486#, c-format
487msgid " -h, --help Prints out this screen\n"
488msgstr " -h, --help affiche l'aide-mémoire\n"
489
490#: utils/cpufreq-info.c:495
491#, c-format
492msgid ""
493"If no argument or only the -c, --cpu parameter is given, debug output about\n"
494"cpufreq is printed which is useful e.g. for reporting bugs.\n"
495msgstr ""
496"Par défaut, les informations de déboguage seront affichées si aucun\n"
497"argument, ou bien si seulement l'argument -c (--cpu) est donné, afin de\n"
498"faciliter les rapports de bogues par exemple\n"
499
500#: utils/cpufreq-info.c:497
501#, c-format
502msgid ""
503"For the arguments marked with *, omitting the -c or --cpu argument is\n"
504"equivalent to setting it to zero\n"
505msgstr "Les arguments avec un * utiliseront le CPU 0 si -c (--cpu) est omis\n"
506
507#: utils/cpufreq-info.c:580
508#, c-format
509msgid ""
510"The argument passed to this tool can't be combined with passing a --cpu "
511"argument\n"
512msgstr "Cette option est incompatible avec --cpu\n"
513
514#: utils/cpufreq-info.c:596
515#, c-format
516msgid ""
517"You can't specify more than one --cpu parameter and/or\n"
518"more than one output-specific argument\n"
519msgstr ""
520"On ne peut indiquer plus d'un paramètre --cpu, tout comme l'on ne peut\n"
521"spécifier plus d'un argument de formatage\n"
522
523#: utils/cpufreq-info.c:600 utils/cpufreq-set.c:82 utils/cpupower-set.c:42
524#: utils/cpupower-info.c:42 utils/cpuidle-info.c:213
525#, c-format
526msgid "invalid or unknown argument\n"
527msgstr "option invalide\n"
528
529#: utils/cpufreq-info.c:617
530#, c-format
531msgid "couldn't analyze CPU %d as it doesn't seem to be present\n"
532msgstr "analyse du CPU %d impossible puisqu'il ne semble pas être présent\n"
533
534#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142
535#, c-format
536msgid "analyzing CPU %d:\n"
537msgstr "analyse du CPU %d :\n"
538
539#: utils/cpufreq-set.c:25
540#, fuzzy, c-format
541msgid "Usage: cpupower frequency-set [options]\n"
542msgstr "Usage : cpufreq-set [options]\n"
543
544#: utils/cpufreq-set.c:27
545#, c-format
546msgid ""
547" -d FREQ, --min FREQ new minimum CPU frequency the governor may "
548"select\n"
549msgstr ""
550" -d FREQ, --min FREQ nouvelle fréquence minimale du CPU à utiliser\n"
551" par le régulateur\n"
552
553#: utils/cpufreq-set.c:28
554#, c-format
555msgid ""
556" -u FREQ, --max FREQ new maximum CPU frequency the governor may "
557"select\n"
558msgstr ""
559" -u FREQ, --max FREQ nouvelle fréquence maximale du CPU à utiliser\n"
560" par le régulateur\n"
561
562#: utils/cpufreq-set.c:29
563#, c-format
564msgid " -g GOV, --governor GOV new cpufreq governor\n"
565msgstr " -g GOV, --governor GOV active le régulateur GOV\n"
566
567#: utils/cpufreq-set.c:30
568#, c-format
569msgid ""
570" -f FREQ, --freq FREQ specific frequency to be set. Requires userspace\n"
571" governor to be available and loaded\n"
572msgstr ""
573" -f FREQ, --freq FREQ fixe la fréquence du processeur à FREQ. Il faut\n"
574" que le régulateur « userspace » soit disponible \n"
575" et activé.\n"
576
577#: utils/cpufreq-set.c:32
578#, c-format
579msgid " -r, --related Switches all hardware-related CPUs\n"
580msgstr ""
581
582#: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27
583#, fuzzy, c-format
584msgid " -h, --help Prints out this screen\n"
585msgstr " -h, --help affiche l'aide-mémoire\n"
586
587#: utils/cpufreq-set.c:35
588#, fuzzy, c-format
589msgid ""
590"Notes:\n"
591"1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n"
592msgstr "Les arguments avec un * utiliseront le CPU 0 si -c (--cpu) est omis\n"
593
594#: utils/cpufreq-set.c:37
595#, fuzzy, c-format
596msgid ""
597"2. The -f FREQ, --freq FREQ parameter cannot be combined with any other "
598"parameter\n"
599" except the -c CPU, --cpu CPU parameter\n"
600"3. FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz\n"
601" by postfixing the value with the wanted unit name, without any space\n"
602" (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
603msgstr ""
604"Remarque :\n"
605"1. Le CPU numéro 0 sera utilisé par défaut si -c (ou --cpu) est omis ;\n"
606"2. l'argument -f FREQ (ou --freq FREQ) ne peut être utilisé qu'avec --cpu ;\n"
607"3. on pourra préciser l'unité des fréquences en postfixant sans aucune "
608"espace\n"
609" les valeurs par hz, kHz (par défaut), MHz, GHz ou THz\n"
610" (kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
611
612#: utils/cpufreq-set.c:57
613#, c-format
614msgid ""
615"Error setting new values. Common errors:\n"
616"- Do you have proper administration rights? (super-user?)\n"
617"- Is the governor you requested available and modprobed?\n"
618"- Trying to set an invalid policy?\n"
619"- Trying to set a specific frequency, but userspace governor is not "
620"available,\n"
621" for example because of hardware which cannot be set to a specific "
622"frequency\n"
623" or because the userspace governor isn't loaded?\n"
624msgstr ""
625"En ajustant les nouveaux paramètres, une erreur est apparue. Les sources\n"
626"d'erreur typique sont :\n"
627"- droit d'administration insuffisant (êtes-vous root ?) ;\n"
628"- le régulateur choisi n'est pas disponible, ou bien n'est pas disponible "
629"en\n"
630" tant que module noyau ;\n"
631"- la tactique n'est pas disponible ;\n"
632"- vous voulez utiliser l'option -f/--freq, mais le régulateur « userspace »\n"
633" n'est pas disponible, par exemple parce que le matériel ne le supporte\n"
634" pas, ou bien n'est tout simplement pas chargé.\n"
635
636#: utils/cpufreq-set.c:170
637#, c-format
638msgid "wrong, unknown or unhandled CPU?\n"
639msgstr "CPU inconnu ou non supporté ?\n"
640
641#: utils/cpufreq-set.c:302
642#, c-format
643msgid ""
644"the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n"
645"-g/--governor parameters\n"
646msgstr ""
647"l'option -f/--freq est incompatible avec les options -d/--min, -u/--max et\n"
648"-g/--governor\n"
649
650#: utils/cpufreq-set.c:308
651#, c-format
652msgid ""
653"At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n"
654"-g/--governor must be passed\n"
655msgstr ""
656"L'un de ces paramètres est obligatoire : -f/--freq, -d/--min, -u/--max et\n"
657"-g/--governor\n"
658
659#: utils/cpufreq-set.c:347
660#, c-format
661msgid "Setting cpu: %d\n"
662msgstr ""
663
664#: utils/cpupower-set.c:22
665#, c-format
666msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n"
667msgstr ""
668
669#: utils/cpupower-set.c:24
670#, c-format
671msgid ""
672" -b, --perf-bias [VAL] Sets CPU's power vs performance policy on some\n"
673" Intel models [0-15], see manpage for details\n"
674msgstr ""
675
676#: utils/cpupower-set.c:26
677#, c-format
678msgid ""
679" -m, --sched-mc [VAL] Sets the kernel's multi core scheduler policy.\n"
680msgstr ""
681
682#: utils/cpupower-set.c:27
683#, c-format
684msgid ""
685" -s, --sched-smt [VAL] Sets the kernel's thread sibling scheduler "
686"policy.\n"
687msgstr ""
688
689#: utils/cpupower-set.c:80
690#, c-format
691msgid "--perf-bias param out of range [0-%d]\n"
692msgstr ""
693
694#: utils/cpupower-set.c:91
695#, c-format
696msgid "--sched-mc param out of range [0-%d]\n"
697msgstr ""
698
699#: utils/cpupower-set.c:102
700#, c-format
701msgid "--sched-smt param out of range [0-%d]\n"
702msgstr ""
703
704#: utils/cpupower-set.c:121
705#, c-format
706msgid "Error setting sched-mc %s\n"
707msgstr ""
708
709#: utils/cpupower-set.c:127
710#, c-format
711msgid "Error setting sched-smt %s\n"
712msgstr ""
713
714#: utils/cpupower-set.c:146
715#, c-format
716msgid "Error setting perf-bias value on CPU %d\n"
717msgstr ""
718
719#: utils/cpupower-info.c:21
720#, c-format
721msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n"
722msgstr ""
723
724#: utils/cpupower-info.c:23
725#, c-format
726msgid ""
727" -b, --perf-bias Gets CPU's power vs performance policy on some\n"
728" Intel models [0-15], see manpage for details\n"
729msgstr ""
730
731#: utils/cpupower-info.c:25
732#, fuzzy, c-format
733msgid " -m, --sched-mc Gets the kernel's multi core scheduler policy.\n"
734msgstr " -p, --policy Affiche la tactique actuelle de cpufreq *\n"
735
736#: utils/cpupower-info.c:26
737#, c-format
738msgid ""
739" -s, --sched-smt Gets the kernel's thread sibling scheduler policy.\n"
740msgstr ""
741
742#: utils/cpupower-info.c:28
743#, c-format
744msgid ""
745"\n"
746"Passing no option will show all info, by default only on core 0\n"
747msgstr ""
748
749#: utils/cpupower-info.c:102
750#, c-format
751msgid "System's multi core scheduler setting: "
752msgstr ""
753
754#. if sysfs file is missing it's: errno == ENOENT
755#: utils/cpupower-info.c:105 utils/cpupower-info.c:114
756#, c-format
757msgid "not supported\n"
758msgstr ""
759
760#: utils/cpupower-info.c:111
761#, c-format
762msgid "System's thread sibling scheduler setting: "
763msgstr ""
764
765#: utils/cpupower-info.c:126
766#, c-format
767msgid "Intel's performance bias setting needs root privileges\n"
768msgstr ""
769
770#: utils/cpupower-info.c:128
771#, c-format
772msgid "System does not support Intel's performance bias setting\n"
773msgstr ""
774
775#: utils/cpupower-info.c:147
776#, c-format
777msgid "Could not read perf-bias value\n"
778msgstr ""
779
780#: utils/cpupower-info.c:150
781#, c-format
782msgid "perf-bias: %d\n"
783msgstr ""
784
785#: utils/cpuidle-info.c:28
786#, fuzzy, c-format
787msgid "Analyzing CPU %d:\n"
788msgstr "analyse du CPU %d :\n"
789
790#: utils/cpuidle-info.c:32
791#, c-format
792msgid "CPU %u: No idle states\n"
793msgstr ""
794
795#: utils/cpuidle-info.c:36
796#, c-format
797msgid "CPU %u: Can't read idle state info\n"
798msgstr ""
799
800#: utils/cpuidle-info.c:41
801#, c-format
802msgid "Could not determine max idle state %u\n"
803msgstr ""
804
805#: utils/cpuidle-info.c:46
806#, c-format
807msgid "Number of idle states: %d\n"
808msgstr ""
809
810#: utils/cpuidle-info.c:48
811#, fuzzy, c-format
812msgid "Available idle states:"
813msgstr " plage de fréquence : "
814
815#: utils/cpuidle-info.c:71
816#, c-format
817msgid "Flags/Description: %s\n"
818msgstr ""
819
820#: utils/cpuidle-info.c:74
821#, c-format
822msgid "Latency: %lu\n"
823msgstr ""
824
825#: utils/cpuidle-info.c:76
826#, c-format
827msgid "Usage: %lu\n"
828msgstr ""
829
830#: utils/cpuidle-info.c:78
831#, c-format
832msgid "Duration: %llu\n"
833msgstr ""
834
835#: utils/cpuidle-info.c:90
836#, c-format
837msgid "Could not determine cpuidle driver\n"
838msgstr ""
839
840#: utils/cpuidle-info.c:94
841#, fuzzy, c-format
842msgid "CPUidle driver: %s\n"
843msgstr " pilote : %s\n"
844
845#: utils/cpuidle-info.c:99
846#, c-format
847msgid "Could not determine cpuidle governor\n"
848msgstr ""
849
850#: utils/cpuidle-info.c:103
851#, c-format
852msgid "CPUidle governor: %s\n"
853msgstr ""
854
855#: utils/cpuidle-info.c:122
856#, c-format
857msgid "CPU %u: Can't read C-state info\n"
858msgstr ""
859
860#. printf("Cstates: %d\n", cstates);
861#: utils/cpuidle-info.c:127
862#, c-format
863msgid "active state: C0\n"
864msgstr ""
865
866#: utils/cpuidle-info.c:128
867#, c-format
868msgid "max_cstate: C%u\n"
869msgstr ""
870
871#: utils/cpuidle-info.c:129
872#, c-format
873msgid "maximum allowed latency: %lu usec\n"
874msgstr ""
875
876#: utils/cpuidle-info.c:130
877#, c-format
878msgid "states:\t\n"
879msgstr ""
880
881#: utils/cpuidle-info.c:132
882#, c-format
883msgid " C%d: type[C%d] "
884msgstr ""
885
886#: utils/cpuidle-info.c:134
887#, c-format
888msgid "promotion[--] demotion[--] "
889msgstr ""
890
891#: utils/cpuidle-info.c:135
892#, c-format
893msgid "latency[%03lu] "
894msgstr ""
895
896#: utils/cpuidle-info.c:137
897#, c-format
898msgid "usage[%08lu] "
899msgstr ""
900
901#: utils/cpuidle-info.c:139
902#, c-format
903msgid "duration[%020Lu] \n"
904msgstr ""
905
906#: utils/cpuidle-info.c:147
907#, fuzzy, c-format
908msgid "Usage: cpupower idleinfo [options]\n"
909msgstr "Usage : cpufreq-info [options]\n"
910
911#: utils/cpuidle-info.c:149
912#, fuzzy, c-format
913msgid " -s, --silent Only show general C-state information\n"
914msgstr " -e, --debug Afficher les informations de déboguage\n"
915
916#: utils/cpuidle-info.c:150
917#, fuzzy, c-format
918msgid ""
919" -o, --proc Prints out information like provided by the /proc/"
920"acpi/processor/*/power\n"
921" interface in older kernels\n"
922msgstr ""
923" -o, --proc Affiche les informations en utilisant l'interface\n"
924" fournie par /proc/cpufreq, présente dans les "
925"versions\n"
926" 2.4 et les anciennes versions 2.6 du noyau\n"
927
928#: utils/cpuidle-info.c:209
929#, fuzzy, c-format
930msgid "You can't specify more than one output-specific argument\n"
931msgstr ""
932"On ne peut indiquer plus d'un paramètre --cpu, tout comme l'on ne peut\n"
933"spécifier plus d'un argument de formatage\n"
934
935#~ msgid ""
936#~ " -c CPU, --cpu CPU CPU number which information shall be determined "
937#~ "about\n"
938#~ msgstr ""
939#~ " -c CPU, --cpu CPU Numéro du CPU pour lequel l'information sera "
940#~ "affichée\n"
941
942#~ msgid ""
943#~ " -c CPU, --cpu CPU number of CPU where cpufreq settings shall be "
944#~ "modified\n"
945#~ msgstr ""
946#~ " -c CPU, --cpu CPU numéro du CPU à prendre en compte pour les\n"
947#~ " changements\n"
diff --git a/tools/power/cpupower/po/it.po b/tools/power/cpupower/po/it.po
new file mode 100644
index 000000000000..f80c4ddb9bda
--- /dev/null
+++ b/tools/power/cpupower/po/it.po
@@ -0,0 +1,961 @@
1# Italian translations for cpufrequtils package
2# Copyright (C) 2004-2009
3# This file is distributed under the same license as the cpufrequtils package.
4# Mattia Dongili <malattia@gmail.com>.
5#
6#
7msgid ""
8msgstr ""
9"Project-Id-Version: cpufrequtils 0.3\n"
10"Report-Msgid-Bugs-To: \n"
11"POT-Creation-Date: 2011-03-08 17:03+0100\n"
12"PO-Revision-Date: 2009-08-15 12:00+0900\n"
13"Last-Translator: Mattia Dongili <malattia@gmail.com>\n"
14"Language-Team: NONE\n"
15"Language: \n"
16"MIME-Version: 1.0\n"
17"Content-Type: text/plain; charset=UTF-8\n"
18"Content-Transfer-Encoding: 8bit\n"
19
20#: utils/idle_monitor/nhm_idle.c:36
21msgid "Processor Core C3"
22msgstr ""
23
24#: utils/idle_monitor/nhm_idle.c:43
25msgid "Processor Core C6"
26msgstr ""
27
28#: utils/idle_monitor/nhm_idle.c:51
29msgid "Processor Package C3"
30msgstr ""
31
32#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70
33msgid "Processor Package C6"
34msgstr ""
35
36#: utils/idle_monitor/snb_idle.c:33
37msgid "Processor Core C7"
38msgstr ""
39
40#: utils/idle_monitor/snb_idle.c:40
41msgid "Processor Package C2"
42msgstr ""
43
44#: utils/idle_monitor/snb_idle.c:47
45msgid "Processor Package C7"
46msgstr ""
47
48#: utils/idle_monitor/amd_fam14h_idle.c:56
49msgid "Package in sleep state (PC1 or deeper)"
50msgstr ""
51
52#: utils/idle_monitor/amd_fam14h_idle.c:63
53msgid "Processor Package C1"
54msgstr ""
55
56#: utils/idle_monitor/amd_fam14h_idle.c:77
57msgid "North Bridge P1 boolean counter (returns 0 or 1)"
58msgstr ""
59
60#: utils/idle_monitor/mperf_monitor.c:35
61msgid "Processor Core not idle"
62msgstr ""
63
64#: utils/idle_monitor/mperf_monitor.c:42
65msgid "Processor Core in an idle state"
66msgstr ""
67
68#: utils/idle_monitor/mperf_monitor.c:50
69msgid "Average Frequency (including boost) in MHz"
70msgstr ""
71
72#: utils/idle_monitor/cpupower-monitor.c:66
73#, c-format
74msgid ""
75"cpupower monitor: [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
76"interval_sec | -c command ...]\n"
77msgstr ""
78
79#: utils/idle_monitor/cpupower-monitor.c:69
80#, c-format
81msgid ""
82"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
83"interval_sec | -c command ...]\n"
84msgstr ""
85
86#: utils/idle_monitor/cpupower-monitor.c:71
87#, c-format
88msgid "\t -v: be more verbose\n"
89msgstr ""
90
91#: utils/idle_monitor/cpupower-monitor.c:73
92#, c-format
93msgid "\t -h: print this help\n"
94msgstr ""
95
96#: utils/idle_monitor/cpupower-monitor.c:74
97#, c-format
98msgid "\t -i: time intervall to measure for in seconds (default 1)\n"
99msgstr ""
100
101#: utils/idle_monitor/cpupower-monitor.c:75
102#, c-format
103msgid "\t -t: show CPU topology/hierarchy\n"
104msgstr ""
105
106#: utils/idle_monitor/cpupower-monitor.c:76
107#, c-format
108msgid "\t -l: list available CPU sleep monitors (for use with -m)\n"
109msgstr ""
110
111#: utils/idle_monitor/cpupower-monitor.c:77
112#, c-format
113msgid "\t -m: show specific CPU sleep monitors only (in same order)\n"
114msgstr ""
115
116#: utils/idle_monitor/cpupower-monitor.c:79
117#, c-format
118msgid ""
119"only one of: -t, -l, -m are allowed\n"
120"If none of them is passed,"
121msgstr ""
122
123#: utils/idle_monitor/cpupower-monitor.c:80
124#, c-format
125msgid " all supported monitors are shown\n"
126msgstr ""
127
128#: utils/idle_monitor/cpupower-monitor.c:197
129#, c-format
130msgid "Monitor %s, Counter %s has no count function. Implementation error\n"
131msgstr ""
132
133#: utils/idle_monitor/cpupower-monitor.c:207
134#, c-format
135msgid " *is offline\n"
136msgstr ""
137
138#: utils/idle_monitor/cpupower-monitor.c:236
139#, c-format
140msgid "%s: max monitor name length (%d) exceeded\n"
141msgstr ""
142
143#: utils/idle_monitor/cpupower-monitor.c:250
144#, c-format
145msgid "No matching monitor found in %s, try -l option\n"
146msgstr ""
147
148#: utils/idle_monitor/cpupower-monitor.c:266
149#, c-format
150msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n"
151msgstr ""
152
153#: utils/idle_monitor/cpupower-monitor.c:319
154#, c-format
155msgid "%s took %.5f seconds and exited with status %d\n"
156msgstr ""
157
158#: utils/idle_monitor/cpupower-monitor.c:406
159#, c-format
160msgid "Cannot read number of available processors\n"
161msgstr ""
162
163#: utils/idle_monitor/cpupower-monitor.c:417
164#, c-format
165msgid "Available monitor %s needs root access\n"
166msgstr ""
167
168#: utils/idle_monitor/cpupower-monitor.c:428
169#, c-format
170msgid "No HW Cstate monitors found\n"
171msgstr ""
172
173#: utils/cpupower.c:78
174#, c-format
175msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n"
176msgstr ""
177
178#: utils/cpupower.c:79
179#, c-format
180msgid "cpupower --version\n"
181msgstr ""
182
183#: utils/cpupower.c:80
184#, c-format
185msgid "Supported subcommands are:\n"
186msgstr ""
187
188#: utils/cpupower.c:83
189#, c-format
190msgid ""
191"\n"
192"Some subcommands can make use of the -c cpulist option.\n"
193msgstr ""
194
195#: utils/cpupower.c:84
196#, c-format
197msgid "Look at the general cpupower manpage how to use it\n"
198msgstr ""
199
200#: utils/cpupower.c:85
201#, c-format
202msgid "and read up the subcommand's manpage whether it is supported.\n"
203msgstr ""
204
205#: utils/cpupower.c:86
206#, c-format
207msgid ""
208"\n"
209"Use cpupower help subcommand for getting help for above subcommands.\n"
210msgstr ""
211
212#: utils/cpupower.c:91
213#, c-format
214msgid "Report errors and bugs to %s, please.\n"
215msgstr "Per favore, comunicare errori e malfunzionamenti a %s.\n"
216
217#: utils/cpupower.c:114
218#, c-format
219msgid "Error parsing cpu list\n"
220msgstr ""
221
222#: utils/cpupower.c:172
223#, c-format
224msgid "Subcommand %s needs root privileges\n"
225msgstr ""
226
227#: utils/cpufreq-info.c:31
228#, c-format
229msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n"
230msgstr "Impossibile determinare il numero di CPU (%s: %s), assumo sia 1\n"
231
232#: utils/cpufreq-info.c:63
233#, c-format
234msgid ""
235" minimum CPU frequency - maximum CPU frequency - governor\n"
236msgstr ""
237" frequenza minima CPU - frequenza massima CPU - gestore\n"
238
239#: utils/cpufreq-info.c:151
240#, c-format
241msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n"
242msgstr ""
243
244#. P state changes via MSR are identified via cpuid 80000007
245#. on Intel and AMD, but we assume boost capable machines can do that
246#. if (cpuid_eax(0x80000000) >= 0x80000007
247#. && (cpuid_edx(0x80000007) & (1 << 7)))
248#.
249#: utils/cpufreq-info.c:161
250#, c-format
251msgid " boost state support: \n"
252msgstr ""
253
254#: utils/cpufreq-info.c:163
255#, c-format
256msgid " Supported: %s\n"
257msgstr ""
258
259#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
260msgid "yes"
261msgstr ""
262
263#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
264msgid "no"
265msgstr ""
266
267#: utils/cpufreq-info.c:164
268#, fuzzy, c-format
269msgid " Active: %s\n"
270msgstr " modulo %s\n"
271
272#: utils/cpufreq-info.c:177
273#, c-format
274msgid " Boost States: %d\n"
275msgstr ""
276
277#: utils/cpufreq-info.c:178
278#, c-format
279msgid " Total States: %d\n"
280msgstr ""
281
282#: utils/cpufreq-info.c:181
283#, c-format
284msgid " Pstate-Pb%d: %luMHz (boost state)\n"
285msgstr ""
286
287#: utils/cpufreq-info.c:184
288#, c-format
289msgid " Pstate-P%d: %luMHz\n"
290msgstr ""
291
292#: utils/cpufreq-info.c:211
293#, c-format
294msgid " no or unknown cpufreq driver is active on this CPU\n"
295msgstr " nessun modulo o modulo cpufreq sconosciuto per questa CPU\n"
296
297#: utils/cpufreq-info.c:213
298#, c-format
299msgid " driver: %s\n"
300msgstr " modulo %s\n"
301
302#: utils/cpufreq-info.c:219
303#, c-format
304msgid " CPUs which run at the same hardware frequency: "
305msgstr " CPU che operano alla stessa frequenza hardware: "
306
307#: utils/cpufreq-info.c:230
308#, c-format
309msgid " CPUs which need to have their frequency coordinated by software: "
310msgstr " CPU che è necessario siano coordinate dal software: "
311
312#: utils/cpufreq-info.c:241
313#, c-format
314msgid " maximum transition latency: "
315msgstr " latenza massima durante la transizione: "
316
317#: utils/cpufreq-info.c:247
318#, c-format
319msgid " hardware limits: "
320msgstr " limiti hardware: "
321
322#: utils/cpufreq-info.c:256
323#, c-format
324msgid " available frequency steps: "
325msgstr " frequenze disponibili: "
326
327#: utils/cpufreq-info.c:269
328#, c-format
329msgid " available cpufreq governors: "
330msgstr " gestori disponibili: "
331
332#: utils/cpufreq-info.c:280
333#, c-format
334msgid " current policy: frequency should be within "
335msgstr " gestore attuale: la frequenza deve mantenersi tra "
336
337#: utils/cpufreq-info.c:282
338#, c-format
339msgid " and "
340msgstr " e "
341
342#: utils/cpufreq-info.c:286
343#, c-format
344msgid ""
345"The governor \"%s\" may decide which speed to use\n"
346" within this range.\n"
347msgstr ""
348" Il gestore \"%s\" può decidere quale velocità usare\n"
349" in questo intervallo.\n"
350
351#: utils/cpufreq-info.c:293
352#, c-format
353msgid " current CPU frequency is "
354msgstr " la frequenza attuale della CPU è "
355
356#: utils/cpufreq-info.c:296
357#, c-format
358msgid " (asserted by call to hardware)"
359msgstr " (ottenuta da una chiamata diretta all'hardware)"
360
361#: utils/cpufreq-info.c:304
362#, c-format
363msgid " cpufreq stats: "
364msgstr " statistiche cpufreq:"
365
366#: utils/cpufreq-info.c:472
367#, fuzzy, c-format
368msgid "Usage: cpupower freqinfo [options]\n"
369msgstr "Uso: cpufreq-info [opzioni]\n"
370
371#: utils/cpufreq-info.c:473 utils/cpufreq-set.c:26 utils/cpupower-set.c:23
372#: utils/cpupower-info.c:22 utils/cpuidle-info.c:148
373#, c-format
374msgid "Options:\n"
375msgstr "Opzioni:\n"
376
377#: utils/cpufreq-info.c:474
378#, fuzzy, c-format
379msgid " -e, --debug Prints out debug information [default]\n"
380msgstr " -e, --debug Mostra informazioni di debug\n"
381
382#: utils/cpufreq-info.c:475
383#, c-format
384msgid ""
385" -f, --freq Get frequency the CPU currently runs at, according\n"
386" to the cpufreq core *\n"
387msgstr ""
388" -f, --freq Mostra la frequenza attuale della CPU secondo\n"
389" il modulo cpufreq *\n"
390
391#: utils/cpufreq-info.c:477
392#, c-format
393msgid ""
394" -w, --hwfreq Get frequency the CPU currently runs at, by reading\n"
395" it from hardware (only available to root) *\n"
396msgstr ""
397" -w, --hwfreq Mostra la frequenza attuale della CPU leggendola\n"
398" dall'hardware (disponibile solo per l'utente root) *\n"
399
400#: utils/cpufreq-info.c:479
401#, c-format
402msgid ""
403" -l, --hwlimits Determine the minimum and maximum CPU frequency "
404"allowed *\n"
405msgstr ""
406" -l, --hwlimits Determina le frequenze minima e massima possibili per "
407"la CPU *\n"
408
409#: utils/cpufreq-info.c:480
410#, c-format
411msgid " -d, --driver Determines the used cpufreq kernel driver *\n"
412msgstr ""
413" -d, --driver Determina il modulo cpufreq del kernel in uso *\n"
414
415#: utils/cpufreq-info.c:481
416#, c-format
417msgid " -p, --policy Gets the currently used cpufreq policy *\n"
418msgstr ""
419" -p, --policy Mostra il gestore cpufreq attualmente in uso *\n"
420
421#: utils/cpufreq-info.c:482
422#, c-format
423msgid " -g, --governors Determines available cpufreq governors *\n"
424msgstr " -g, --governors Determina i gestori cpufreq disponibili *\n"
425
426#: utils/cpufreq-info.c:483
427#, c-format
428msgid ""
429" -r, --related-cpus Determines which CPUs run at the same hardware "
430"frequency *\n"
431msgstr ""
432" -r, --related-cpus Determina quali CPU operano alla stessa frequenza *\n"
433
434#: utils/cpufreq-info.c:484
435#, c-format
436msgid ""
437" -a, --affected-cpus Determines which CPUs need to have their frequency\n"
438" coordinated by software *\n"
439msgstr ""
440" -a, --affected-cpus Determina quali CPU devono avere la frequenza\n"
441" coordinata dal software *\n"
442
443#: utils/cpufreq-info.c:486
444#, c-format
445msgid " -s, --stats Shows cpufreq statistics if available\n"
446msgstr " -s, --stats Mostra le statistiche se disponibili\n"
447
448#: utils/cpufreq-info.c:487
449#, c-format
450msgid ""
451" -y, --latency Determines the maximum latency on CPU frequency "
452"changes *\n"
453msgstr ""
454" -y, --latency Determina la latenza massima durante i cambi di "
455"frequenza *\n"
456
457#: utils/cpufreq-info.c:488
458#, c-format
459msgid " -b, --boost Checks for turbo or boost modes *\n"
460msgstr ""
461
462#: utils/cpufreq-info.c:489
463#, c-format
464msgid ""
465" -o, --proc Prints out information like provided by the /proc/"
466"cpufreq\n"
467" interface in 2.4. and early 2.6. kernels\n"
468msgstr ""
469" -o, --proc Stampa le informazioni come se provenissero dalla\n"
470" interfaccia cpufreq /proc/ presente nei kernel\n"
471" 2.4 ed i primi 2.6\n"
472
473#: utils/cpufreq-info.c:491
474#, c-format
475msgid ""
476" -m, --human human-readable output for the -f, -w, -s and -y "
477"parameters\n"
478msgstr ""
479" -m, --human formatta l'output delle opzioni -f, -w, -s e -y in "
480"maniera\n"
481" leggibile da un essere umano\n"
482
483#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152
484#, c-format
485msgid " -h, --help Prints out this screen\n"
486msgstr " -h, --help Stampa questa schermata\n"
487
488#: utils/cpufreq-info.c:495
489#, c-format
490msgid ""
491"If no argument or only the -c, --cpu parameter is given, debug output about\n"
492"cpufreq is printed which is useful e.g. for reporting bugs.\n"
493msgstr ""
494"Se non viene specificata nessuna opzione o viene specificata solo l'opzione -"
495"c, --cpu,\n"
496"le informazioni di debug per cpufreq saranno utili ad esempio a riportare i "
497"bug.\n"
498
499#: utils/cpufreq-info.c:497
500#, c-format
501msgid ""
502"For the arguments marked with *, omitting the -c or --cpu argument is\n"
503"equivalent to setting it to zero\n"
504msgstr ""
505"Per le opzioni segnalate con *, omettere l'opzione -c o --cpu è come "
506"specificarla\n"
507"con il valore 0\n"
508
509#: utils/cpufreq-info.c:580
510#, c-format
511msgid ""
512"The argument passed to this tool can't be combined with passing a --cpu "
513"argument\n"
514msgstr ""
515"L'opzione specificata a questo programma non può essere combinata con --cpu\n"
516
517#: utils/cpufreq-info.c:596
518#, c-format
519msgid ""
520"You can't specify more than one --cpu parameter and/or\n"
521"more than one output-specific argument\n"
522msgstr ""
523"Non è possibile specificare più di una volta l'opzione --cpu e/o\n"
524"specificare più di un parametro di output specifico\n"
525
526#: utils/cpufreq-info.c:600 utils/cpufreq-set.c:82 utils/cpupower-set.c:42
527#: utils/cpupower-info.c:42 utils/cpuidle-info.c:213
528#, c-format
529msgid "invalid or unknown argument\n"
530msgstr "opzione sconosciuta o non valida\n"
531
532#: utils/cpufreq-info.c:617
533#, c-format
534msgid "couldn't analyze CPU %d as it doesn't seem to be present\n"
535msgstr "impossibile analizzare la CPU %d poiché non sembra essere presente\n"
536
537#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142
538#, c-format
539msgid "analyzing CPU %d:\n"
540msgstr "analisi della CPU %d:\n"
541
542#: utils/cpufreq-set.c:25
543#, fuzzy, c-format
544msgid "Usage: cpupower frequency-set [options]\n"
545msgstr "Uso: cpufreq-set [opzioni]\n"
546
547#: utils/cpufreq-set.c:27
548#, c-format
549msgid ""
550" -d FREQ, --min FREQ new minimum CPU frequency the governor may "
551"select\n"
552msgstr ""
553" -d FREQ, --min FREQ la nuova frequenza minima che il gestore cpufreq "
554"può scegliere\n"
555
556#: utils/cpufreq-set.c:28
557#, c-format
558msgid ""
559" -u FREQ, --max FREQ new maximum CPU frequency the governor may "
560"select\n"
561msgstr ""
562" -u FREQ, --max FREQ la nuova frequenza massima che il gestore cpufreq "
563"può scegliere\n"
564
565#: utils/cpufreq-set.c:29
566#, c-format
567msgid " -g GOV, --governor GOV new cpufreq governor\n"
568msgstr " -g GOV, --governor GOV nuovo gestore cpufreq\n"
569
570#: utils/cpufreq-set.c:30
571#, c-format
572msgid ""
573" -f FREQ, --freq FREQ specific frequency to be set. Requires userspace\n"
574" governor to be available and loaded\n"
575msgstr ""
576" -f FREQ, --freq FREQ specifica la frequenza a cui impostare la CPU.\n"
577" È necessario che il gestore userspace sia "
578"disponibile e caricato\n"
579
580#: utils/cpufreq-set.c:32
581#, c-format
582msgid " -r, --related Switches all hardware-related CPUs\n"
583msgstr ""
584" -r, --related Modifica tutte le CPU coordinate dall'hardware\n"
585
586#: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27
587#, c-format
588msgid " -h, --help Prints out this screen\n"
589msgstr " -h, --help Stampa questa schermata\n"
590
591#: utils/cpufreq-set.c:35
592#, fuzzy, c-format
593msgid ""
594"Notes:\n"
595"1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n"
596msgstr ""
597"Per le opzioni segnalate con *, omettere l'opzione -c o --cpu è come "
598"specificarla\n"
599"con il valore 0\n"
600
601#: utils/cpufreq-set.c:37
602#, fuzzy, c-format
603msgid ""
604"2. The -f FREQ, --freq FREQ parameter cannot be combined with any other "
605"parameter\n"
606" except the -c CPU, --cpu CPU parameter\n"
607"3. FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz\n"
608" by postfixing the value with the wanted unit name, without any space\n"
609" (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
610msgstr ""
611"Note:\n"
612"1. Omettere l'opzione -c o --cpu è equivalente a impostarlo a 0\n"
613"2. l'opzione -f FREQ, --freq FREQ non può essere specificata con altre "
614"opzioni\n"
615" ad eccezione dell'opzione -c CPU o --cpu CPU\n"
616"3. le FREQuenze possono essere specuficate in Hz, kHz (default), MHz, GHz, "
617"or THz\n"
618" postponendo l'unità di misura al valore senza nessuno spazio fra loro\n"
619" (FREQuenza in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
620
621#: utils/cpufreq-set.c:57
622#, c-format
623msgid ""
624"Error setting new values. Common errors:\n"
625"- Do you have proper administration rights? (super-user?)\n"
626"- Is the governor you requested available and modprobed?\n"
627"- Trying to set an invalid policy?\n"
628"- Trying to set a specific frequency, but userspace governor is not "
629"available,\n"
630" for example because of hardware which cannot be set to a specific "
631"frequency\n"
632" or because the userspace governor isn't loaded?\n"
633msgstr ""
634"Si sono verificati degli errori impostando i nuovi valori.\n"
635"Alcuni errori comuni possono essere:\n"
636"- Hai i necessari diritti di amministrazione? (super-user?)\n"
637"- Il gestore che hai richiesto è disponibile e caricato?\n"
638"- Stai provando ad impostare una politica di gestione non valida?\n"
639"- Stai provando a impostare una specifica frequenza ma il gestore\n"
640" userspace non è disponibile, per esempio a causa dell'hardware\n"
641" che non supporta frequenze fisse o a causa del fatto che\n"
642" il gestore userspace non è caricato?\n"
643
644#: utils/cpufreq-set.c:170
645#, c-format
646msgid "wrong, unknown or unhandled CPU?\n"
647msgstr "CPU errata, sconosciuta o non gestita?\n"
648
649#: utils/cpufreq-set.c:302
650#, c-format
651msgid ""
652"the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n"
653"-g/--governor parameters\n"
654msgstr ""
655"l'opzione -f/--freq non può venire combinata con i parametri\n"
656" -d/--min, -u/--max o -g/--governor\n"
657
658#: utils/cpufreq-set.c:308
659#, c-format
660msgid ""
661"At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n"
662"-g/--governor must be passed\n"
663msgstr ""
664"Almeno una delle opzioni -f/--freq, -d/--min, -u/--max, e -g/--governor\n"
665"deve essere specificata\n"
666
667#: utils/cpufreq-set.c:347
668#, c-format
669msgid "Setting cpu: %d\n"
670msgstr ""
671
672#: utils/cpupower-set.c:22
673#, c-format
674msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n"
675msgstr ""
676
677#: utils/cpupower-set.c:24
678#, c-format
679msgid ""
680" -b, --perf-bias [VAL] Sets CPU's power vs performance policy on some\n"
681" Intel models [0-15], see manpage for details\n"
682msgstr ""
683
684#: utils/cpupower-set.c:26
685#, c-format
686msgid ""
687" -m, --sched-mc [VAL] Sets the kernel's multi core scheduler policy.\n"
688msgstr ""
689
690#: utils/cpupower-set.c:27
691#, c-format
692msgid ""
693" -s, --sched-smt [VAL] Sets the kernel's thread sibling scheduler "
694"policy.\n"
695msgstr ""
696
697#: utils/cpupower-set.c:80
698#, c-format
699msgid "--perf-bias param out of range [0-%d]\n"
700msgstr ""
701
702#: utils/cpupower-set.c:91
703#, c-format
704msgid "--sched-mc param out of range [0-%d]\n"
705msgstr ""
706
707#: utils/cpupower-set.c:102
708#, c-format
709msgid "--sched-smt param out of range [0-%d]\n"
710msgstr ""
711
712#: utils/cpupower-set.c:121
713#, c-format
714msgid "Error setting sched-mc %s\n"
715msgstr ""
716
717#: utils/cpupower-set.c:127
718#, c-format
719msgid "Error setting sched-smt %s\n"
720msgstr ""
721
722#: utils/cpupower-set.c:146
723#, c-format
724msgid "Error setting perf-bias value on CPU %d\n"
725msgstr ""
726
727#: utils/cpupower-info.c:21
728#, c-format
729msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n"
730msgstr ""
731
732#: utils/cpupower-info.c:23
733#, c-format
734msgid ""
735" -b, --perf-bias Gets CPU's power vs performance policy on some\n"
736" Intel models [0-15], see manpage for details\n"
737msgstr ""
738
739#: utils/cpupower-info.c:25
740#, fuzzy, c-format
741msgid " -m, --sched-mc Gets the kernel's multi core scheduler policy.\n"
742msgstr ""
743" -p, --policy Mostra il gestore cpufreq attualmente in uso *\n"
744
745#: utils/cpupower-info.c:26
746#, c-format
747msgid ""
748" -s, --sched-smt Gets the kernel's thread sibling scheduler policy.\n"
749msgstr ""
750
751#: utils/cpupower-info.c:28
752#, c-format
753msgid ""
754"\n"
755"Passing no option will show all info, by default only on core 0\n"
756msgstr ""
757
758#: utils/cpupower-info.c:102
759#, c-format
760msgid "System's multi core scheduler setting: "
761msgstr ""
762
763#. if sysfs file is missing it's: errno == ENOENT
764#: utils/cpupower-info.c:105 utils/cpupower-info.c:114
765#, c-format
766msgid "not supported\n"
767msgstr ""
768
769#: utils/cpupower-info.c:111
770#, c-format
771msgid "System's thread sibling scheduler setting: "
772msgstr ""
773
774#: utils/cpupower-info.c:126
775#, c-format
776msgid "Intel's performance bias setting needs root privileges\n"
777msgstr ""
778
779#: utils/cpupower-info.c:128
780#, c-format
781msgid "System does not support Intel's performance bias setting\n"
782msgstr ""
783
784#: utils/cpupower-info.c:147
785#, c-format
786msgid "Could not read perf-bias value\n"
787msgstr ""
788
789#: utils/cpupower-info.c:150
790#, c-format
791msgid "perf-bias: %d\n"
792msgstr ""
793
794#: utils/cpuidle-info.c:28
795#, fuzzy, c-format
796msgid "Analyzing CPU %d:\n"
797msgstr "analisi della CPU %d:\n"
798
799#: utils/cpuidle-info.c:32
800#, c-format
801msgid "CPU %u: No idle states\n"
802msgstr ""
803
804#: utils/cpuidle-info.c:36
805#, c-format
806msgid "CPU %u: Can't read idle state info\n"
807msgstr ""
808
809#: utils/cpuidle-info.c:41
810#, c-format
811msgid "Could not determine max idle state %u\n"
812msgstr ""
813
814#: utils/cpuidle-info.c:46
815#, c-format
816msgid "Number of idle states: %d\n"
817msgstr ""
818
819#: utils/cpuidle-info.c:48
820#, fuzzy, c-format
821msgid "Available idle states:"
822msgstr " frequenze disponibili: "
823
824#: utils/cpuidle-info.c:71
825#, c-format
826msgid "Flags/Description: %s\n"
827msgstr ""
828
829#: utils/cpuidle-info.c:74
830#, c-format
831msgid "Latency: %lu\n"
832msgstr ""
833
834#: utils/cpuidle-info.c:76
835#, c-format
836msgid "Usage: %lu\n"
837msgstr ""
838
839#: utils/cpuidle-info.c:78
840#, c-format
841msgid "Duration: %llu\n"
842msgstr ""
843
844#: utils/cpuidle-info.c:90
845#, c-format
846msgid "Could not determine cpuidle driver\n"
847msgstr ""
848
849#: utils/cpuidle-info.c:94
850#, fuzzy, c-format
851msgid "CPUidle driver: %s\n"
852msgstr " modulo %s\n"
853
854#: utils/cpuidle-info.c:99
855#, c-format
856msgid "Could not determine cpuidle governor\n"
857msgstr ""
858
859#: utils/cpuidle-info.c:103
860#, c-format
861msgid "CPUidle governor: %s\n"
862msgstr ""
863
864#: utils/cpuidle-info.c:122
865#, c-format
866msgid "CPU %u: Can't read C-state info\n"
867msgstr ""
868
869#. printf("Cstates: %d\n", cstates);
870#: utils/cpuidle-info.c:127
871#, c-format
872msgid "active state: C0\n"
873msgstr ""
874
875#: utils/cpuidle-info.c:128
876#, c-format
877msgid "max_cstate: C%u\n"
878msgstr ""
879
880#: utils/cpuidle-info.c:129
881#, fuzzy, c-format
882msgid "maximum allowed latency: %lu usec\n"
883msgstr " latenza massima durante la transizione: "
884
885#: utils/cpuidle-info.c:130
886#, c-format
887msgid "states:\t\n"
888msgstr ""
889
890#: utils/cpuidle-info.c:132
891#, c-format
892msgid " C%d: type[C%d] "
893msgstr ""
894
895#: utils/cpuidle-info.c:134
896#, c-format
897msgid "promotion[--] demotion[--] "
898msgstr ""
899
900#: utils/cpuidle-info.c:135
901#, c-format
902msgid "latency[%03lu] "
903msgstr ""
904
905#: utils/cpuidle-info.c:137
906#, c-format
907msgid "usage[%08lu] "
908msgstr ""
909
910#: utils/cpuidle-info.c:139
911#, c-format
912msgid "duration[%020Lu] \n"
913msgstr ""
914
915#: utils/cpuidle-info.c:147
916#, fuzzy, c-format
917msgid "Usage: cpupower idleinfo [options]\n"
918msgstr "Uso: cpufreq-info [opzioni]\n"
919
920#: utils/cpuidle-info.c:149
921#, fuzzy, c-format
922msgid " -s, --silent Only show general C-state information\n"
923msgstr " -e, --debug Mostra informazioni di debug\n"
924
925#: utils/cpuidle-info.c:150
926#, fuzzy, c-format
927msgid ""
928" -o, --proc Prints out information like provided by the /proc/"
929"acpi/processor/*/power\n"
930" interface in older kernels\n"
931msgstr ""
932" -o, --proc Stampa le informazioni come se provenissero dalla\n"
933" interfaccia cpufreq /proc/ presente nei kernel\n"
934" 2.4 ed i primi 2.6\n"
935
936#: utils/cpuidle-info.c:209
937#, fuzzy, c-format
938msgid "You can't specify more than one output-specific argument\n"
939msgstr ""
940"Non è possibile specificare più di una volta l'opzione --cpu e/o\n"
941"specificare più di un parametro di output specifico\n"
942
943#~ msgid ""
944#~ " -c CPU, --cpu CPU CPU number which information shall be determined "
945#~ "about\n"
946#~ msgstr ""
947#~ " -c CPU, --cpu CPU Numero di CPU per la quale ottenere le "
948#~ "informazioni\n"
949
950#~ msgid ""
951#~ " -c CPU, --cpu CPU number of CPU where cpufreq settings shall be "
952#~ "modified\n"
953#~ msgstr ""
954#~ " -c CPU, --cpu CPU numero di CPU per la quale modificare le "
955#~ "impostazioni\n"
956
957#, fuzzy
958#~ msgid " CPUs which coordinate software frequency requirements: "
959#~ msgstr ""
960#~ " CPU per le quali e` necessario cambiare la frequenza "
961#~ "contemporaneamente: "
diff --git a/tools/power/cpupower/po/pt.po b/tools/power/cpupower/po/pt.po
new file mode 100644
index 000000000000..990f5267ffe8
--- /dev/null
+++ b/tools/power/cpupower/po/pt.po
@@ -0,0 +1,957 @@
1# Brazilian Portuguese translations for cpufrequtils package
2# Copyright (C) 2008 THE cpufrequtils'S COPYRIGHT HOLDER
3# This file is distributed under the same license as the cpufrequtils package.
4# Claudio Eduardo <claudioeddy@gmail.com>, 2009.
5#
6#
7msgid ""
8msgstr ""
9"Project-Id-Version: cpufrequtils 004\n"
10"Report-Msgid-Bugs-To: \n"
11"POT-Creation-Date: 2011-03-08 17:03+0100\n"
12"PO-Revision-Date: 2008-06-14 22:16-0400\n"
13"Last-Translator: Claudio Eduardo <claudioeddy@gmail.com>\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
17
18#: utils/idle_monitor/nhm_idle.c:36
19msgid "Processor Core C3"
20msgstr ""
21
22#: utils/idle_monitor/nhm_idle.c:43
23msgid "Processor Core C6"
24msgstr ""
25
26#: utils/idle_monitor/nhm_idle.c:51
27msgid "Processor Package C3"
28msgstr ""
29
30#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70
31msgid "Processor Package C6"
32msgstr ""
33
34#: utils/idle_monitor/snb_idle.c:33
35msgid "Processor Core C7"
36msgstr ""
37
38#: utils/idle_monitor/snb_idle.c:40
39msgid "Processor Package C2"
40msgstr ""
41
42#: utils/idle_monitor/snb_idle.c:47
43msgid "Processor Package C7"
44msgstr ""
45
46#: utils/idle_monitor/amd_fam14h_idle.c:56
47msgid "Package in sleep state (PC1 or deeper)"
48msgstr ""
49
50#: utils/idle_monitor/amd_fam14h_idle.c:63
51msgid "Processor Package C1"
52msgstr ""
53
54#: utils/idle_monitor/amd_fam14h_idle.c:77
55msgid "North Bridge P1 boolean counter (returns 0 or 1)"
56msgstr ""
57
58#: utils/idle_monitor/mperf_monitor.c:35
59msgid "Processor Core not idle"
60msgstr ""
61
62#: utils/idle_monitor/mperf_monitor.c:42
63msgid "Processor Core in an idle state"
64msgstr ""
65
66#: utils/idle_monitor/mperf_monitor.c:50
67msgid "Average Frequency (including boost) in MHz"
68msgstr ""
69
70#: utils/idle_monitor/cpupower-monitor.c:66
71#, c-format
72msgid ""
73"cpupower monitor: [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
74"interval_sec | -c command ...]\n"
75msgstr ""
76
77#: utils/idle_monitor/cpupower-monitor.c:69
78#, c-format
79msgid ""
80"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
81"interval_sec | -c command ...]\n"
82msgstr ""
83
84#: utils/idle_monitor/cpupower-monitor.c:71
85#, c-format
86msgid "\t -v: be more verbose\n"
87msgstr ""
88
89#: utils/idle_monitor/cpupower-monitor.c:73
90#, c-format
91msgid "\t -h: print this help\n"
92msgstr ""
93
94#: utils/idle_monitor/cpupower-monitor.c:74
95#, c-format
96msgid "\t -i: time intervall to measure for in seconds (default 1)\n"
97msgstr ""
98
99#: utils/idle_monitor/cpupower-monitor.c:75
100#, c-format
101msgid "\t -t: show CPU topology/hierarchy\n"
102msgstr ""
103
104#: utils/idle_monitor/cpupower-monitor.c:76
105#, c-format
106msgid "\t -l: list available CPU sleep monitors (for use with -m)\n"
107msgstr ""
108
109#: utils/idle_monitor/cpupower-monitor.c:77
110#, c-format
111msgid "\t -m: show specific CPU sleep monitors only (in same order)\n"
112msgstr ""
113
114#: utils/idle_monitor/cpupower-monitor.c:79
115#, c-format
116msgid ""
117"only one of: -t, -l, -m are allowed\n"
118"If none of them is passed,"
119msgstr ""
120
121#: utils/idle_monitor/cpupower-monitor.c:80
122#, c-format
123msgid " all supported monitors are shown\n"
124msgstr ""
125
126#: utils/idle_monitor/cpupower-monitor.c:197
127#, c-format
128msgid "Monitor %s, Counter %s has no count function. Implementation error\n"
129msgstr ""
130
131#: utils/idle_monitor/cpupower-monitor.c:207
132#, c-format
133msgid " *is offline\n"
134msgstr ""
135
136#: utils/idle_monitor/cpupower-monitor.c:236
137#, c-format
138msgid "%s: max monitor name length (%d) exceeded\n"
139msgstr ""
140
141#: utils/idle_monitor/cpupower-monitor.c:250
142#, c-format
143msgid "No matching monitor found in %s, try -l option\n"
144msgstr ""
145
146#: utils/idle_monitor/cpupower-monitor.c:266
147#, c-format
148msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n"
149msgstr ""
150
151#: utils/idle_monitor/cpupower-monitor.c:319
152#, c-format
153msgid "%s took %.5f seconds and exited with status %d\n"
154msgstr ""
155
156#: utils/idle_monitor/cpupower-monitor.c:406
157#, c-format
158msgid "Cannot read number of available processors\n"
159msgstr ""
160
161#: utils/idle_monitor/cpupower-monitor.c:417
162#, c-format
163msgid "Available monitor %s needs root access\n"
164msgstr ""
165
166#: utils/idle_monitor/cpupower-monitor.c:428
167#, c-format
168msgid "No HW Cstate monitors found\n"
169msgstr ""
170
171#: utils/cpupower.c:78
172#, c-format
173msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n"
174msgstr ""
175
176#: utils/cpupower.c:79
177#, c-format
178msgid "cpupower --version\n"
179msgstr ""
180
181#: utils/cpupower.c:80
182#, c-format
183msgid "Supported subcommands are:\n"
184msgstr ""
185
186#: utils/cpupower.c:83
187#, c-format
188msgid ""
189"\n"
190"Some subcommands can make use of the -c cpulist option.\n"
191msgstr ""
192
193#: utils/cpupower.c:84
194#, c-format
195msgid "Look at the general cpupower manpage how to use it\n"
196msgstr ""
197
198#: utils/cpupower.c:85
199#, c-format
200msgid "and read up the subcommand's manpage whether it is supported.\n"
201msgstr ""
202
203#: utils/cpupower.c:86
204#, c-format
205msgid ""
206"\n"
207"Use cpupower help subcommand for getting help for above subcommands.\n"
208msgstr ""
209
210#: utils/cpupower.c:91
211#, c-format
212msgid "Report errors and bugs to %s, please.\n"
213msgstr "Reporte erros e bugs para %s, por favor.\n"
214
215#: utils/cpupower.c:114
216#, c-format
217msgid "Error parsing cpu list\n"
218msgstr ""
219
220#: utils/cpupower.c:172
221#, c-format
222msgid "Subcommand %s needs root privileges\n"
223msgstr ""
224
225#: utils/cpufreq-info.c:31
226#, c-format
227msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n"
228msgstr "Não foi possível contar o número de CPUs (%s: %s), assumindo 1\n"
229
230#: utils/cpufreq-info.c:63
231#, c-format
232msgid ""
233" minimum CPU frequency - maximum CPU frequency - governor\n"
234msgstr ""
235" frequência mínina do CPU - frequência máxima do CPU - "
236"regulador\n"
237
238#: utils/cpufreq-info.c:151
239#, c-format
240msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n"
241msgstr ""
242
243#. P state changes via MSR are identified via cpuid 80000007
244#. on Intel and AMD, but we assume boost capable machines can do that
245#. if (cpuid_eax(0x80000000) >= 0x80000007
246#. && (cpuid_edx(0x80000007) & (1 << 7)))
247#.
248#: utils/cpufreq-info.c:161
249#, c-format
250msgid " boost state support: \n"
251msgstr ""
252
253#: utils/cpufreq-info.c:163
254#, c-format
255msgid " Supported: %s\n"
256msgstr ""
257
258#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
259msgid "yes"
260msgstr ""
261
262#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
263msgid "no"
264msgstr ""
265
266#: utils/cpufreq-info.c:164
267#, fuzzy, c-format
268msgid " Active: %s\n"
269msgstr " driver: %s\n"
270
271#: utils/cpufreq-info.c:177
272#, c-format
273msgid " Boost States: %d\n"
274msgstr ""
275
276#: utils/cpufreq-info.c:178
277#, c-format
278msgid " Total States: %d\n"
279msgstr ""
280
281#: utils/cpufreq-info.c:181
282#, c-format
283msgid " Pstate-Pb%d: %luMHz (boost state)\n"
284msgstr ""
285
286#: utils/cpufreq-info.c:184
287#, c-format
288msgid " Pstate-P%d: %luMHz\n"
289msgstr ""
290
291#: utils/cpufreq-info.c:211
292#, c-format
293msgid " no or unknown cpufreq driver is active on this CPU\n"
294msgstr " nenhum ou driver do cpufreq deconhecido está ativo nesse CPU\n"
295
296#: utils/cpufreq-info.c:213
297#, c-format
298msgid " driver: %s\n"
299msgstr " driver: %s\n"
300
301#: utils/cpufreq-info.c:219
302#, c-format
303msgid " CPUs which run at the same hardware frequency: "
304msgstr " CPUs que rodam na mesma frequência de hardware: "
305
306#: utils/cpufreq-info.c:230
307#, c-format
308msgid " CPUs which need to have their frequency coordinated by software: "
309msgstr " CPUs que precisam ter suas frequências coordenadas por software: "
310
311#: utils/cpufreq-info.c:241
312#, c-format
313msgid " maximum transition latency: "
314msgstr " maior latência de transição: "
315
316#: utils/cpufreq-info.c:247
317#, c-format
318msgid " hardware limits: "
319msgstr " limites do hardware: "
320
321#: utils/cpufreq-info.c:256
322#, c-format
323msgid " available frequency steps: "
324msgstr " níveis de frequência disponíveis: "
325
326#: utils/cpufreq-info.c:269
327#, c-format
328msgid " available cpufreq governors: "
329msgstr " reguladores do cpufreq disponíveis: "
330
331#: utils/cpufreq-info.c:280
332#, c-format
333msgid " current policy: frequency should be within "
334msgstr " política de frequência atual deve estar entre "
335
336#: utils/cpufreq-info.c:282
337#, c-format
338msgid " and "
339msgstr " e "
340
341#: utils/cpufreq-info.c:286
342#, c-format
343msgid ""
344"The governor \"%s\" may decide which speed to use\n"
345" within this range.\n"
346msgstr ""
347"O regulador \"%s\" deve decidir qual velocidade usar\n"
348" dentro desse limite.\n"
349
350#: utils/cpufreq-info.c:293
351#, c-format
352msgid " current CPU frequency is "
353msgstr " frequência atual do CPU é "
354
355#: utils/cpufreq-info.c:296
356#, c-format
357msgid " (asserted by call to hardware)"
358msgstr " (declarado por chamada ao hardware)"
359
360#: utils/cpufreq-info.c:304
361#, c-format
362msgid " cpufreq stats: "
363msgstr " status do cpufreq: "
364
365#: utils/cpufreq-info.c:472
366#, fuzzy, c-format
367msgid "Usage: cpupower freqinfo [options]\n"
368msgstr "Uso: cpufreq-info [opções]\n"
369
370#: utils/cpufreq-info.c:473 utils/cpufreq-set.c:26 utils/cpupower-set.c:23
371#: utils/cpupower-info.c:22 utils/cpuidle-info.c:148
372#, c-format
373msgid "Options:\n"
374msgstr "Opções:\n"
375
376#: utils/cpufreq-info.c:474
377#, fuzzy, c-format
378msgid " -e, --debug Prints out debug information [default]\n"
379msgstr " -e, --debug Mostra informação de debug\n"
380
381#: utils/cpufreq-info.c:475
382#, c-format
383msgid ""
384" -f, --freq Get frequency the CPU currently runs at, according\n"
385" to the cpufreq core *\n"
386msgstr ""
387" -f, --freq Obtem a frequência na qual o CPU roda no momento, de "
388"acordo\n"
389" com o núcleo do cpufreq *\n"
390
391#: utils/cpufreq-info.c:477
392#, c-format
393msgid ""
394" -w, --hwfreq Get frequency the CPU currently runs at, by reading\n"
395" it from hardware (only available to root) *\n"
396msgstr ""
397" -w, --hwfreq Obtem a frequência na qual o CPU está operando no "
398"momento,\n"
399" através de leitura no hardware (disponível somente "
400"para root) *\n"
401
402#: utils/cpufreq-info.c:479
403#, c-format
404msgid ""
405" -l, --hwlimits Determine the minimum and maximum CPU frequency "
406"allowed *\n"
407msgstr ""
408" -l, --hwlimits Determina a frequência mínima e máxima do CPU "
409"permitida *\n"
410
411#: utils/cpufreq-info.c:480
412#, c-format
413msgid " -d, --driver Determines the used cpufreq kernel driver *\n"
414msgstr ""
415" -d, --driver Determina o driver do kernel do cpufreq usado *\n"
416
417#: utils/cpufreq-info.c:481
418#, c-format
419msgid " -p, --policy Gets the currently used cpufreq policy *\n"
420msgstr ""
421"--p, --policy Obtem a política do cpufreq em uso no momento *\n"
422
423#: utils/cpufreq-info.c:482
424#, c-format
425msgid " -g, --governors Determines available cpufreq governors *\n"
426msgstr ""
427" -g, --governors Determina reguladores do cpufreq disponíveis *\n"
428
429#: utils/cpufreq-info.c:483
430#, c-format
431msgid ""
432" -r, --related-cpus Determines which CPUs run at the same hardware "
433"frequency *\n"
434msgstr ""
435" -r, --related-cpus Determina quais CPUs rodam na mesma frequência de "
436"hardware *\n"
437
438#: utils/cpufreq-info.c:484
439#, c-format
440msgid ""
441" -a, --affected-cpus Determines which CPUs need to have their frequency\n"
442" coordinated by software *\n"
443msgstr ""
444" -a, --affected-cpus Determina quais CPUs precisam ter suas frequências\n"
445" coordenadas por software *\n"
446
447#: utils/cpufreq-info.c:486
448#, c-format
449msgid " -s, --stats Shows cpufreq statistics if available\n"
450msgstr " -s, --stats Mostra estatísticas do cpufreq se disponíveis\n"
451
452#: utils/cpufreq-info.c:487
453#, c-format
454msgid ""
455" -y, --latency Determines the maximum latency on CPU frequency "
456"changes *\n"
457msgstr ""
458" -y, --latency Determina a latência máxima nas trocas de frequência "
459"do CPU *\n"
460
461#: utils/cpufreq-info.c:488
462#, c-format
463msgid " -b, --boost Checks for turbo or boost modes *\n"
464msgstr ""
465
466#: utils/cpufreq-info.c:489
467#, c-format
468msgid ""
469" -o, --proc Prints out information like provided by the /proc/"
470"cpufreq\n"
471" interface in 2.4. and early 2.6. kernels\n"
472msgstr ""
473" -o, --proc Mostra informação do tipo provida pela interface /"
474"proc/cpufreq\n"
475" em kernels 2.4. e mais recentes 2.6\n"
476
477#: utils/cpufreq-info.c:491
478#, c-format
479msgid ""
480" -m, --human human-readable output for the -f, -w, -s and -y "
481"parameters\n"
482msgstr ""
483" -m, --human saída legível para humanos para os parâmetros -f, -w, "
484"-s e -y\n"
485
486#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152
487#, c-format
488msgid " -h, --help Prints out this screen\n"
489msgstr " -h, --help Imprime essa tela\n"
490
491#: utils/cpufreq-info.c:495
492#, c-format
493msgid ""
494"If no argument or only the -c, --cpu parameter is given, debug output about\n"
495"cpufreq is printed which is useful e.g. for reporting bugs.\n"
496msgstr ""
497"Se nenhum argumento ou somente o parâmetro -c, --cpu é dado, informação de "
498"debug sobre\n"
499"o cpufreq é mostrada, o que é útil por exemplo para reportar bugs.\n"
500
501#: utils/cpufreq-info.c:497
502#, c-format
503msgid ""
504"For the arguments marked with *, omitting the -c or --cpu argument is\n"
505"equivalent to setting it to zero\n"
506msgstr ""
507"Para os argumentos marcados com *, omitir o argumento -c ou --cpu é\n"
508"equivalente a setá-lo como zero\n"
509
510#: utils/cpufreq-info.c:580
511#, c-format
512msgid ""
513"The argument passed to this tool can't be combined with passing a --cpu "
514"argument\n"
515msgstr ""
516"O argumento usado pra essa ferramenta não pode ser combinado com um "
517"argumento --cpu\n"
518
519#: utils/cpufreq-info.c:596
520#, c-format
521msgid ""
522"You can't specify more than one --cpu parameter and/or\n"
523"more than one output-specific argument\n"
524msgstr ""
525"Você não pode especificar mais do que um parâmetro --cpu e/ou\n"
526"mais do que um argumento de saída específico\n"
527
528#: utils/cpufreq-info.c:600 utils/cpufreq-set.c:82 utils/cpupower-set.c:42
529#: utils/cpupower-info.c:42 utils/cpuidle-info.c:213
530#, c-format
531msgid "invalid or unknown argument\n"
532msgstr "argumento inválido ou desconhecido\n"
533
534#: utils/cpufreq-info.c:617
535#, c-format
536msgid "couldn't analyze CPU %d as it doesn't seem to be present\n"
537msgstr ""
538"não foi possível analisar o CPU % já que o mesmo parece não estar presente\n"
539
540#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142
541#, c-format
542msgid "analyzing CPU %d:\n"
543msgstr "analisando o CPU %d:\n"
544
545#: utils/cpufreq-set.c:25
546#, fuzzy, c-format
547msgid "Usage: cpupower frequency-set [options]\n"
548msgstr "Uso: cpufreq-set [opções]\n"
549
550#: utils/cpufreq-set.c:27
551#, c-format
552msgid ""
553" -d FREQ, --min FREQ new minimum CPU frequency the governor may "
554"select\n"
555msgstr ""
556" -d FREQ, --min FREQ nova frequência mínima do CPU que o regulador "
557"deve selecionar\n"
558
559#: utils/cpufreq-set.c:28
560#, c-format
561msgid ""
562" -u FREQ, --max FREQ new maximum CPU frequency the governor may "
563"select\n"
564msgstr ""
565" -u FREQ, --max FREQ nova frequência máxima do CPU que o regulador "
566"deve escolher\n"
567
568#: utils/cpufreq-set.c:29
569#, c-format
570msgid " -g GOV, --governor GOV new cpufreq governor\n"
571msgstr " -g GOV, --governor GOV novo regulador do cpufreq\n"
572
573#: utils/cpufreq-set.c:30
574#, c-format
575msgid ""
576" -f FREQ, --freq FREQ specific frequency to be set. Requires userspace\n"
577" governor to be available and loaded\n"
578msgstr ""
579" -f FREQ, --freq FREQ frequência específica para ser setada. Necessita "
580"que o regulador em\n"
581" nível de usuário esteja disponível e carregado\n"
582
583#: utils/cpufreq-set.c:32
584#, c-format
585msgid " -r, --related Switches all hardware-related CPUs\n"
586msgstr ""
587" -r, --related Modifica todos os CPUs relacionados ao hardware\n"
588
589#: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27
590#, c-format
591msgid " -h, --help Prints out this screen\n"
592msgstr " -h, --help Mostra essa tela\n"
593
594#: utils/cpufreq-set.c:35
595#, fuzzy, c-format
596msgid ""
597"Notes:\n"
598"1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n"
599msgstr ""
600"Para os argumentos marcados com *, omitir o argumento -c ou --cpu é\n"
601"equivalente a setá-lo como zero\n"
602
603#: utils/cpufreq-set.c:37
604#, fuzzy, c-format
605msgid ""
606"2. The -f FREQ, --freq FREQ parameter cannot be combined with any other "
607"parameter\n"
608" except the -c CPU, --cpu CPU parameter\n"
609"3. FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz\n"
610" by postfixing the value with the wanted unit name, without any space\n"
611" (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
612msgstr ""
613"Notas:\n"
614"1. Omitir o argumento -c or --cpu é equivalente a setá-lo como zero\n"
615"2. O parâmetro -f FREQ, --freq FREQ não pode ser combinado com qualquer "
616"outro parâmetro\n"
617" exceto com o parâmetro -c CPU, --cpu CPU\n"
618"3. FREQuências podem ser usadas em Hz, kHz (padrão), MHz, GHz, o THz\n"
619" colocando o nome desejado da unidade após o valor, sem qualquer espaço\n"
620" (FREQuência em kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
621
622#: utils/cpufreq-set.c:57
623#, c-format
624msgid ""
625"Error setting new values. Common errors:\n"
626"- Do you have proper administration rights? (super-user?)\n"
627"- Is the governor you requested available and modprobed?\n"
628"- Trying to set an invalid policy?\n"
629"- Trying to set a specific frequency, but userspace governor is not "
630"available,\n"
631" for example because of hardware which cannot be set to a specific "
632"frequency\n"
633" or because the userspace governor isn't loaded?\n"
634msgstr ""
635"Erro ao setar novos valores. Erros comuns:\n"
636"- Você tem direitos administrativos necessários? (super-usuário?)\n"
637"- O regulador que você requesitou está disponível e foi \"modprobed\"?\n"
638"- Tentando setar uma política inválida?\n"
639"- Tentando setar uma frequência específica, mas o regulador em nível de "
640"usuário não está disponível,\n"
641" por exemplo devido ao hardware que não pode ser setado pra uma frequência "
642"específica\n"
643" ou porque o regulador em nível de usuário não foi carregado?\n"
644
645#: utils/cpufreq-set.c:170
646#, c-format
647msgid "wrong, unknown or unhandled CPU?\n"
648msgstr "CPU errado, desconhecido ou inesperado?\n"
649
650#: utils/cpufreq-set.c:302
651#, c-format
652msgid ""
653"the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n"
654"-g/--governor parameters\n"
655msgstr ""
656"o parâmetro -f/--freq não pode ser combinado com os parâmetros -d/--min, -"
657"u/--max ou\n"
658"-g/--governor\n"
659
660#: utils/cpufreq-set.c:308
661#, c-format
662msgid ""
663"At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n"
664"-g/--governor must be passed\n"
665msgstr ""
666"Pelo menos um parâmetro entre -f/--freq, -d/--min, -u/--max, e\n"
667"-g/--governor deve ser usado\n"
668
669#: utils/cpufreq-set.c:347
670#, c-format
671msgid "Setting cpu: %d\n"
672msgstr ""
673
674#: utils/cpupower-set.c:22
675#, c-format
676msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n"
677msgstr ""
678
679#: utils/cpupower-set.c:24
680#, c-format
681msgid ""
682" -b, --perf-bias [VAL] Sets CPU's power vs performance policy on some\n"
683" Intel models [0-15], see manpage for details\n"
684msgstr ""
685
686#: utils/cpupower-set.c:26
687#, c-format
688msgid ""
689" -m, --sched-mc [VAL] Sets the kernel's multi core scheduler policy.\n"
690msgstr ""
691
692#: utils/cpupower-set.c:27
693#, c-format
694msgid ""
695" -s, --sched-smt [VAL] Sets the kernel's thread sibling scheduler "
696"policy.\n"
697msgstr ""
698
699#: utils/cpupower-set.c:80
700#, c-format
701msgid "--perf-bias param out of range [0-%d]\n"
702msgstr ""
703
704#: utils/cpupower-set.c:91
705#, c-format
706msgid "--sched-mc param out of range [0-%d]\n"
707msgstr ""
708
709#: utils/cpupower-set.c:102
710#, c-format
711msgid "--sched-smt param out of range [0-%d]\n"
712msgstr ""
713
714#: utils/cpupower-set.c:121
715#, c-format
716msgid "Error setting sched-mc %s\n"
717msgstr ""
718
719#: utils/cpupower-set.c:127
720#, c-format
721msgid "Error setting sched-smt %s\n"
722msgstr ""
723
724#: utils/cpupower-set.c:146
725#, c-format
726msgid "Error setting perf-bias value on CPU %d\n"
727msgstr ""
728
729#: utils/cpupower-info.c:21
730#, c-format
731msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n"
732msgstr ""
733
734#: utils/cpupower-info.c:23
735#, c-format
736msgid ""
737" -b, --perf-bias Gets CPU's power vs performance policy on some\n"
738" Intel models [0-15], see manpage for details\n"
739msgstr ""
740
741#: utils/cpupower-info.c:25
742#, fuzzy, c-format
743msgid " -m, --sched-mc Gets the kernel's multi core scheduler policy.\n"
744msgstr ""
745"--p, --policy Obtem a política do cpufreq em uso no momento *\n"
746
747#: utils/cpupower-info.c:26
748#, c-format
749msgid ""
750" -s, --sched-smt Gets the kernel's thread sibling scheduler policy.\n"
751msgstr ""
752
753#: utils/cpupower-info.c:28
754#, c-format
755msgid ""
756"\n"
757"Passing no option will show all info, by default only on core 0\n"
758msgstr ""
759
760#: utils/cpupower-info.c:102
761#, c-format
762msgid "System's multi core scheduler setting: "
763msgstr ""
764
765#. if sysfs file is missing it's: errno == ENOENT
766#: utils/cpupower-info.c:105 utils/cpupower-info.c:114
767#, c-format
768msgid "not supported\n"
769msgstr ""
770
771#: utils/cpupower-info.c:111
772#, c-format
773msgid "System's thread sibling scheduler setting: "
774msgstr ""
775
776#: utils/cpupower-info.c:126
777#, c-format
778msgid "Intel's performance bias setting needs root privileges\n"
779msgstr ""
780
781#: utils/cpupower-info.c:128
782#, c-format
783msgid "System does not support Intel's performance bias setting\n"
784msgstr ""
785
786#: utils/cpupower-info.c:147
787#, c-format
788msgid "Could not read perf-bias value\n"
789msgstr ""
790
791#: utils/cpupower-info.c:150
792#, c-format
793msgid "perf-bias: %d\n"
794msgstr ""
795
796#: utils/cpuidle-info.c:28
797#, fuzzy, c-format
798msgid "Analyzing CPU %d:\n"
799msgstr "analisando o CPU %d:\n"
800
801#: utils/cpuidle-info.c:32
802#, c-format
803msgid "CPU %u: No idle states\n"
804msgstr ""
805
806#: utils/cpuidle-info.c:36
807#, c-format
808msgid "CPU %u: Can't read idle state info\n"
809msgstr ""
810
811#: utils/cpuidle-info.c:41
812#, c-format
813msgid "Could not determine max idle state %u\n"
814msgstr ""
815
816#: utils/cpuidle-info.c:46
817#, c-format
818msgid "Number of idle states: %d\n"
819msgstr ""
820
821#: utils/cpuidle-info.c:48
822#, fuzzy, c-format
823msgid "Available idle states:"
824msgstr " níveis de frequência disponíveis: "
825
826#: utils/cpuidle-info.c:71
827#, c-format
828msgid "Flags/Description: %s\n"
829msgstr ""
830
831#: utils/cpuidle-info.c:74
832#, c-format
833msgid "Latency: %lu\n"
834msgstr ""
835
836#: utils/cpuidle-info.c:76
837#, c-format
838msgid "Usage: %lu\n"
839msgstr ""
840
841#: utils/cpuidle-info.c:78
842#, c-format
843msgid "Duration: %llu\n"
844msgstr ""
845
846#: utils/cpuidle-info.c:90
847#, c-format
848msgid "Could not determine cpuidle driver\n"
849msgstr ""
850
851#: utils/cpuidle-info.c:94
852#, fuzzy, c-format
853msgid "CPUidle driver: %s\n"
854msgstr " driver: %s\n"
855
856#: utils/cpuidle-info.c:99
857#, c-format
858msgid "Could not determine cpuidle governor\n"
859msgstr ""
860
861#: utils/cpuidle-info.c:103
862#, c-format
863msgid "CPUidle governor: %s\n"
864msgstr ""
865
866#: utils/cpuidle-info.c:122
867#, c-format
868msgid "CPU %u: Can't read C-state info\n"
869msgstr ""
870
871#. printf("Cstates: %d\n", cstates);
872#: utils/cpuidle-info.c:127
873#, c-format
874msgid "active state: C0\n"
875msgstr ""
876
877#: utils/cpuidle-info.c:128
878#, c-format
879msgid "max_cstate: C%u\n"
880msgstr ""
881
882#: utils/cpuidle-info.c:129
883#, fuzzy, c-format
884msgid "maximum allowed latency: %lu usec\n"
885msgstr " maior latência de transição: "
886
887#: utils/cpuidle-info.c:130
888#, c-format
889msgid "states:\t\n"
890msgstr ""
891
892#: utils/cpuidle-info.c:132
893#, c-format
894msgid " C%d: type[C%d] "
895msgstr ""
896
897#: utils/cpuidle-info.c:134
898#, c-format
899msgid "promotion[--] demotion[--] "
900msgstr ""
901
902#: utils/cpuidle-info.c:135
903#, c-format
904msgid "latency[%03lu] "
905msgstr ""
906
907#: utils/cpuidle-info.c:137
908#, c-format
909msgid "usage[%08lu] "
910msgstr ""
911
912#: utils/cpuidle-info.c:139
913#, c-format
914msgid "duration[%020Lu] \n"
915msgstr ""
916
917#: utils/cpuidle-info.c:147
918#, fuzzy, c-format
919msgid "Usage: cpupower idleinfo [options]\n"
920msgstr "Uso: cpufreq-info [opções]\n"
921
922#: utils/cpuidle-info.c:149
923#, fuzzy, c-format
924msgid " -s, --silent Only show general C-state information\n"
925msgstr " -e, --debug Mostra informação de debug\n"
926
927#: utils/cpuidle-info.c:150
928#, fuzzy, c-format
929msgid ""
930" -o, --proc Prints out information like provided by the /proc/"
931"acpi/processor/*/power\n"
932" interface in older kernels\n"
933msgstr ""
934" -o, --proc Mostra informação do tipo provida pela interface /"
935"proc/cpufreq\n"
936" em kernels 2.4. e mais recentes 2.6\n"
937
938#: utils/cpuidle-info.c:209
939#, fuzzy, c-format
940msgid "You can't specify more than one output-specific argument\n"
941msgstr ""
942"Você não pode especificar mais do que um parâmetro --cpu e/ou\n"
943"mais do que um argumento de saída específico\n"
944
945#~ msgid ""
946#~ " -c CPU, --cpu CPU CPU number which information shall be determined "
947#~ "about\n"
948#~ msgstr ""
949#~ " -c CPU, --cpu CPU número do CPU sobre o qual as inforções devem ser "
950#~ "determinadas\n"
951
952#~ msgid ""
953#~ " -c CPU, --cpu CPU number of CPU where cpufreq settings shall be "
954#~ "modified\n"
955#~ msgstr ""
956#~ " -c CPU, --cpu CPU número do CPU onde as configurações do cpufreq "
957#~ "vão ser modificadas\n"
diff --git a/tools/power/cpupower/utils/builtin.h b/tools/power/cpupower/utils/builtin.h
new file mode 100644
index 000000000000..c870ffba5219
--- /dev/null
+++ b/tools/power/cpupower/utils/builtin.h
@@ -0,0 +1,18 @@
1#ifndef BUILTIN_H
2#define BUILTIN_H
3
4extern int cmd_set(int argc, const char **argv);
5extern int cmd_info(int argc, const char **argv);
6extern int cmd_freq_set(int argc, const char **argv);
7extern int cmd_freq_info(int argc, const char **argv);
8extern int cmd_idle_info(int argc, const char **argv);
9extern int cmd_monitor(int argc, const char **argv);
10
11extern void set_help(void);
12extern void info_help(void);
13extern void freq_set_help(void);
14extern void freq_info_help(void);
15extern void idle_info_help(void);
16extern void monitor_help(void);
17
18#endif
diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c
new file mode 100644
index 000000000000..5a1d25f056b3
--- /dev/null
+++ b/tools/power/cpupower/utils/cpufreq-info.c
@@ -0,0 +1,708 @@
1/*
2 * (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.de>
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 */
6
7
8#include <unistd.h>
9#include <stdio.h>
10#include <errno.h>
11#include <stdlib.h>
12#include <string.h>
13
14#include <getopt.h>
15
16#include "cpufreq.h"
17#include "helpers/helpers.h"
18#include "helpers/bitmask.h"
19
20#define LINE_LEN 10
21
22static unsigned int count_cpus(void)
23{
24 FILE *fp;
25 char value[LINE_LEN];
26 unsigned int ret = 0;
27 unsigned int cpunr = 0;
28
29 fp = fopen("/proc/stat", "r");
30 if (!fp) {
31 printf(_("Couldn't count the number of CPUs (%s: %s), assuming 1\n"), "/proc/stat", strerror(errno));
32 return 1;
33 }
34
35 while (!feof(fp)) {
36 if (!fgets(value, LINE_LEN, fp))
37 continue;
38 value[LINE_LEN - 1] = '\0';
39 if (strlen(value) < (LINE_LEN - 2))
40 continue;
41 if (strstr(value, "cpu "))
42 continue;
43 if (sscanf(value, "cpu%d ", &cpunr) != 1)
44 continue;
45 if (cpunr > ret)
46 ret = cpunr;
47 }
48 fclose(fp);
49
50 /* cpu count starts from 0, on error return 1 (UP) */
51 return ret + 1;
52}
53
54
55static void proc_cpufreq_output(void)
56{
57 unsigned int cpu, nr_cpus;
58 struct cpufreq_policy *policy;
59 unsigned int min_pctg = 0;
60 unsigned int max_pctg = 0;
61 unsigned long min, max;
62
63 printf(_(" minimum CPU frequency - maximum CPU frequency - governor\n"));
64
65 nr_cpus = count_cpus();
66 for (cpu = 0; cpu < nr_cpus; cpu++) {
67 policy = cpufreq_get_policy(cpu);
68 if (!policy)
69 continue;
70
71 if (cpufreq_get_hardware_limits(cpu, &min, &max)) {
72 max = 0;
73 } else {
74 min_pctg = (policy->min * 100) / max;
75 max_pctg = (policy->max * 100) / max;
76 }
77 printf("CPU%3d %9lu kHz (%3d %%) - %9lu kHz (%3d %%) - %s\n",
78 cpu , policy->min, max ? min_pctg : 0, policy->max,
79 max ? max_pctg : 0, policy->governor);
80
81 cpufreq_put_policy(policy);
82 }
83}
84
85static void print_speed(unsigned long speed)
86{
87 unsigned long tmp;
88
89 if (speed > 1000000) {
90 tmp = speed % 10000;
91 if (tmp >= 5000)
92 speed += 10000;
93 printf("%u.%02u GHz", ((unsigned int) speed/1000000),
94 ((unsigned int) (speed%1000000)/10000));
95 } else if (speed > 100000) {
96 tmp = speed % 1000;
97 if (tmp >= 500)
98 speed += 1000;
99 printf("%u MHz", ((unsigned int) speed / 1000));
100 } else if (speed > 1000) {
101 tmp = speed % 100;
102 if (tmp >= 50)
103 speed += 100;
104 printf("%u.%01u MHz", ((unsigned int) speed/1000),
105 ((unsigned int) (speed%1000)/100));
106 } else
107 printf("%lu kHz", speed);
108
109 return;
110}
111
112static void print_duration(unsigned long duration)
113{
114 unsigned long tmp;
115
116 if (duration > 1000000) {
117 tmp = duration % 10000;
118 if (tmp >= 5000)
119 duration += 10000;
120 printf("%u.%02u ms", ((unsigned int) duration/1000000),
121 ((unsigned int) (duration%1000000)/10000));
122 } else if (duration > 100000) {
123 tmp = duration % 1000;
124 if (tmp >= 500)
125 duration += 1000;
126 printf("%u us", ((unsigned int) duration / 1000));
127 } else if (duration > 1000) {
128 tmp = duration % 100;
129 if (tmp >= 50)
130 duration += 100;
131 printf("%u.%01u us", ((unsigned int) duration/1000),
132 ((unsigned int) (duration%1000)/100));
133 } else
134 printf("%lu ns", duration);
135
136 return;
137}
138
139/* --boost / -b */
140
141static int get_boost_mode(unsigned int cpu)
142{
143 int support, active, b_states = 0, ret, pstate_no, i;
144 /* ToDo: Make this more global */
145 unsigned long pstates[MAX_HW_PSTATES] = {0,};
146
147 if (cpupower_cpu_info.vendor != X86_VENDOR_AMD &&
148 cpupower_cpu_info.vendor != X86_VENDOR_INTEL)
149 return 0;
150
151 ret = cpufreq_has_boost_support(cpu, &support, &active, &b_states);
152 if (ret) {
153 printf(_("Error while evaluating Boost Capabilities"
154 " on CPU %d -- are you root?\n"), cpu);
155 return ret;
156 }
157 /* P state changes via MSR are identified via cpuid 80000007
158 on Intel and AMD, but we assume boost capable machines can do that
159 if (cpuid_eax(0x80000000) >= 0x80000007
160 && (cpuid_edx(0x80000007) & (1 << 7)))
161 */
162
163 printf(_(" boost state support:\n"));
164
165 printf(_(" Supported: %s\n"), support ? _("yes") : _("no"));
166 printf(_(" Active: %s\n"), active ? _("yes") : _("no"));
167
168 if (cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
169 cpupower_cpu_info.family >= 0x10) {
170 ret = decode_pstates(cpu, cpupower_cpu_info.family, b_states,
171 pstates, &pstate_no);
172 if (ret)
173 return ret;
174
175 printf(_(" Boost States: %d\n"), b_states);
176 printf(_(" Total States: %d\n"), pstate_no);
177 for (i = 0; i < pstate_no; i++) {
178 if (i < b_states)
179 printf(_(" Pstate-Pb%d: %luMHz (boost state)"
180 "\n"), i, pstates[i]);
181 else
182 printf(_(" Pstate-P%d: %luMHz\n"),
183 i - b_states, pstates[i]);
184 }
185 } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_HAS_TURBO_RATIO) {
186 double bclk;
187 unsigned long long intel_turbo_ratio = 0;
188 unsigned int ratio;
189
190 /* Any way to autodetect this ? */
191 if (cpupower_cpu_info.caps & CPUPOWER_CAP_IS_SNB)
192 bclk = 100.00;
193 else
194 bclk = 133.33;
195 intel_turbo_ratio = msr_intel_get_turbo_ratio(cpu);
196 dprint (" Ratio: 0x%llx - bclk: %f\n",
197 intel_turbo_ratio, bclk);
198
199 ratio = (intel_turbo_ratio >> 24) & 0xFF;
200 if (ratio)
201 printf(_(" %.0f MHz max turbo 4 active cores\n"),
202 ratio * bclk);
203
204 ratio = (intel_turbo_ratio >> 16) & 0xFF;
205 if (ratio)
206 printf(_(" %.0f MHz max turbo 3 active cores\n"),
207 ratio * bclk);
208
209 ratio = (intel_turbo_ratio >> 8) & 0xFF;
210 if (ratio)
211 printf(_(" %.0f MHz max turbo 2 active cores\n"),
212 ratio * bclk);
213
214 ratio = (intel_turbo_ratio >> 0) & 0xFF;
215 if (ratio)
216 printf(_(" %.0f MHz max turbo 1 active cores\n"),
217 ratio * bclk);
218 }
219 return 0;
220}
221
222static void debug_output_one(unsigned int cpu)
223{
224 char *driver;
225 struct cpufreq_affected_cpus *cpus;
226 struct cpufreq_available_frequencies *freqs;
227 unsigned long min, max, freq_kernel, freq_hardware;
228 unsigned long total_trans, latency;
229 unsigned long long total_time;
230 struct cpufreq_policy *policy;
231 struct cpufreq_available_governors *governors;
232 struct cpufreq_stats *stats;
233
234 if (cpufreq_cpu_exists(cpu))
235 return;
236
237 freq_kernel = cpufreq_get_freq_kernel(cpu);
238 freq_hardware = cpufreq_get_freq_hardware(cpu);
239
240 driver = cpufreq_get_driver(cpu);
241 if (!driver) {
242 printf(_(" no or unknown cpufreq driver is active on this CPU\n"));
243 } else {
244 printf(_(" driver: %s\n"), driver);
245 cpufreq_put_driver(driver);
246 }
247
248 cpus = cpufreq_get_related_cpus(cpu);
249 if (cpus) {
250 printf(_(" CPUs which run at the same hardware frequency: "));
251 while (cpus->next) {
252 printf("%d ", cpus->cpu);
253 cpus = cpus->next;
254 }
255 printf("%d\n", cpus->cpu);
256 cpufreq_put_related_cpus(cpus);
257 }
258
259 cpus = cpufreq_get_affected_cpus(cpu);
260 if (cpus) {
261 printf(_(" CPUs which need to have their frequency coordinated by software: "));
262 while (cpus->next) {
263 printf("%d ", cpus->cpu);
264 cpus = cpus->next;
265 }
266 printf("%d\n", cpus->cpu);
267 cpufreq_put_affected_cpus(cpus);
268 }
269
270 latency = cpufreq_get_transition_latency(cpu);
271 if (latency) {
272 printf(_(" maximum transition latency: "));
273 print_duration(latency);
274 printf(".\n");
275 }
276
277 if (!(cpufreq_get_hardware_limits(cpu, &min, &max))) {
278 printf(_(" hardware limits: "));
279 print_speed(min);
280 printf(" - ");
281 print_speed(max);
282 printf("\n");
283 }
284
285 freqs = cpufreq_get_available_frequencies(cpu);
286 if (freqs) {
287 printf(_(" available frequency steps: "));
288 while (freqs->next) {
289 print_speed(freqs->frequency);
290 printf(", ");
291 freqs = freqs->next;
292 }
293 print_speed(freqs->frequency);
294 printf("\n");
295 cpufreq_put_available_frequencies(freqs);
296 }
297
298 governors = cpufreq_get_available_governors(cpu);
299 if (governors) {
300 printf(_(" available cpufreq governors: "));
301 while (governors->next) {
302 printf("%s, ", governors->governor);
303 governors = governors->next;
304 }
305 printf("%s\n", governors->governor);
306 cpufreq_put_available_governors(governors);
307 }
308
309 policy = cpufreq_get_policy(cpu);
310 if (policy) {
311 printf(_(" current policy: frequency should be within "));
312 print_speed(policy->min);
313 printf(_(" and "));
314 print_speed(policy->max);
315
316 printf(".\n ");
317 printf(_("The governor \"%s\" may"
318 " decide which speed to use\n within this range.\n"),
319 policy->governor);
320 cpufreq_put_policy(policy);
321 }
322
323 if (freq_kernel || freq_hardware) {
324 printf(_(" current CPU frequency is "));
325 if (freq_hardware) {
326 print_speed(freq_hardware);
327 printf(_(" (asserted by call to hardware)"));
328 } else
329 print_speed(freq_kernel);
330 printf(".\n");
331 }
332 stats = cpufreq_get_stats(cpu, &total_time);
333 if (stats) {
334 printf(_(" cpufreq stats: "));
335 while (stats) {
336 print_speed(stats->frequency);
337 printf(":%.2f%%", (100.0 * stats->time_in_state) / total_time);
338 stats = stats->next;
339 if (stats)
340 printf(", ");
341 }
342 cpufreq_put_stats(stats);
343 total_trans = cpufreq_get_transitions(cpu);
344 if (total_trans)
345 printf(" (%lu)\n", total_trans);
346 else
347 printf("\n");
348 }
349 get_boost_mode(cpu);
350
351}
352
353/* --freq / -f */
354
355static int get_freq_kernel(unsigned int cpu, unsigned int human)
356{
357 unsigned long freq = cpufreq_get_freq_kernel(cpu);
358 if (!freq)
359 return -EINVAL;
360 if (human) {
361 print_speed(freq);
362 printf("\n");
363 } else
364 printf("%lu\n", freq);
365 return 0;
366}
367
368
369/* --hwfreq / -w */
370
371static int get_freq_hardware(unsigned int cpu, unsigned int human)
372{
373 unsigned long freq = cpufreq_get_freq_hardware(cpu);
374 if (!freq)
375 return -EINVAL;
376 if (human) {
377 print_speed(freq);
378 printf("\n");
379 } else
380 printf("%lu\n", freq);
381 return 0;
382}
383
384/* --hwlimits / -l */
385
386static int get_hardware_limits(unsigned int cpu)
387{
388 unsigned long min, max;
389 if (cpufreq_get_hardware_limits(cpu, &min, &max))
390 return -EINVAL;
391 printf("%lu %lu\n", min, max);
392 return 0;
393}
394
395/* --driver / -d */
396
397static int get_driver(unsigned int cpu)
398{
399 char *driver = cpufreq_get_driver(cpu);
400 if (!driver)
401 return -EINVAL;
402 printf("%s\n", driver);
403 cpufreq_put_driver(driver);
404 return 0;
405}
406
407/* --policy / -p */
408
409static int get_policy(unsigned int cpu)
410{
411 struct cpufreq_policy *policy = cpufreq_get_policy(cpu);
412 if (!policy)
413 return -EINVAL;
414 printf("%lu %lu %s\n", policy->min, policy->max, policy->governor);
415 cpufreq_put_policy(policy);
416 return 0;
417}
418
419/* --governors / -g */
420
421static int get_available_governors(unsigned int cpu)
422{
423 struct cpufreq_available_governors *governors =
424 cpufreq_get_available_governors(cpu);
425 if (!governors)
426 return -EINVAL;
427
428 while (governors->next) {
429 printf("%s ", governors->governor);
430 governors = governors->next;
431 }
432 printf("%s\n", governors->governor);
433 cpufreq_put_available_governors(governors);
434 return 0;
435}
436
437
438/* --affected-cpus / -a */
439
440static int get_affected_cpus(unsigned int cpu)
441{
442 struct cpufreq_affected_cpus *cpus = cpufreq_get_affected_cpus(cpu);
443 if (!cpus)
444 return -EINVAL;
445
446 while (cpus->next) {
447 printf("%d ", cpus->cpu);
448 cpus = cpus->next;
449 }
450 printf("%d\n", cpus->cpu);
451 cpufreq_put_affected_cpus(cpus);
452 return 0;
453}
454
455/* --related-cpus / -r */
456
457static int get_related_cpus(unsigned int cpu)
458{
459 struct cpufreq_affected_cpus *cpus = cpufreq_get_related_cpus(cpu);
460 if (!cpus)
461 return -EINVAL;
462
463 while (cpus->next) {
464 printf("%d ", cpus->cpu);
465 cpus = cpus->next;
466 }
467 printf("%d\n", cpus->cpu);
468 cpufreq_put_related_cpus(cpus);
469 return 0;
470}
471
472/* --stats / -s */
473
474static int get_freq_stats(unsigned int cpu, unsigned int human)
475{
476 unsigned long total_trans = cpufreq_get_transitions(cpu);
477 unsigned long long total_time;
478 struct cpufreq_stats *stats = cpufreq_get_stats(cpu, &total_time);
479 while (stats) {
480 if (human) {
481 print_speed(stats->frequency);
482 printf(":%.2f%%",
483 (100.0 * stats->time_in_state) / total_time);
484 } else
485 printf("%lu:%llu",
486 stats->frequency, stats->time_in_state);
487 stats = stats->next;
488 if (stats)
489 printf(", ");
490 }
491 cpufreq_put_stats(stats);
492 if (total_trans)
493 printf(" (%lu)\n", total_trans);
494 return 0;
495}
496
497/* --latency / -y */
498
499static int get_latency(unsigned int cpu, unsigned int human)
500{
501 unsigned long latency = cpufreq_get_transition_latency(cpu);
502 if (!latency)
503 return -EINVAL;
504
505 if (human) {
506 print_duration(latency);
507 printf("\n");
508 } else
509 printf("%lu\n", latency);
510 return 0;
511}
512
513void freq_info_help(void)
514{
515 printf(_("Usage: cpupower freqinfo [options]\n"));
516 printf(_("Options:\n"));
517 printf(_(" -e, --debug Prints out debug information [default]\n"));
518 printf(_(" -f, --freq Get frequency the CPU currently runs at, according\n"
519 " to the cpufreq core *\n"));
520 printf(_(" -w, --hwfreq Get frequency the CPU currently runs at, by reading\n"
521 " it from hardware (only available to root) *\n"));
522 printf(_(" -l, --hwlimits Determine the minimum and maximum CPU frequency allowed *\n"));
523 printf(_(" -d, --driver Determines the used cpufreq kernel driver *\n"));
524 printf(_(" -p, --policy Gets the currently used cpufreq policy *\n"));
525 printf(_(" -g, --governors Determines available cpufreq governors *\n"));
526 printf(_(" -r, --related-cpus Determines which CPUs run at the same hardware frequency *\n"));
527 printf(_(" -a, --affected-cpus Determines which CPUs need to have their frequency\n"
528 " coordinated by software *\n"));
529 printf(_(" -s, --stats Shows cpufreq statistics if available\n"));
530 printf(_(" -y, --latency Determines the maximum latency on CPU frequency changes *\n"));
531 printf(_(" -b, --boost Checks for turbo or boost modes *\n"));
532 printf(_(" -o, --proc Prints out information like provided by the /proc/cpufreq\n"
533 " interface in 2.4. and early 2.6. kernels\n"));
534 printf(_(" -m, --human human-readable output for the -f, -w, -s and -y parameters\n"));
535 printf(_(" -h, --help Prints out this screen\n"));
536
537 printf("\n");
538 printf(_("If no argument is given, full output about\n"
539 "cpufreq is printed which is useful e.g. for reporting bugs.\n\n"));
540 printf(_("By default info of CPU 0 is shown which can be overridden\n"
541 "with the cpupower --cpu main command option.\n"));
542}
543
544static struct option info_opts[] = {
545 { .name = "debug", .has_arg = no_argument, .flag = NULL, .val = 'e'},
546 { .name = "boost", .has_arg = no_argument, .flag = NULL, .val = 'b'},
547 { .name = "freq", .has_arg = no_argument, .flag = NULL, .val = 'f'},
548 { .name = "hwfreq", .has_arg = no_argument, .flag = NULL, .val = 'w'},
549 { .name = "hwlimits", .has_arg = no_argument, .flag = NULL, .val = 'l'},
550 { .name = "driver", .has_arg = no_argument, .flag = NULL, .val = 'd'},
551 { .name = "policy", .has_arg = no_argument, .flag = NULL, .val = 'p'},
552 { .name = "governors", .has_arg = no_argument, .flag = NULL, .val = 'g'},
553 { .name = "related-cpus", .has_arg = no_argument, .flag = NULL, .val = 'r'},
554 { .name = "affected-cpus",.has_arg = no_argument, .flag = NULL, .val = 'a'},
555 { .name = "stats", .has_arg = no_argument, .flag = NULL, .val = 's'},
556 { .name = "latency", .has_arg = no_argument, .flag = NULL, .val = 'y'},
557 { .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'},
558 { .name = "human", .has_arg = no_argument, .flag = NULL, .val = 'm'},
559 { .name = "help", .has_arg = no_argument, .flag = NULL, .val = 'h'},
560 { },
561};
562
563int cmd_freq_info(int argc, char **argv)
564{
565 extern char *optarg;
566 extern int optind, opterr, optopt;
567 int ret = 0, cont = 1;
568 unsigned int cpu = 0;
569 unsigned int human = 0;
570 int output_param = 0;
571
572 do {
573 ret = getopt_long(argc, argv, "hoefwldpgrasmyb", info_opts, NULL);
574 switch (ret) {
575 case '?':
576 output_param = '?';
577 cont = 0;
578 break;
579 case 'h':
580 output_param = 'h';
581 cont = 0;
582 break;
583 case -1:
584 cont = 0;
585 break;
586 case 'b':
587 case 'o':
588 case 'a':
589 case 'r':
590 case 'g':
591 case 'p':
592 case 'd':
593 case 'l':
594 case 'w':
595 case 'f':
596 case 'e':
597 case 's':
598 case 'y':
599 if (output_param) {
600 output_param = -1;
601 cont = 0;
602 break;
603 }
604 output_param = ret;
605 break;
606 case 'm':
607 if (human) {
608 output_param = -1;
609 cont = 0;
610 break;
611 }
612 human = 1;
613 break;
614 default:
615 fprintf(stderr, "invalid or unknown argument\n");
616 return EXIT_FAILURE;
617 }
618 } while (cont);
619
620 switch (output_param) {
621 case 'o':
622 if (!bitmask_isallclear(cpus_chosen)) {
623 printf(_("The argument passed to this tool can't be "
624 "combined with passing a --cpu argument\n"));
625 return -EINVAL;
626 }
627 break;
628 case 0:
629 output_param = 'e';
630 }
631
632 ret = 0;
633
634 /* Default is: show output of CPU 0 only */
635 if (bitmask_isallclear(cpus_chosen))
636 bitmask_setbit(cpus_chosen, 0);
637
638 switch (output_param) {
639 case -1:
640 printf(_("You can't specify more than one --cpu parameter and/or\n"
641 "more than one output-specific argument\n"));
642 return -EINVAL;
643 case '?':
644 printf(_("invalid or unknown argument\n"));
645 freq_info_help();
646 return -EINVAL;
647 case 'h':
648 freq_info_help();
649 return EXIT_SUCCESS;
650 case 'o':
651 proc_cpufreq_output();
652 return EXIT_SUCCESS;
653 }
654
655 for (cpu = bitmask_first(cpus_chosen);
656 cpu <= bitmask_last(cpus_chosen); cpu++) {
657
658 if (!bitmask_isbitset(cpus_chosen, cpu))
659 continue;
660 if (cpufreq_cpu_exists(cpu)) {
661 printf(_("couldn't analyze CPU %d as it doesn't seem to be present\n"), cpu);
662 continue;
663 }
664 printf(_("analyzing CPU %d:\n"), cpu);
665
666 switch (output_param) {
667 case 'b':
668 get_boost_mode(cpu);
669 break;
670 case 'e':
671 debug_output_one(cpu);
672 break;
673 case 'a':
674 ret = get_affected_cpus(cpu);
675 break;
676 case 'r':
677 ret = get_related_cpus(cpu);
678 break;
679 case 'g':
680 ret = get_available_governors(cpu);
681 break;
682 case 'p':
683 ret = get_policy(cpu);
684 break;
685 case 'd':
686 ret = get_driver(cpu);
687 break;
688 case 'l':
689 ret = get_hardware_limits(cpu);
690 break;
691 case 'w':
692 ret = get_freq_hardware(cpu, human);
693 break;
694 case 'f':
695 ret = get_freq_kernel(cpu, human);
696 break;
697 case 's':
698 ret = get_freq_stats(cpu, human);
699 break;
700 case 'y':
701 ret = get_latency(cpu, human);
702 break;
703 }
704 if (ret)
705 return ret;
706 }
707 return ret;
708}
diff --git a/tools/power/cpupower/utils/cpufreq-set.c b/tools/power/cpupower/utils/cpufreq-set.c
new file mode 100644
index 000000000000..5f783622bf31
--- /dev/null
+++ b/tools/power/cpupower/utils/cpufreq-set.c
@@ -0,0 +1,358 @@
1/*
2 * (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.de>
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 */
6
7
8#include <unistd.h>
9#include <stdio.h>
10#include <errno.h>
11#include <stdlib.h>
12#include <limits.h>
13#include <string.h>
14#include <ctype.h>
15
16#include <getopt.h>
17
18#include "cpufreq.h"
19#include "helpers/helpers.h"
20
21#define NORM_FREQ_LEN 32
22
23void freq_set_help(void)
24{
25 printf(_("Usage: cpupower frequency-set [options]\n"));
26 printf(_("Options:\n"));
27 printf(_(" -d FREQ, --min FREQ new minimum CPU frequency the governor may select\n"));
28 printf(_(" -u FREQ, --max FREQ new maximum CPU frequency the governor may select\n"));
29 printf(_(" -g GOV, --governor GOV new cpufreq governor\n"));
30 printf(_(" -f FREQ, --freq FREQ specific frequency to be set. Requires userspace\n"
31 " governor to be available and loaded\n"));
32 printf(_(" -r, --related Switches all hardware-related CPUs\n"));
33 printf(_(" -h, --help Prints out this screen\n"));
34 printf("\n");
35 printf(_("Notes:\n"
36 "1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n"));
37 printf(_("2. The -f FREQ, --freq FREQ parameter cannot be combined with any other parameter\n"
38 " except the -c CPU, --cpu CPU parameter\n"
39 "3. FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz\n"
40 " by postfixing the value with the wanted unit name, without any space\n"
41 " (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"));
42
43}
44
45static struct option set_opts[] = {
46 { .name = "min", .has_arg = required_argument, .flag = NULL, .val = 'd'},
47 { .name = "max", .has_arg = required_argument, .flag = NULL, .val = 'u'},
48 { .name = "governor", .has_arg = required_argument, .flag = NULL, .val = 'g'},
49 { .name = "freq", .has_arg = required_argument, .flag = NULL, .val = 'f'},
50 { .name = "help", .has_arg = no_argument, .flag = NULL, .val = 'h'},
51 { .name = "related", .has_arg = no_argument, .flag = NULL, .val='r'},
52 { },
53};
54
55static void print_error(void)
56{
57 printf(_("Error setting new values. Common errors:\n"
58 "- Do you have proper administration rights? (super-user?)\n"
59 "- Is the governor you requested available and modprobed?\n"
60 "- Trying to set an invalid policy?\n"
61 "- Trying to set a specific frequency, but userspace governor is not available,\n"
62 " for example because of hardware which cannot be set to a specific frequency\n"
63 " or because the userspace governor isn't loaded?\n"));
64};
65
66struct freq_units {
67 char *str_unit;
68 int power_of_ten;
69};
70
71const struct freq_units def_units[] = {
72 {"hz", -3},
73 {"khz", 0}, /* default */
74 {"mhz", 3},
75 {"ghz", 6},
76 {"thz", 9},
77 {NULL, 0}
78};
79
80static void print_unknown_arg(void)
81{
82 printf(_("invalid or unknown argument\n"));
83 freq_set_help();
84}
85
86static unsigned long string_to_frequency(const char *str)
87{
88 char normalized[NORM_FREQ_LEN];
89 const struct freq_units *unit;
90 const char *scan;
91 char *end;
92 unsigned long freq;
93 int power = 0, match_count = 0, i, cp, pad;
94
95 while (*str == '0')
96 str++;
97
98 for (scan = str; isdigit(*scan) || *scan == '.'; scan++) {
99 if (*scan == '.' && match_count == 0)
100 match_count = 1;
101 else if (*scan == '.' && match_count == 1)
102 return 0;
103 }
104
105 if (*scan) {
106 match_count = 0;
107 for (unit = def_units; unit->str_unit; unit++) {
108 for (i = 0;
109 scan[i] && tolower(scan[i]) == unit->str_unit[i];
110 ++i)
111 continue;
112 if (scan[i])
113 continue;
114 match_count++;
115 power = unit->power_of_ten;
116 }
117 if (match_count != 1)
118 return 0;
119 }
120
121 /* count the number of digits to be copied */
122 for (cp = 0; isdigit(str[cp]); cp++)
123 continue;
124
125 if (str[cp] == '.') {
126 while (power > -1 && isdigit(str[cp+1]))
127 cp++, power--;
128 }
129 if (power >= -1) /* not enough => pad */
130 pad = power + 1;
131 else /* to much => strip */
132 pad = 0, cp += power + 1;
133 /* check bounds */
134 if (cp <= 0 || cp + pad > NORM_FREQ_LEN - 1)
135 return 0;
136
137 /* copy digits */
138 for (i = 0; i < cp; i++, str++) {
139 if (*str == '.')
140 str++;
141 normalized[i] = *str;
142 }
143 /* and pad */
144 for (; i < cp + pad; i++)
145 normalized[i] = '0';
146
147 /* round up, down ? */
148 match_count = (normalized[i-1] >= '5');
149 /* and drop the decimal part */
150 normalized[i-1] = 0; /* cp > 0 && pad >= 0 ==> i > 0 */
151
152 /* final conversion (and applying rounding) */
153 errno = 0;
154 freq = strtoul(normalized, &end, 10);
155 if (errno)
156 return 0;
157 else {
158 if (match_count && freq != ULONG_MAX)
159 freq++;
160 return freq;
161 }
162}
163
164static int do_new_policy(unsigned int cpu, struct cpufreq_policy *new_pol)
165{
166 struct cpufreq_policy *cur_pol = cpufreq_get_policy(cpu);
167 int ret;
168
169 if (!cur_pol) {
170 printf(_("wrong, unknown or unhandled CPU?\n"));
171 return -EINVAL;
172 }
173
174 if (!new_pol->min)
175 new_pol->min = cur_pol->min;
176
177 if (!new_pol->max)
178 new_pol->max = cur_pol->max;
179
180 if (!new_pol->governor)
181 new_pol->governor = cur_pol->governor;
182
183 ret = cpufreq_set_policy(cpu, new_pol);
184
185 cpufreq_put_policy(cur_pol);
186
187 return ret;
188}
189
190
191static int do_one_cpu(unsigned int cpu, struct cpufreq_policy *new_pol,
192 unsigned long freq, unsigned int pc)
193{
194 switch (pc) {
195 case 0:
196 return cpufreq_set_frequency(cpu, freq);
197
198 case 1:
199 /* if only one value of a policy is to be changed, we can
200 * use a "fast path".
201 */
202 if (new_pol->min)
203 return cpufreq_modify_policy_min(cpu, new_pol->min);
204 else if (new_pol->max)
205 return cpufreq_modify_policy_max(cpu, new_pol->max);
206 else if (new_pol->governor)
207 return cpufreq_modify_policy_governor(cpu,
208 new_pol->governor);
209
210 default:
211 /* slow path */
212 return do_new_policy(cpu, new_pol);
213 }
214}
215
216int cmd_freq_set(int argc, char **argv)
217{
218 extern char *optarg;
219 extern int optind, opterr, optopt;
220 int ret = 0, cont = 1;
221 int double_parm = 0, related = 0, policychange = 0;
222 unsigned long freq = 0;
223 char gov[20];
224 unsigned int cpu;
225
226 struct cpufreq_policy new_pol = {
227 .min = 0,
228 .max = 0,
229 .governor = NULL,
230 };
231
232 /* parameter parsing */
233 do {
234 ret = getopt_long(argc, argv, "d:u:g:f:hr", set_opts, NULL);
235 switch (ret) {
236 case '?':
237 print_unknown_arg();
238 return -EINVAL;
239 case 'h':
240 freq_set_help();
241 return 0;
242 case -1:
243 cont = 0;
244 break;
245 case 'r':
246 if (related)
247 double_parm++;
248 related++;
249 break;
250 case 'd':
251 if (new_pol.min)
252 double_parm++;
253 policychange++;
254 new_pol.min = string_to_frequency(optarg);
255 if (new_pol.min == 0) {
256 print_unknown_arg();
257 return -EINVAL;
258 }
259 break;
260 case 'u':
261 if (new_pol.max)
262 double_parm++;
263 policychange++;
264 new_pol.max = string_to_frequency(optarg);
265 if (new_pol.max == 0) {
266 print_unknown_arg();
267 return -EINVAL;
268 }
269 break;
270 case 'f':
271 if (freq)
272 double_parm++;
273 freq = string_to_frequency(optarg);
274 if (freq == 0) {
275 print_unknown_arg();
276 return -EINVAL;
277 }
278 break;
279 case 'g':
280 if (new_pol.governor)
281 double_parm++;
282 policychange++;
283 if ((strlen(optarg) < 3) || (strlen(optarg) > 18)) {
284 print_unknown_arg();
285 return -EINVAL;
286 }
287 if ((sscanf(optarg, "%s", gov)) != 1) {
288 print_unknown_arg();
289 return -EINVAL;
290 }
291 new_pol.governor = gov;
292 break;
293 }
294 } while (cont);
295
296 /* parameter checking */
297 if (double_parm) {
298 printf("the same parameter was passed more than once\n");
299 return -EINVAL;
300 }
301
302 if (freq && policychange) {
303 printf(_("the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n"
304 "-g/--governor parameters\n"));
305 return -EINVAL;
306 }
307
308 if (!freq && !policychange) {
309 printf(_("At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n"
310 "-g/--governor must be passed\n"));
311 return -EINVAL;
312 }
313
314 /* Default is: set all CPUs */
315 if (bitmask_isallclear(cpus_chosen))
316 bitmask_setall(cpus_chosen);
317
318 /* Also set frequency settings for related CPUs if -r is passed */
319 if (related) {
320 for (cpu = bitmask_first(cpus_chosen);
321 cpu <= bitmask_last(cpus_chosen); cpu++) {
322 struct cpufreq_affected_cpus *cpus;
323
324 if (!bitmask_isbitset(cpus_chosen, cpu) ||
325 cpufreq_cpu_exists(cpu))
326 continue;
327
328 cpus = cpufreq_get_related_cpus(cpu);
329 if (!cpus)
330 break;
331 while (cpus->next) {
332 bitmask_setbit(cpus_chosen, cpus->cpu);
333 cpus = cpus->next;
334 }
335 cpufreq_put_related_cpus(cpus);
336 }
337 }
338
339
340 /* loop over CPUs */
341 for (cpu = bitmask_first(cpus_chosen);
342 cpu <= bitmask_last(cpus_chosen); cpu++) {
343
344 if (!bitmask_isbitset(cpus_chosen, cpu) ||
345 cpufreq_cpu_exists(cpu))
346 continue;
347
348 printf(_("Setting cpu: %d\n"), cpu);
349 ret = do_one_cpu(cpu, &new_pol, freq, policychange);
350 if (ret)
351 break;
352 }
353
354 if (ret)
355 print_error();
356
357 return ret;
358}
diff --git a/tools/power/cpupower/utils/cpuidle-info.c b/tools/power/cpupower/utils/cpuidle-info.c
new file mode 100644
index 000000000000..70da3574f1e9
--- /dev/null
+++ b/tools/power/cpupower/utils/cpuidle-info.c
@@ -0,0 +1,244 @@
1/*
2 * (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.de>
3 * (C) 2010 Thomas Renninger <trenn@suse.de>
4 *
5 * Licensed under the terms of the GNU GPL License version 2.
6 */
7
8
9#include <unistd.h>
10#include <stdio.h>
11#include <errno.h>
12#include <stdlib.h>
13#include <string.h>
14#include <getopt.h>
15#include <cpufreq.h>
16
17#include "helpers/helpers.h"
18#include "helpers/sysfs.h"
19#include "helpers/bitmask.h"
20
21#define LINE_LEN 10
22
23static void cpuidle_cpu_output(unsigned int cpu, int verbose)
24{
25 int idlestates, idlestate;
26 char *tmp;
27
28 printf(_ ("Analyzing CPU %d:\n"), cpu);
29
30 idlestates = sysfs_get_idlestate_count(cpu);
31 if (idlestates == 0) {
32 printf(_("CPU %u: No idle states\n"), cpu);
33 return;
34 } else if (idlestates <= 0) {
35 printf(_("CPU %u: Can't read idle state info\n"), cpu);
36 return;
37 }
38 tmp = sysfs_get_idlestate_name(cpu, idlestates - 1);
39 if (!tmp) {
40 printf(_("Could not determine max idle state %u\n"),
41 idlestates - 1);
42 return;
43 }
44
45 printf(_("Number of idle states: %d\n"), idlestates);
46
47 printf(_("Available idle states:"));
48 for (idlestate = 1; idlestate < idlestates; idlestate++) {
49 tmp = sysfs_get_idlestate_name(cpu, idlestate);
50 if (!tmp)
51 continue;
52 printf(" %s", tmp);
53 free(tmp);
54 }
55 printf("\n");
56
57 if (!verbose)
58 return;
59
60 for (idlestate = 1; idlestate < idlestates; idlestate++) {
61 tmp = sysfs_get_idlestate_name(cpu, idlestate);
62 if (!tmp)
63 continue;
64 printf("%s:\n", tmp);
65 free(tmp);
66
67 tmp = sysfs_get_idlestate_desc(cpu, idlestate);
68 if (!tmp)
69 continue;
70 printf(_("Flags/Description: %s\n"), tmp);
71 free(tmp);
72
73 printf(_("Latency: %lu\n"),
74 sysfs_get_idlestate_latency(cpu, idlestate));
75 printf(_("Usage: %lu\n"),
76 sysfs_get_idlestate_usage(cpu, idlestate));
77 printf(_("Duration: %llu\n"),
78 sysfs_get_idlestate_time(cpu, idlestate));
79 }
80 printf("\n");
81}
82
83static void cpuidle_general_output(void)
84{
85 char *tmp;
86
87 tmp = sysfs_get_cpuidle_driver();
88 if (!tmp) {
89 printf(_("Could not determine cpuidle driver\n"));
90 return;
91 }
92
93 printf(_("CPUidle driver: %s\n"), tmp);
94 free(tmp);
95
96 tmp = sysfs_get_cpuidle_governor();
97 if (!tmp) {
98 printf(_("Could not determine cpuidle governor\n"));
99 return;
100 }
101
102 printf(_("CPUidle governor: %s\n"), tmp);
103 free(tmp);
104}
105
106static void proc_cpuidle_cpu_output(unsigned int cpu)
107{
108 long max_allowed_cstate = 2000000000;
109 int cstates, cstate;
110
111 cstates = sysfs_get_idlestate_count(cpu);
112 if (cstates == 0) {
113 /*
114 * Go on and print same useless info as you'd see with
115 * cat /proc/acpi/processor/../power
116 * printf(_("CPU %u: No C-states available\n"), cpu);
117 * return;
118 */
119 } else if (cstates <= 0) {
120 printf(_("CPU %u: Can't read C-state info\n"), cpu);
121 return;
122 }
123 /* printf("Cstates: %d\n", cstates); */
124
125 printf(_("active state: C0\n"));
126 printf(_("max_cstate: C%u\n"), cstates-1);
127 printf(_("maximum allowed latency: %lu usec\n"), max_allowed_cstate);
128 printf(_("states:\t\n"));
129 for (cstate = 1; cstate < cstates; cstate++) {
130 printf(_(" C%d: "
131 "type[C%d] "), cstate, cstate);
132 printf(_("promotion[--] demotion[--] "));
133 printf(_("latency[%03lu] "),
134 sysfs_get_idlestate_latency(cpu, cstate));
135 printf(_("usage[%08lu] "),
136 sysfs_get_idlestate_usage(cpu, cstate));
137 printf(_("duration[%020Lu] \n"),
138 sysfs_get_idlestate_time(cpu, cstate));
139 }
140}
141
142/* --freq / -f */
143
144void idle_info_help(void)
145{
146 printf(_ ("Usage: cpupower idleinfo [options]\n"));
147 printf(_ ("Options:\n"));
148 printf(_ (" -s, --silent Only show general C-state information\n"));
149 printf(_ (" -o, --proc Prints out information like provided by the /proc/acpi/processor/*/power\n"
150 " interface in older kernels\n"));
151 printf(_ (" -h, --help Prints out this screen\n"));
152
153 printf("\n");
154}
155
156static struct option info_opts[] = {
157 { .name = "silent", .has_arg = no_argument, .flag = NULL, .val = 's'},
158 { .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'},
159 { .name = "help", .has_arg = no_argument, .flag = NULL, .val = 'h'},
160 { },
161};
162
163static inline void cpuidle_exit(int fail)
164{
165 idle_info_help();
166 exit(EXIT_FAILURE);
167}
168
169int cmd_idle_info(int argc, char **argv)
170{
171 extern char *optarg;
172 extern int optind, opterr, optopt;
173 int ret = 0, cont = 1, output_param = 0, verbose = 1;
174 unsigned int cpu = 0;
175
176 do {
177 ret = getopt_long(argc, argv, "hos", info_opts, NULL);
178 if (ret == -1)
179 break;
180 switch (ret) {
181 case '?':
182 output_param = '?';
183 cont = 0;
184 break;
185 case 'h':
186 output_param = 'h';
187 cont = 0;
188 break;
189 case 's':
190 verbose = 0;
191 break;
192 case -1:
193 cont = 0;
194 break;
195 case 'o':
196 if (output_param) {
197 output_param = -1;
198 cont = 0;
199 break;
200 }
201 output_param = ret;
202 break;
203 }
204 } while (cont);
205
206 switch (output_param) {
207 case -1:
208 printf(_("You can't specify more than one "
209 "output-specific argument\n"));
210 cpuidle_exit(EXIT_FAILURE);
211 case '?':
212 printf(_("invalid or unknown argument\n"));
213 cpuidle_exit(EXIT_FAILURE);
214 case 'h':
215 cpuidle_exit(EXIT_SUCCESS);
216 }
217
218 /* Default is: show output of CPU 0 only */
219 if (bitmask_isallclear(cpus_chosen))
220 bitmask_setbit(cpus_chosen, 0);
221
222 if (output_param == 0)
223 cpuidle_general_output();
224
225 for (cpu = bitmask_first(cpus_chosen);
226 cpu <= bitmask_last(cpus_chosen); cpu++) {
227
228 if (!bitmask_isbitset(cpus_chosen, cpu) ||
229 cpufreq_cpu_exists(cpu))
230 continue;
231
232 switch (output_param) {
233
234 case 'o':
235 proc_cpuidle_cpu_output(cpu);
236 break;
237 case 0:
238 printf("\n");
239 cpuidle_cpu_output(cpu, verbose);
240 break;
241 }
242 }
243 return EXIT_SUCCESS;
244}
diff --git a/tools/power/cpupower/utils/cpupower-info.c b/tools/power/cpupower/utils/cpupower-info.c
new file mode 100644
index 000000000000..85253cb7600e
--- /dev/null
+++ b/tools/power/cpupower/utils/cpupower-info.c
@@ -0,0 +1,153 @@
1/*
2 * (C) 2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 */
6
7
8#include <unistd.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <errno.h>
12#include <string.h>
13#include <getopt.h>
14
15#include <cpufreq.h>
16#include "helpers/helpers.h"
17#include "helpers/sysfs.h"
18
19void info_help(void)
20{
21 printf(_("Usage: cpupower info [ -b ] [ -m ] [ -s ]\n"));
22 printf(_("Options:\n"));
23 printf(_(" -b, --perf-bias Gets CPU's power vs performance policy on some\n"
24 " Intel models [0-15], see manpage for details\n"));
25 printf(_(" -m, --sched-mc Gets the kernel's multi core scheduler policy.\n"));
26 printf(_(" -s, --sched-smt Gets the kernel's thread sibling scheduler policy.\n"));
27 printf(_(" -h, --help Prints out this screen\n"));
28 printf(_("\nPassing no option will show all info, by default only on core 0\n"));
29 printf("\n");
30}
31
32static struct option set_opts[] = {
33 { .name = "perf-bias", .has_arg = optional_argument, .flag = NULL, .val = 'b'},
34 { .name = "sched-mc", .has_arg = optional_argument, .flag = NULL, .val = 'm'},
35 { .name = "sched-smt", .has_arg = optional_argument, .flag = NULL, .val = 's'},
36 { .name = "help", .has_arg = no_argument, .flag = NULL, .val = 'h'},
37 { },
38};
39
40static void print_wrong_arg_exit(void)
41{
42 printf(_("invalid or unknown argument\n"));
43 info_help();
44 exit(EXIT_FAILURE);
45}
46
47int cmd_info(int argc, char **argv)
48{
49 extern char *optarg;
50 extern int optind, opterr, optopt;
51 unsigned int cpu;
52
53 union {
54 struct {
55 int sched_mc:1;
56 int sched_smt:1;
57 int perf_bias:1;
58 };
59 int params;
60 } params = {};
61 int ret = 0;
62
63 setlocale(LC_ALL, "");
64 textdomain(PACKAGE);
65
66 /* parameter parsing */
67 while ((ret = getopt_long(argc, argv, "msbh", set_opts, NULL)) != -1) {
68 switch (ret) {
69 case 'h':
70 info_help();
71 return 0;
72 case 'b':
73 if (params.perf_bias)
74 print_wrong_arg_exit();
75 params.perf_bias = 1;
76 break;
77 case 'm':
78 if (params.sched_mc)
79 print_wrong_arg_exit();
80 params.sched_mc = 1;
81 break;
82 case 's':
83 if (params.sched_smt)
84 print_wrong_arg_exit();
85 params.sched_smt = 1;
86 break;
87 default:
88 print_wrong_arg_exit();
89 }
90 };
91
92 if (!params.params)
93 params.params = 0x7;
94
95 /* Default is: show output of CPU 0 only */
96 if (bitmask_isallclear(cpus_chosen))
97 bitmask_setbit(cpus_chosen, 0);
98
99 if (params.sched_mc) {
100 ret = sysfs_get_sched("mc");
101 printf(_("System's multi core scheduler setting: "));
102 if (ret < 0)
103 /* if sysfs file is missing it's: errno == ENOENT */
104 printf(_("not supported\n"));
105 else
106 printf("%d\n", ret);
107 }
108 if (params.sched_smt) {
109 ret = sysfs_get_sched("smt");
110 printf(_("System's thread sibling scheduler setting: "));
111 if (ret < 0)
112 /* if sysfs file is missing it's: errno == ENOENT */
113 printf(_("not supported\n"));
114 else
115 printf("%d\n", ret);
116 }
117
118 /* Add more per cpu options here */
119 if (!params.perf_bias)
120 return ret;
121
122 if (params.perf_bias) {
123 if (!run_as_root) {
124 params.perf_bias = 0;
125 printf(_("Intel's performance bias setting needs root privileges\n"));
126 } else if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS)) {
127 printf(_("System does not support Intel's performance"
128 " bias setting\n"));
129 params.perf_bias = 0;
130 }
131 }
132
133 /* loop over CPUs */
134 for (cpu = bitmask_first(cpus_chosen);
135 cpu <= bitmask_last(cpus_chosen); cpu++) {
136
137 if (!bitmask_isbitset(cpus_chosen, cpu) ||
138 cpufreq_cpu_exists(cpu))
139 continue;
140
141 printf(_("analyzing CPU %d:\n"), cpu);
142
143 if (params.perf_bias) {
144 ret = msr_intel_get_perf_bias(cpu);
145 if (ret < 0) {
146 printf(_("Could not read perf-bias value\n"));
147 break;
148 } else
149 printf(_("perf-bias: %d\n"), ret);
150 }
151 }
152 return ret;
153}
diff --git a/tools/power/cpupower/utils/cpupower-set.c b/tools/power/cpupower/utils/cpupower-set.c
new file mode 100644
index 000000000000..bc1b391e46f0
--- /dev/null
+++ b/tools/power/cpupower/utils/cpupower-set.c
@@ -0,0 +1,153 @@
1/*
2 * (C) 2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 */
6
7
8#include <unistd.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <errno.h>
12#include <string.h>
13#include <getopt.h>
14
15#include <cpufreq.h>
16#include "helpers/helpers.h"
17#include "helpers/sysfs.h"
18#include "helpers/bitmask.h"
19
20void set_help(void)
21{
22 printf(_("Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n"));
23 printf(_("Options:\n"));
24 printf(_(" -b, --perf-bias [VAL] Sets CPU's power vs performance policy on some\n"
25 " Intel models [0-15], see manpage for details\n"));
26 printf(_(" -m, --sched-mc [VAL] Sets the kernel's multi core scheduler policy.\n"));
27 printf(_(" -s, --sched-smt [VAL] Sets the kernel's thread sibling scheduler policy.\n"));
28 printf(_(" -h, --help Prints out this screen\n"));
29 printf("\n");
30}
31
32static struct option set_opts[] = {
33 { .name = "perf-bias", .has_arg = optional_argument, .flag = NULL, .val = 'b'},
34 { .name = "sched-mc", .has_arg = optional_argument, .flag = NULL, .val = 'm'},
35 { .name = "sched-smt", .has_arg = optional_argument, .flag = NULL, .val = 's'},
36 { .name = "help", .has_arg = no_argument, .flag = NULL, .val = 'h'},
37 { },
38};
39
40static void print_wrong_arg_exit(void)
41{
42 printf(_("invalid or unknown argument\n"));
43 set_help();
44 exit(EXIT_FAILURE);
45}
46
47int cmd_set(int argc, char **argv)
48{
49 extern char *optarg;
50 extern int optind, opterr, optopt;
51 unsigned int cpu;
52
53 union {
54 struct {
55 int sched_mc:1;
56 int sched_smt:1;
57 int perf_bias:1;
58 };
59 int params;
60 } params;
61 int sched_mc = 0, sched_smt = 0, perf_bias = 0;
62 int ret = 0;
63
64 setlocale(LC_ALL, "");
65 textdomain(PACKAGE);
66
67 params.params = 0;
68 /* parameter parsing */
69 while ((ret = getopt_long(argc, argv, "m:s:b:h",
70 set_opts, NULL)) != -1) {
71 switch (ret) {
72 case 'h':
73 set_help();
74 return 0;
75 case 'b':
76 if (params.perf_bias)
77 print_wrong_arg_exit();
78 perf_bias = atoi(optarg);
79 if (perf_bias < 0 || perf_bias > 15) {
80 printf(_("--perf-bias param out "
81 "of range [0-%d]\n"), 15);
82 print_wrong_arg_exit();
83 }
84 params.perf_bias = 1;
85 break;
86 case 'm':
87 if (params.sched_mc)
88 print_wrong_arg_exit();
89 sched_mc = atoi(optarg);
90 if (sched_mc < 0 || sched_mc > 2) {
91 printf(_("--sched-mc param out "
92 "of range [0-%d]\n"), 2);
93 print_wrong_arg_exit();
94 }
95 params.sched_mc = 1;
96 break;
97 case 's':
98 if (params.sched_smt)
99 print_wrong_arg_exit();
100 sched_smt = atoi(optarg);
101 if (sched_smt < 0 || sched_smt > 2) {
102 printf(_("--sched-smt param out "
103 "of range [0-%d]\n"), 2);
104 print_wrong_arg_exit();
105 }
106 params.sched_smt = 1;
107 break;
108 default:
109 print_wrong_arg_exit();
110 }
111 };
112
113 if (!params.params) {
114 set_help();
115 return -EINVAL;
116 }
117
118 if (params.sched_mc) {
119 ret = sysfs_set_sched("mc", sched_mc);
120 if (ret)
121 fprintf(stderr, _("Error setting sched-mc %s\n"),
122 (ret == -ENODEV) ? "not supported" : "");
123 }
124 if (params.sched_smt) {
125 ret = sysfs_set_sched("smt", sched_smt);
126 if (ret)
127 fprintf(stderr, _("Error setting sched-smt %s\n"),
128 (ret == -ENODEV) ? "not supported" : "");
129 }
130
131 /* Default is: set all CPUs */
132 if (bitmask_isallclear(cpus_chosen))
133 bitmask_setall(cpus_chosen);
134
135 /* loop over CPUs */
136 for (cpu = bitmask_first(cpus_chosen);
137 cpu <= bitmask_last(cpus_chosen); cpu++) {
138
139 if (!bitmask_isbitset(cpus_chosen, cpu) ||
140 cpufreq_cpu_exists(cpu))
141 continue;
142
143 if (params.perf_bias) {
144 ret = msr_intel_set_perf_bias(cpu, perf_bias);
145 if (ret) {
146 fprintf(stderr, _("Error setting perf-bias "
147 "value on CPU %d\n"), cpu);
148 break;
149 }
150 }
151 }
152 return ret;
153}
diff --git a/tools/power/cpupower/utils/cpupower.c b/tools/power/cpupower/utils/cpupower.c
new file mode 100644
index 000000000000..5844ae0f786f
--- /dev/null
+++ b/tools/power/cpupower/utils/cpupower.c
@@ -0,0 +1,203 @@
1/*
2 * (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 *
6 * Ideas taken over from the perf userspace tool (included in the Linus
7 * kernel git repo): subcommand builtins and param parsing.
8 */
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <unistd.h>
14
15#include "builtin.h"
16#include "helpers/helpers.h"
17#include "helpers/bitmask.h"
18
19struct cmd_struct {
20 const char *cmd;
21 int (*main)(int, const char **);
22 void (*usage)(void);
23 int needs_root;
24};
25
26#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
27
28int cmd_help(int argc, const char **argv);
29
30/* Global cpu_info object available for all binaries
31 * Info only retrieved from CPU 0
32 *
33 * Values will be zero/unknown on non X86 archs
34 */
35struct cpupower_cpu_info cpupower_cpu_info;
36int run_as_root;
37/* Affected cpus chosen by -c/--cpu param */
38struct bitmask *cpus_chosen;
39
40#ifdef DEBUG
41int be_verbose;
42#endif
43
44static void print_help(void);
45
46static struct cmd_struct commands[] = {
47 { "frequency-info", cmd_freq_info, freq_info_help, 0 },
48 { "frequency-set", cmd_freq_set, freq_set_help, 1 },
49 { "idle-info", cmd_idle_info, idle_info_help, 0 },
50 { "set", cmd_set, set_help, 1 },
51 { "info", cmd_info, info_help, 0 },
52 { "monitor", cmd_monitor, monitor_help, 0 },
53 { "help", cmd_help, print_help, 0 },
54 /* { "bench", cmd_bench, NULL, 1 }, */
55};
56
57int cmd_help(int argc, const char **argv)
58{
59 unsigned int i;
60
61 if (argc > 1) {
62 for (i = 0; i < ARRAY_SIZE(commands); i++) {
63 struct cmd_struct *p = commands + i;
64 if (strcmp(p->cmd, argv[1]))
65 continue;
66 if (p->usage) {
67 p->usage();
68 return EXIT_SUCCESS;
69 }
70 }
71 }
72 print_help();
73 if (argc == 1)
74 return EXIT_SUCCESS; /* cpupower help */
75 return EXIT_FAILURE;
76}
77
78static void print_help(void)
79{
80 unsigned int i;
81
82#ifdef DEBUG
83 printf(_("cpupower [ -d ][ -c cpulist ] subcommand [ARGS]\n"));
84 printf(_(" -d, --debug May increase output (stderr) on some subcommands\n"));
85#else
86 printf(_("cpupower [ -c cpulist ] subcommand [ARGS]\n"));
87#endif
88 printf(_("cpupower --version\n"));
89 printf(_("Supported subcommands are:\n"));
90 for (i = 0; i < ARRAY_SIZE(commands); i++)
91 printf("\t%s\n", commands[i].cmd);
92 printf(_("\nSome subcommands can make use of the -c cpulist option.\n"));
93 printf(_("Look at the general cpupower manpage how to use it\n"));
94 printf(_("and read up the subcommand's manpage whether it is supported.\n"));
95 printf(_("\nUse cpupower help subcommand for getting help for above subcommands.\n"));
96}
97
98static void print_version(void)
99{
100 printf(PACKAGE " " VERSION "\n");
101 printf(_("Report errors and bugs to %s, please.\n"), PACKAGE_BUGREPORT);
102}
103
104static void handle_options(int *argc, const char ***argv)
105{
106 int ret, x, new_argc = 0;
107
108 if (*argc < 1)
109 return;
110
111 for (x = 0; x < *argc && ((*argv)[x])[0] == '-'; x++) {
112 const char *param = (*argv)[x];
113 if (!strcmp(param, "-h") || !strcmp(param, "--help")) {
114 print_help();
115 exit(EXIT_SUCCESS);
116 } else if (!strcmp(param, "-c") || !strcmp(param, "--cpu")) {
117 if (*argc < 2) {
118 print_help();
119 exit(EXIT_FAILURE);
120 }
121 if (!strcmp((*argv)[x+1], "all"))
122 bitmask_setall(cpus_chosen);
123 else {
124 ret = bitmask_parselist(
125 (*argv)[x+1], cpus_chosen);
126 if (ret < 0) {
127 fprintf(stderr, _("Error parsing cpu "
128 "list\n"));
129 exit(EXIT_FAILURE);
130 }
131 }
132 x += 1;
133 /* Cut out param: cpupower -c 1 info -> cpupower info */
134 new_argc += 2;
135 continue;
136 } else if (!strcmp(param, "-v") ||
137 !strcmp(param, "--version")) {
138 print_version();
139 exit(EXIT_SUCCESS);
140#ifdef DEBUG
141 } else if (!strcmp(param, "-d") || !strcmp(param, "--debug")) {
142 be_verbose = 1;
143 new_argc++;
144 continue;
145#endif
146 } else {
147 fprintf(stderr, "Unknown option: %s\n", param);
148 print_help();
149 exit(EXIT_FAILURE);
150 }
151 }
152 *argc -= new_argc;
153 *argv += new_argc;
154}
155
156int main(int argc, const char *argv[])
157{
158 const char *cmd;
159 unsigned int i, ret;
160
161 cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
162
163 argc--;
164 argv += 1;
165
166 handle_options(&argc, &argv);
167
168 cmd = argv[0];
169
170 if (argc < 1) {
171 print_help();
172 return EXIT_FAILURE;
173 }
174
175 setlocale(LC_ALL, "");
176 textdomain(PACKAGE);
177
178 /* Turn "perf cmd --help" into "perf help cmd" */
179 if (argc > 1 && !strcmp(argv[1], "--help")) {
180 argv[1] = argv[0];
181 argv[0] = cmd = "help";
182 }
183
184 get_cpu_info(0, &cpupower_cpu_info);
185 run_as_root = !getuid();
186
187 for (i = 0; i < ARRAY_SIZE(commands); i++) {
188 struct cmd_struct *p = commands + i;
189 if (strcmp(p->cmd, cmd))
190 continue;
191 if (!run_as_root && p->needs_root) {
192 fprintf(stderr, _("Subcommand %s needs root "
193 "privileges\n"), cmd);
194 return EXIT_FAILURE;
195 }
196 ret = p->main(argc, argv);
197 if (cpus_chosen)
198 bitmask_free(cpus_chosen);
199 return ret;
200 }
201 print_help();
202 return EXIT_FAILURE;
203}
diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c
new file mode 100644
index 000000000000..87d5605bdda8
--- /dev/null
+++ b/tools/power/cpupower/utils/helpers/amd.c
@@ -0,0 +1,137 @@
1#if defined(__i386__) || defined(__x86_64__)
2#include <unistd.h>
3#include <errno.h>
4#include <stdio.h>
5#include <stdint.h>
6
7#include <pci/pci.h>
8
9#include "helpers/helpers.h"
10
11#define MSR_AMD_PSTATE_STATUS 0xc0010063
12#define MSR_AMD_PSTATE 0xc0010064
13#define MSR_AMD_PSTATE_LIMIT 0xc0010061
14
15union msr_pstate {
16 struct {
17 unsigned fid:6;
18 unsigned did:3;
19 unsigned vid:7;
20 unsigned res1:6;
21 unsigned nbdid:1;
22 unsigned res2:2;
23 unsigned nbvid:7;
24 unsigned iddval:8;
25 unsigned idddiv:2;
26 unsigned res3:21;
27 unsigned en:1;
28 } bits;
29 unsigned long long val;
30};
31
32static int get_did(int family, union msr_pstate pstate)
33{
34 int t;
35
36 if (family == 0x12)
37 t = pstate.val & 0xf;
38 else
39 t = pstate.bits.did;
40
41 return t;
42}
43
44static int get_cof(int family, union msr_pstate pstate)
45{
46 int t;
47 int fid, did;
48
49 did = get_did(family, pstate);
50
51 t = 0x10;
52 fid = pstate.bits.fid;
53 if (family == 0x11)
54 t = 0x8;
55
56 return (100 * (fid + t)) >> did;
57}
58
59/* Needs:
60 * cpu -> the cpu that gets evaluated
61 * cpu_family -> The cpu's family (0x10, 0x12,...)
62 * boots_states -> how much boost states the machines support
63 *
64 * Fills up:
65 * pstates -> a pointer to an array of size MAX_HW_PSTATES
66 * must be initialized with zeros.
67 * All available HW pstates (including boost states)
68 * no -> amount of pstates above array got filled up with
69 *
70 * returns zero on success, -1 on failure
71 */
72int decode_pstates(unsigned int cpu, unsigned int cpu_family,
73 int boost_states, unsigned long *pstates, int *no)
74{
75 int i, psmax, pscur;
76 union msr_pstate pstate;
77 unsigned long long val;
78
79 /* Only read out frequencies from HW when CPU might be boostable
80 to keep the code as short and clean as possible.
81 Otherwise frequencies are exported via ACPI tables.
82 */
83 if (cpu_family < 0x10 || cpu_family == 0x14)
84 return -1;
85
86 if (read_msr(cpu, MSR_AMD_PSTATE_LIMIT, &val))
87 return -1;
88
89 psmax = (val >> 4) & 0x7;
90
91 if (read_msr(cpu, MSR_AMD_PSTATE_STATUS, &val))
92 return -1;
93
94 pscur = val & 0x7;
95
96 pscur += boost_states;
97 psmax += boost_states;
98 for (i = 0; i <= psmax; i++) {
99 if (i >= MAX_HW_PSTATES) {
100 fprintf(stderr, "HW pstates [%d] exceeding max [%d]\n",
101 psmax, MAX_HW_PSTATES);
102 return -1;
103 }
104 if (read_msr(cpu, MSR_AMD_PSTATE + i, &pstate.val))
105 return -1;
106 pstates[i] = get_cof(cpu_family, pstate);
107 }
108 *no = i;
109 return 0;
110}
111
112int amd_pci_get_num_boost_states(int *active, int *states)
113{
114 struct pci_access *pci_acc;
115 int vendor_id = 0x1022;
116 int boost_dev_ids[4] = {0x1204, 0x1604, 0x1704, 0};
117 struct pci_dev *device;
118 uint8_t val = 0;
119
120 *active = *states = 0;
121
122 device = pci_acc_init(&pci_acc, vendor_id, boost_dev_ids);
123
124 if (device == NULL)
125 return -ENODEV;
126
127 val = pci_read_byte(device, 0x15c);
128 if (val & 3)
129 *active = 1;
130 else
131 *active = 0;
132 *states = (val >> 2) & 7;
133
134 pci_cleanup(pci_acc);
135 return 0;
136}
137#endif /* defined(__i386__) || defined(__x86_64__) */
diff --git a/tools/power/cpupower/utils/helpers/bitmask.c b/tools/power/cpupower/utils/helpers/bitmask.c
new file mode 100644
index 000000000000..5c074c60f904
--- /dev/null
+++ b/tools/power/cpupower/utils/helpers/bitmask.c
@@ -0,0 +1,292 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include <helpers/bitmask.h>
6
7/* How many bits in an unsigned long */
8#define bitsperlong (8 * sizeof(unsigned long))
9
10/* howmany(a,b) : how many elements of size b needed to hold all of a */
11#define howmany(x, y) (((x)+((y)-1))/(y))
12
13/* How many longs in mask of n bits */
14#define longsperbits(n) howmany(n, bitsperlong)
15
16#define max(a, b) ((a) > (b) ? (a) : (b))
17
18/*
19 * Allocate and free `struct bitmask *`
20 */
21
22/* Allocate a new `struct bitmask` with a size of n bits */
23struct bitmask *bitmask_alloc(unsigned int n)
24{
25 struct bitmask *bmp;
26
27 bmp = malloc(sizeof(*bmp));
28 if (bmp == 0)
29 return 0;
30 bmp->size = n;
31 bmp->maskp = calloc(longsperbits(n), sizeof(unsigned long));
32 if (bmp->maskp == 0) {
33 free(bmp);
34 return 0;
35 }
36 return bmp;
37}
38
39/* Free `struct bitmask` */
40void bitmask_free(struct bitmask *bmp)
41{
42 if (bmp == 0)
43 return;
44 free(bmp->maskp);
45 bmp->maskp = (unsigned long *)0xdeadcdef; /* double free tripwire */
46 free(bmp);
47}
48
49/*
50 * The routines _getbit() and _setbit() are the only
51 * routines that actually understand the layout of bmp->maskp[].
52 *
53 * On little endian architectures, this could simply be an array of
54 * bytes. But the kernel layout of bitmasks _is_ visible to userspace
55 * via the sched_(set/get)affinity calls in Linux 2.6, and on big
56 * endian architectures, it is painfully obvious that this is an
57 * array of unsigned longs.
58 */
59
60/* Return the value (0 or 1) of bit n in bitmask bmp */
61static unsigned int _getbit(const struct bitmask *bmp, unsigned int n)
62{
63 if (n < bmp->size)
64 return (bmp->maskp[n/bitsperlong] >> (n % bitsperlong)) & 1;
65 else
66 return 0;
67}
68
69/* Set bit n in bitmask bmp to value v (0 or 1) */
70static void _setbit(struct bitmask *bmp, unsigned int n, unsigned int v)
71{
72 if (n < bmp->size) {
73 if (v)
74 bmp->maskp[n/bitsperlong] |= 1UL << (n % bitsperlong);
75 else
76 bmp->maskp[n/bitsperlong] &=
77 ~(1UL << (n % bitsperlong));
78 }
79}
80
81/*
82 * When parsing bitmask lists, only allow numbers, separated by one
83 * of the allowed next characters.
84 *
85 * The parameter 'sret' is the return from a sscanf "%u%c". It is
86 * -1 if the sscanf input string was empty. It is 0 if the first
87 * character in the sscanf input string was not a decimal number.
88 * It is 1 if the unsigned number matching the "%u" was the end of the
89 * input string. It is 2 if one or more additional characters followed
90 * the matched unsigned number. If it is 2, then 'nextc' is the first
91 * character following the number. The parameter 'ok_next_chars'
92 * is the nul-terminated list of allowed next characters.
93 *
94 * The mask term just scanned was ok if and only if either the numbers
95 * matching the %u were all of the input or if the next character in
96 * the input past the numbers was one of the allowed next characters.
97 */
98static int scan_was_ok(int sret, char nextc, const char *ok_next_chars)
99{
100 return sret == 1 ||
101 (sret == 2 && strchr(ok_next_chars, nextc) != NULL);
102}
103
104static const char *nexttoken(const char *q, int sep)
105{
106 if (q)
107 q = strchr(q, sep);
108 if (q)
109 q++;
110 return q;
111}
112
113/* Set a single bit i in bitmask */
114struct bitmask *bitmask_setbit(struct bitmask *bmp, unsigned int i)
115{
116 _setbit(bmp, i, 1);
117 return bmp;
118}
119
120/* Set all bits in bitmask: bmp = ~0 */
121struct bitmask *bitmask_setall(struct bitmask *bmp)
122{
123 unsigned int i;
124 for (i = 0; i < bmp->size; i++)
125 _setbit(bmp, i, 1);
126 return bmp;
127}
128
129/* Clear all bits in bitmask: bmp = 0 */
130struct bitmask *bitmask_clearall(struct bitmask *bmp)
131{
132 unsigned int i;
133 for (i = 0; i < bmp->size; i++)
134 _setbit(bmp, i, 0);
135 return bmp;
136}
137
138/* True if all bits are clear */
139int bitmask_isallclear(const struct bitmask *bmp)
140{
141 unsigned int i;
142 for (i = 0; i < bmp->size; i++)
143 if (_getbit(bmp, i))
144 return 0;
145 return 1;
146}
147
148/* True if specified bit i is set */
149int bitmask_isbitset(const struct bitmask *bmp, unsigned int i)
150{
151 return _getbit(bmp, i);
152}
153
154/* Number of lowest set bit (min) */
155unsigned int bitmask_first(const struct bitmask *bmp)
156{
157 return bitmask_next(bmp, 0);
158}
159
160/* Number of highest set bit (max) */
161unsigned int bitmask_last(const struct bitmask *bmp)
162{
163 unsigned int i;
164 unsigned int m = bmp->size;
165 for (i = 0; i < bmp->size; i++)
166 if (_getbit(bmp, i))
167 m = i;
168 return m;
169}
170
171/* Number of next set bit at or above given bit i */
172unsigned int bitmask_next(const struct bitmask *bmp, unsigned int i)
173{
174 unsigned int n;
175 for (n = i; n < bmp->size; n++)
176 if (_getbit(bmp, n))
177 break;
178 return n;
179}
180
181/*
182 * Parses a comma-separated list of numbers and ranges of numbers,
183 * with optional ':%u' strides modifying ranges, into provided bitmask.
184 * Some examples of input lists and their equivalent simple list:
185 * Input Equivalent to
186 * 0-3 0,1,2,3
187 * 0-7:2 0,2,4,6
188 * 1,3,5-7 1,3,5,6,7
189 * 0-3:2,8-15:4 0,2,8,12
190 */
191int bitmask_parselist(const char *buf, struct bitmask *bmp)
192{
193 const char *p, *q;
194
195 bitmask_clearall(bmp);
196
197 q = buf;
198 while (p = q, q = nexttoken(q, ','), p) {
199 unsigned int a; /* begin of range */
200 unsigned int b; /* end of range */
201 unsigned int s; /* stride */
202 const char *c1, *c2; /* next tokens after '-' or ',' */
203 char nextc; /* char after sscanf %u match */
204 int sret; /* sscanf return (number of matches) */
205
206 sret = sscanf(p, "%u%c", &a, &nextc);
207 if (!scan_was_ok(sret, nextc, ",-"))
208 goto err;
209 b = a;
210 s = 1;
211 c1 = nexttoken(p, '-');
212 c2 = nexttoken(p, ',');
213 if (c1 != NULL && (c2 == NULL || c1 < c2)) {
214 sret = sscanf(c1, "%u%c", &b, &nextc);
215 if (!scan_was_ok(sret, nextc, ",:"))
216 goto err;
217 c1 = nexttoken(c1, ':');
218 if (c1 != NULL && (c2 == NULL || c1 < c2)) {
219 sret = sscanf(c1, "%u%c", &s, &nextc);
220 if (!scan_was_ok(sret, nextc, ","))
221 goto err;
222 }
223 }
224 if (!(a <= b))
225 goto err;
226 if (b >= bmp->size)
227 goto err;
228 while (a <= b) {
229 _setbit(bmp, a, 1);
230 a += s;
231 }
232 }
233 return 0;
234err:
235 bitmask_clearall(bmp);
236 return -1;
237}
238
239/*
240 * emit(buf, buflen, rbot, rtop, len)
241 *
242 * Helper routine for bitmask_displaylist(). Write decimal number
243 * or range to buf+len, suppressing output past buf+buflen, with optional
244 * comma-prefix. Return len of what would be written to buf, if it
245 * all fit.
246 */
247
248static inline int emit(char *buf, int buflen, int rbot, int rtop, int len)
249{
250 if (len > 0)
251 len += snprintf(buf + len, max(buflen - len, 0), ",");
252 if (rbot == rtop)
253 len += snprintf(buf + len, max(buflen - len, 0), "%d", rbot);
254 else
255 len += snprintf(buf + len, max(buflen - len, 0), "%d-%d",
256 rbot, rtop);
257 return len;
258}
259
260/*
261 * Write decimal list representation of bmp to buf.
262 *
263 * Output format is a comma-separated list of decimal numbers and
264 * ranges. Consecutively set bits are shown as two hyphen-separated
265 * decimal numbers, the smallest and largest bit numbers set in
266 * the range. Output format is compatible with the format
267 * accepted as input by bitmap_parselist().
268 *
269 * The return value is the number of characters which would be
270 * generated for the given input, excluding the trailing '\0', as
271 * per ISO C99.
272 */
273
274int bitmask_displaylist(char *buf, int buflen, const struct bitmask *bmp)
275{
276 int len = 0;
277 /* current bit is 'cur', most recently seen range is [rbot, rtop] */
278 unsigned int cur, rbot, rtop;
279
280 if (buflen > 0)
281 *buf = 0;
282 rbot = cur = bitmask_first(bmp);
283 while (cur < bmp->size) {
284 rtop = cur;
285 cur = bitmask_next(bmp, cur+1);
286 if (cur >= bmp->size || cur > rtop + 1) {
287 len = emit(buf, buflen, rbot, rtop, len);
288 rbot = cur;
289 }
290 }
291 return len;
292}
diff --git a/tools/power/cpupower/utils/helpers/bitmask.h b/tools/power/cpupower/utils/helpers/bitmask.h
new file mode 100644
index 000000000000..eb289df41053
--- /dev/null
+++ b/tools/power/cpupower/utils/helpers/bitmask.h
@@ -0,0 +1,33 @@
1#ifndef __CPUPOWER_BITMASK__
2#define __CPUPOWER_BITMASK__
3
4/* Taken over from libbitmask, a project initiated from sgi:
5 * Url: http://oss.sgi.com/projects/cpusets/
6 * Unfortunately it's not very widespread, therefore relevant parts are
7 * pasted here.
8 */
9
10struct bitmask {
11 unsigned int size;
12 unsigned long *maskp;
13};
14
15struct bitmask *bitmask_alloc(unsigned int n);
16void bitmask_free(struct bitmask *bmp);
17
18struct bitmask *bitmask_setbit(struct bitmask *bmp, unsigned int i);
19struct bitmask *bitmask_setall(struct bitmask *bmp);
20struct bitmask *bitmask_clearall(struct bitmask *bmp);
21
22unsigned int bitmask_first(const struct bitmask *bmp);
23unsigned int bitmask_next(const struct bitmask *bmp, unsigned int i);
24unsigned int bitmask_last(const struct bitmask *bmp);
25int bitmask_isallclear(const struct bitmask *bmp);
26int bitmask_isbitset(const struct bitmask *bmp, unsigned int i);
27
28int bitmask_parselist(const char *buf, struct bitmask *bmp);
29int bitmask_displaylist(char *buf, int len, const struct bitmask *bmp);
30
31
32
33#endif /*__CPUPOWER_BITMASK__ */
diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c
new file mode 100644
index 000000000000..906895d21cce
--- /dev/null
+++ b/tools/power/cpupower/utils/helpers/cpuid.c
@@ -0,0 +1,176 @@
1#include <stdio.h>
2#include <errno.h>
3#include <string.h>
4#include <unistd.h>
5#include <stdlib.h>
6
7#include "helpers/helpers.h"
8
9static const char *cpu_vendor_table[X86_VENDOR_MAX] = {
10 "Unknown", "GenuineIntel", "AuthenticAMD",
11};
12
13#if defined(__i386__) || defined(__x86_64__)
14
15/* from gcc */
16#include <cpuid.h>
17
18/*
19 * CPUID functions returning a single datum
20 *
21 * Define unsigned int cpuid_e[abcd]x(unsigned int op)
22 */
23#define cpuid_func(reg) \
24 unsigned int cpuid_##reg(unsigned int op) \
25 { \
26 unsigned int eax, ebx, ecx, edx; \
27 __cpuid(op, eax, ebx, ecx, edx); \
28 return reg; \
29 }
30cpuid_func(eax);
31cpuid_func(ebx);
32cpuid_func(ecx);
33cpuid_func(edx);
34
35#endif /* defined(__i386__) || defined(__x86_64__) */
36
37/* get_cpu_info
38 *
39 * Extract CPU vendor, family, model, stepping info from /proc/cpuinfo
40 *
41 * Returns 0 on success or a negativ error code
42 *
43 * TBD: Should there be a cpuid alternative for this if /proc is not mounted?
44 */
45int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info)
46{
47 FILE *fp;
48 char value[64];
49 unsigned int proc, x;
50 unsigned int unknown = 0xffffff;
51 unsigned int cpuid_level, ext_cpuid_level;
52
53 int ret = -EINVAL;
54
55 cpu_info->vendor = X86_VENDOR_UNKNOWN;
56 cpu_info->family = unknown;
57 cpu_info->model = unknown;
58 cpu_info->stepping = unknown;
59 cpu_info->caps = 0;
60
61 fp = fopen("/proc/cpuinfo", "r");
62 if (!fp)
63 return -EIO;
64
65 while (!feof(fp)) {
66 if (!fgets(value, 64, fp))
67 continue;
68 value[63 - 1] = '\0';
69
70 if (!strncmp(value, "processor\t: ", 12))
71 sscanf(value, "processor\t: %u", &proc);
72
73 if (proc != cpu)
74 continue;
75
76 /* Get CPU vendor */
77 if (!strncmp(value, "vendor_id", 9)) {
78 for (x = 1; x < X86_VENDOR_MAX; x++) {
79 if (strstr(value, cpu_vendor_table[x]))
80 cpu_info->vendor = x;
81 }
82 /* Get CPU family, etc. */
83 } else if (!strncmp(value, "cpu family\t: ", 13)) {
84 sscanf(value, "cpu family\t: %u",
85 &cpu_info->family);
86 } else if (!strncmp(value, "model\t\t: ", 9)) {
87 sscanf(value, "model\t\t: %u",
88 &cpu_info->model);
89 } else if (!strncmp(value, "stepping\t: ", 10)) {
90 sscanf(value, "stepping\t: %u",
91 &cpu_info->stepping);
92
93 /* Exit -> all values must have been set */
94 if (cpu_info->vendor == X86_VENDOR_UNKNOWN ||
95 cpu_info->family == unknown ||
96 cpu_info->model == unknown ||
97 cpu_info->stepping == unknown) {
98 ret = -EINVAL;
99 goto out;
100 }
101
102 ret = 0;
103 goto out;
104 }
105 }
106 ret = -ENODEV;
107out:
108 fclose(fp);
109 /* Get some useful CPU capabilities from cpuid */
110 if (cpu_info->vendor != X86_VENDOR_AMD &&
111 cpu_info->vendor != X86_VENDOR_INTEL)
112 return ret;
113
114 cpuid_level = cpuid_eax(0);
115 ext_cpuid_level = cpuid_eax(0x80000000);
116
117 /* Invariant TSC */
118 if (ext_cpuid_level >= 0x80000007 &&
119 (cpuid_edx(0x80000007) & (1 << 8)))
120 cpu_info->caps |= CPUPOWER_CAP_INV_TSC;
121
122 /* Aperf/Mperf registers support */
123 if (cpuid_level >= 6 && (cpuid_ecx(6) & 0x1))
124 cpu_info->caps |= CPUPOWER_CAP_APERF;
125
126 /* AMD Boost state enable/disable register */
127 if (cpu_info->vendor == X86_VENDOR_AMD) {
128 if (ext_cpuid_level >= 0x80000007 &&
129 (cpuid_edx(0x80000007) & (1 << 9)))
130 cpu_info->caps |= CPUPOWER_CAP_AMD_CBP;
131 }
132
133 if (cpu_info->vendor == X86_VENDOR_INTEL) {
134 if (cpuid_level >= 6 &&
135 (cpuid_eax(6) & (1 << 1)))
136 cpu_info->caps |= CPUPOWER_CAP_INTEL_IDA;
137 }
138
139 if (cpu_info->vendor == X86_VENDOR_INTEL) {
140 /* Intel's perf-bias MSR support */
141 if (cpuid_level >= 6 && (cpuid_ecx(6) & (1 << 3)))
142 cpu_info->caps |= CPUPOWER_CAP_PERF_BIAS;
143
144 /* Intel's Turbo Ratio Limit support */
145 if (cpu_info->family == 6) {
146 switch (cpu_info->model) {
147 case 0x1A: /* Core i7, Xeon 5500 series
148 * Bloomfield, Gainstown NHM-EP
149 */
150 case 0x1E: /* Core i7 and i5 Processor
151 * Clarksfield, Lynnfield, Jasper Forest
152 */
153 case 0x1F: /* Core i7 and i5 Processor - Nehalem */
154 case 0x25: /* Westmere Client
155 * Clarkdale, Arrandale
156 */
157 case 0x2C: /* Westmere EP - Gulftown */
158 cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
159 case 0x2A: /* SNB */
160 case 0x2D: /* SNB Xeon */
161 cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
162 cpu_info->caps |= CPUPOWER_CAP_IS_SNB;
163 break;
164 case 0x2E: /* Nehalem-EX Xeon - Beckton */
165 case 0x2F: /* Westmere-EX Xeon - Eagleton */
166 default:
167 break;
168 }
169 }
170 }
171
172 /* printf("ID: %u - Extid: 0x%x - Caps: 0x%llx\n",
173 cpuid_level, ext_cpuid_level, cpu_info->caps);
174 */
175 return ret;
176}
diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h
new file mode 100644
index 000000000000..592ee362b877
--- /dev/null
+++ b/tools/power/cpupower/utils/helpers/helpers.h
@@ -0,0 +1,178 @@
1/*
2 * (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 *
6 * Miscellaneous helpers which do not fit or are worth
7 * to put into separate headers
8 */
9
10#ifndef __CPUPOWERUTILS_HELPERS__
11#define __CPUPOWERUTILS_HELPERS__
12
13#include <libintl.h>
14#include <locale.h>
15
16#include "helpers/bitmask.h"
17
18/* Internationalization ****************************/
19#define _(String) gettext(String)
20#ifndef gettext_noop
21#define gettext_noop(String) String
22#endif
23#define N_(String) gettext_noop(String)
24/* Internationalization ****************************/
25
26extern int run_as_root;
27extern struct bitmask *cpus_chosen;
28
29/* Global verbose (-d) stuff *********************************/
30/*
31 * define DEBUG via global Makefile variable
32 * Debug output is sent to stderr, do:
33 * cpupower monitor 2>/tmp/debug
34 * to split debug output away from normal output
35*/
36#ifdef DEBUG
37extern int be_verbose;
38
39#define dprint(fmt, ...) { \
40 if (be_verbose) { \
41 fprintf(stderr, "%s: " fmt, \
42 __func__, ##__VA_ARGS__); \
43 } \
44 }
45#else
46static inline void dprint(const char *fmt, ...) { }
47#endif
48extern int be_verbose;
49/* Global verbose (-v) stuff *********************************/
50
51/* cpuid and cpuinfo helpers **************************/
52enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL,
53 X86_VENDOR_AMD, X86_VENDOR_MAX};
54
55#define CPUPOWER_CAP_INV_TSC 0x00000001
56#define CPUPOWER_CAP_APERF 0x00000002
57#define CPUPOWER_CAP_AMD_CBP 0x00000004
58#define CPUPOWER_CAP_PERF_BIAS 0x00000008
59#define CPUPOWER_CAP_HAS_TURBO_RATIO 0x00000010
60#define CPUPOWER_CAP_IS_SNB 0x00000011
61#define CPUPOWER_CAP_INTEL_IDA 0x00000012
62
63#define MAX_HW_PSTATES 10
64
65struct cpupower_cpu_info {
66 enum cpupower_cpu_vendor vendor;
67 unsigned int family;
68 unsigned int model;
69 unsigned int stepping;
70 /* CPU capabilities read out from cpuid */
71 unsigned long long caps;
72};
73
74/* get_cpu_info
75 *
76 * Extract CPU vendor, family, model, stepping info from /proc/cpuinfo
77 *
78 * Returns 0 on success or a negativ error code
79 * Only used on x86, below global's struct values are zero/unknown on
80 * other archs
81 */
82extern int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info);
83extern struct cpupower_cpu_info cpupower_cpu_info;
84/* cpuid and cpuinfo helpers **************************/
85
86
87/* CPU topology/hierarchy parsing ******************/
88struct cpupower_topology {
89 /* Amount of CPU cores, packages and threads per core in the system */
90 unsigned int cores;
91 unsigned int pkgs;
92 unsigned int threads; /* per core */
93
94 /* Array gets mallocated with cores entries, holding per core info */
95 struct {
96 int pkg;
97 int core;
98 int cpu;
99 } *core_info;
100};
101
102extern int get_cpu_topology(struct cpupower_topology *cpu_top);
103extern void cpu_topology_release(struct cpupower_topology cpu_top);
104/* CPU topology/hierarchy parsing ******************/
105
106/* X86 ONLY ****************************************/
107#if defined(__i386__) || defined(__x86_64__)
108
109#include <pci/pci.h>
110
111/* Read/Write msr ****************************/
112extern int read_msr(int cpu, unsigned int idx, unsigned long long *val);
113extern int write_msr(int cpu, unsigned int idx, unsigned long long val);
114
115extern int msr_intel_set_perf_bias(unsigned int cpu, unsigned int val);
116extern int msr_intel_get_perf_bias(unsigned int cpu);
117extern unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu);
118
119/* Read/Write msr ****************************/
120
121/* PCI stuff ****************************/
122extern int amd_pci_get_num_boost_states(int *active, int *states);
123extern struct pci_dev *pci_acc_init(struct pci_access **pacc, int vendor_id,
124 int *dev_ids);
125
126/* PCI stuff ****************************/
127
128/* AMD HW pstate decoding **************************/
129
130extern int decode_pstates(unsigned int cpu, unsigned int cpu_family,
131 int boost_states, unsigned long *pstates, int *no);
132
133/* AMD HW pstate decoding **************************/
134
135extern int cpufreq_has_boost_support(unsigned int cpu, int *support,
136 int *active, int * states);
137/*
138 * CPUID functions returning a single datum
139 */
140unsigned int cpuid_eax(unsigned int op);
141unsigned int cpuid_ebx(unsigned int op);
142unsigned int cpuid_ecx(unsigned int op);
143unsigned int cpuid_edx(unsigned int op);
144
145/* cpuid and cpuinfo helpers **************************/
146/* X86 ONLY ********************************************/
147#else
148static inline int decode_pstates(unsigned int cpu, unsigned int cpu_family,
149 int boost_states, unsigned long *pstates,
150 int *no)
151{ return -1; };
152
153static inline int read_msr(int cpu, unsigned int idx, unsigned long long *val)
154{ return -1; };
155static inline int write_msr(int cpu, unsigned int idx, unsigned long long val)
156{ return -1; };
157static inline int msr_intel_set_perf_bias(unsigned int cpu, unsigned int val)
158{ return -1; };
159static inline int msr_intel_get_perf_bias(unsigned int cpu)
160{ return -1; };
161static inline unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu)
162{ return 0; };
163
164/* Read/Write msr ****************************/
165
166static inline int cpufreq_has_boost_support(unsigned int cpu, int *support,
167 int *active, int * states)
168{ return -1; }
169
170/* cpuid and cpuinfo helpers **************************/
171
172static inline unsigned int cpuid_eax(unsigned int op) { return 0; };
173static inline unsigned int cpuid_ebx(unsigned int op) { return 0; };
174static inline unsigned int cpuid_ecx(unsigned int op) { return 0; };
175static inline unsigned int cpuid_edx(unsigned int op) { return 0; };
176#endif /* defined(__i386__) || defined(__x86_64__) */
177
178#endif /* __CPUPOWERUTILS_HELPERS__ */
diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c
new file mode 100644
index 000000000000..1609243f5c64
--- /dev/null
+++ b/tools/power/cpupower/utils/helpers/misc.c
@@ -0,0 +1,27 @@
1#if defined(__i386__) || defined(__x86_64__)
2
3#include "helpers/helpers.h"
4
5int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
6 int *states)
7{
8 struct cpupower_cpu_info cpu_info;
9 int ret;
10
11 *support = *active = *states = 0;
12
13 ret = get_cpu_info(0, &cpu_info);
14 if (ret)
15 return ret;
16
17 if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CBP) {
18 *support = 1;
19 amd_pci_get_num_boost_states(active, states);
20 if (ret <= 0)
21 return ret;
22 *support = 1;
23 } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_INTEL_IDA)
24 *support = *active = 1;
25 return 0;
26}
27#endif /* #if defined(__i386__) || defined(__x86_64__) */
diff --git a/tools/power/cpupower/utils/helpers/msr.c b/tools/power/cpupower/utils/helpers/msr.c
new file mode 100644
index 000000000000..31a4b24a8bc6
--- /dev/null
+++ b/tools/power/cpupower/utils/helpers/msr.c
@@ -0,0 +1,115 @@
1#if defined(__i386__) || defined(__x86_64__)
2
3#include <fcntl.h>
4#include <stdio.h>
5#include <unistd.h>
6#include <stdint.h>
7
8#include "helpers/helpers.h"
9
10/* Intel specific MSRs */
11#define MSR_IA32_PERF_STATUS 0x198
12#define MSR_IA32_MISC_ENABLES 0x1a0
13#define MSR_IA32_ENERGY_PERF_BIAS 0x1b0
14#define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x1ad
15
16/*
17 * read_msr
18 *
19 * Will return 0 on success and -1 on failure.
20 * Possible errno values could be:
21 * EFAULT -If the read/write did not fully complete
22 * EIO -If the CPU does not support MSRs
23 * ENXIO -If the CPU does not exist
24 */
25
26int read_msr(int cpu, unsigned int idx, unsigned long long *val)
27{
28 int fd;
29 char msr_file_name[64];
30
31 sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu);
32 fd = open(msr_file_name, O_RDONLY);
33 if (fd < 0)
34 return -1;
35 if (lseek(fd, idx, SEEK_CUR) == -1)
36 goto err;
37 if (read(fd, val, sizeof *val) != sizeof *val)
38 goto err;
39 close(fd);
40 return 0;
41 err:
42 close(fd);
43 return -1;
44}
45
46/*
47 * write_msr
48 *
49 * Will return 0 on success and -1 on failure.
50 * Possible errno values could be:
51 * EFAULT -If the read/write did not fully complete
52 * EIO -If the CPU does not support MSRs
53 * ENXIO -If the CPU does not exist
54 */
55int write_msr(int cpu, unsigned int idx, unsigned long long val)
56{
57 int fd;
58 char msr_file_name[64];
59
60 sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu);
61 fd = open(msr_file_name, O_WRONLY);
62 if (fd < 0)
63 return -1;
64 if (lseek(fd, idx, SEEK_CUR) == -1)
65 goto err;
66 if (write(fd, &val, sizeof val) != sizeof val)
67 goto err;
68 close(fd);
69 return 0;
70 err:
71 close(fd);
72 return -1;
73}
74
75int msr_intel_get_perf_bias(unsigned int cpu)
76{
77 unsigned long long val;
78 int ret;
79
80 if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS))
81 return -1;
82
83 ret = read_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &val);
84 if (ret)
85 return ret;
86 return val;
87}
88
89int msr_intel_set_perf_bias(unsigned int cpu, unsigned int val)
90{
91 int ret;
92
93 if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS))
94 return -1;
95
96 ret = write_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, val);
97 if (ret)
98 return ret;
99 return 0;
100}
101
102unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu)
103{
104 unsigned long long val;
105 int ret;
106
107 if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_HAS_TURBO_RATIO))
108 return -1;
109
110 ret = read_msr(cpu, MSR_NEHALEM_TURBO_RATIO_LIMIT, &val);
111 if (ret)
112 return ret;
113 return val;
114}
115#endif
diff --git a/tools/power/cpupower/utils/helpers/pci.c b/tools/power/cpupower/utils/helpers/pci.c
new file mode 100644
index 000000000000..cd2eb6fe41c4
--- /dev/null
+++ b/tools/power/cpupower/utils/helpers/pci.c
@@ -0,0 +1,44 @@
1#if defined(__i386__) || defined(__x86_64__)
2
3#include <helpers/helpers.h>
4
5/*
6 * pci_acc_init
7 *
8 * PCI access helper function depending on libpci
9 *
10 * **pacc : if a valid pci_dev is returned
11 * *pacc must be passed to pci_acc_cleanup to free it
12 *
13 * vendor_id : the pci vendor id matching the pci device to access
14 * dev_ids : device ids matching the pci device to access
15 *
16 * Returns :
17 * struct pci_dev which can be used with pci_{read,write}_* functions
18 * to access the PCI config space of matching pci devices
19 */
20struct pci_dev *pci_acc_init(struct pci_access **pacc, int vendor_id,
21 int *dev_ids)
22{
23 struct pci_filter filter_nb_link = { -1, -1, -1, -1, vendor_id, 0};
24 struct pci_dev *device;
25 unsigned int i;
26
27 *pacc = pci_alloc();
28 if (*pacc == NULL)
29 return NULL;
30
31 pci_init(*pacc);
32 pci_scan_bus(*pacc);
33
34 for (i = 0; dev_ids[i] != 0; i++) {
35 filter_nb_link.device = dev_ids[i];
36 for (device = (*pacc)->devices; device; device = device->next) {
37 if (pci_filter_match(&filter_nb_link, device))
38 return device;
39 }
40 }
41 pci_cleanup(*pacc);
42 return NULL;
43}
44#endif /* defined(__i386__) || defined(__x86_64__) */
diff --git a/tools/power/cpupower/utils/helpers/sysfs.c b/tools/power/cpupower/utils/helpers/sysfs.c
new file mode 100644
index 000000000000..55e2466674c6
--- /dev/null
+++ b/tools/power/cpupower/utils/helpers/sysfs.c
@@ -0,0 +1,358 @@
1/*
2 * (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.de>
3 * (C) 2011 Thomas Renninger <trenn@novell.com> Novell Inc.
4 *
5 * Licensed under the terms of the GNU GPL License version 2.
6 */
7
8#include <stdio.h>
9#include <errno.h>
10#include <stdlib.h>
11#include <string.h>
12#include <sys/types.h>
13#include <sys/stat.h>
14#include <fcntl.h>
15#include <unistd.h>
16
17#include "helpers/sysfs.h"
18
19unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen)
20{
21 int fd;
22 ssize_t numread;
23
24 fd = open(path, O_RDONLY);
25 if (fd == -1)
26 return 0;
27
28 numread = read(fd, buf, buflen - 1);
29 if (numread < 1) {
30 close(fd);
31 return 0;
32 }
33
34 buf[numread] = '\0';
35 close(fd);
36
37 return (unsigned int) numread;
38}
39
40static unsigned int sysfs_write_file(const char *path,
41 const char *value, size_t len)
42{
43 int fd;
44 ssize_t numwrite;
45
46 fd = open(path, O_WRONLY);
47 if (fd == -1)
48 return 0;
49
50 numwrite = write(fd, value, len);
51 if (numwrite < 1) {
52 close(fd);
53 return 0;
54 }
55 close(fd);
56 return (unsigned int) numwrite;
57}
58
59/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */
60
61/*
62 * helper function to read file from /sys into given buffer
63 * fname is a relative path under "cpuX/cpuidle/stateX/" dir
64 * cstates starting with 0, C0 is not counted as cstate.
65 * This means if you want C1 info, pass 0 as idlestate param
66 */
67unsigned int sysfs_idlestate_read_file(unsigned int cpu, unsigned int idlestate,
68 const char *fname, char *buf, size_t buflen)
69{
70 char path[SYSFS_PATH_MAX];
71 int fd;
72 ssize_t numread;
73
74 snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s",
75 cpu, idlestate, fname);
76
77 fd = open(path, O_RDONLY);
78 if (fd == -1)
79 return 0;
80
81 numread = read(fd, buf, buflen - 1);
82 if (numread < 1) {
83 close(fd);
84 return 0;
85 }
86
87 buf[numread] = '\0';
88 close(fd);
89
90 return (unsigned int) numread;
91}
92
93/* read access to files which contain one numeric value */
94
95enum idlestate_value {
96 IDLESTATE_USAGE,
97 IDLESTATE_POWER,
98 IDLESTATE_LATENCY,
99 IDLESTATE_TIME,
100 MAX_IDLESTATE_VALUE_FILES
101};
102
103static const char *idlestate_value_files[MAX_IDLESTATE_VALUE_FILES] = {
104 [IDLESTATE_USAGE] = "usage",
105 [IDLESTATE_POWER] = "power",
106 [IDLESTATE_LATENCY] = "latency",
107 [IDLESTATE_TIME] = "time",
108};
109
110static unsigned long long sysfs_idlestate_get_one_value(unsigned int cpu,
111 unsigned int idlestate,
112 enum idlestate_value which)
113{
114 unsigned long long value;
115 unsigned int len;
116 char linebuf[MAX_LINE_LEN];
117 char *endp;
118
119 if (which >= MAX_IDLESTATE_VALUE_FILES)
120 return 0;
121
122 len = sysfs_idlestate_read_file(cpu, idlestate,
123 idlestate_value_files[which],
124 linebuf, sizeof(linebuf));
125 if (len == 0)
126 return 0;
127
128 value = strtoull(linebuf, &endp, 0);
129
130 if (endp == linebuf || errno == ERANGE)
131 return 0;
132
133 return value;
134}
135
136/* read access to files which contain one string */
137
138enum idlestate_string {
139 IDLESTATE_DESC,
140 IDLESTATE_NAME,
141 MAX_IDLESTATE_STRING_FILES
142};
143
144static const char *idlestate_string_files[MAX_IDLESTATE_STRING_FILES] = {
145 [IDLESTATE_DESC] = "desc",
146 [IDLESTATE_NAME] = "name",
147};
148
149
150static char *sysfs_idlestate_get_one_string(unsigned int cpu,
151 unsigned int idlestate,
152 enum idlestate_string which)
153{
154 char linebuf[MAX_LINE_LEN];
155 char *result;
156 unsigned int len;
157
158 if (which >= MAX_IDLESTATE_STRING_FILES)
159 return NULL;
160
161 len = sysfs_idlestate_read_file(cpu, idlestate,
162 idlestate_string_files[which],
163 linebuf, sizeof(linebuf));
164 if (len == 0)
165 return NULL;
166
167 result = strdup(linebuf);
168 if (result == NULL)
169 return NULL;
170
171 if (result[strlen(result) - 1] == '\n')
172 result[strlen(result) - 1] = '\0';
173
174 return result;
175}
176
177unsigned long sysfs_get_idlestate_latency(unsigned int cpu,
178 unsigned int idlestate)
179{
180 return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_LATENCY);
181}
182
183unsigned long sysfs_get_idlestate_usage(unsigned int cpu,
184 unsigned int idlestate)
185{
186 return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_USAGE);
187}
188
189unsigned long long sysfs_get_idlestate_time(unsigned int cpu,
190 unsigned int idlestate)
191{
192 return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_TIME);
193}
194
195char *sysfs_get_idlestate_name(unsigned int cpu, unsigned int idlestate)
196{
197 return sysfs_idlestate_get_one_string(cpu, idlestate, IDLESTATE_NAME);
198}
199
200char *sysfs_get_idlestate_desc(unsigned int cpu, unsigned int idlestate)
201{
202 return sysfs_idlestate_get_one_string(cpu, idlestate, IDLESTATE_DESC);
203}
204
205/*
206 * Returns number of supported C-states of CPU core cpu
207 * Negativ in error case
208 * Zero if cpuidle does not export any C-states
209 */
210int sysfs_get_idlestate_count(unsigned int cpu)
211{
212 char file[SYSFS_PATH_MAX];
213 struct stat statbuf;
214 int idlestates = 1;
215
216
217 snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpuidle");
218 if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode))
219 return -ENODEV;
220
221 snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/cpuidle/state0", cpu);
222 if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode))
223 return 0;
224
225 while (stat(file, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) {
226 snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU
227 "cpu%u/cpuidle/state%d", cpu, idlestates);
228 idlestates++;
229 }
230 idlestates--;
231 return idlestates;
232}
233
234/* CPUidle general /sys/devices/system/cpu/cpuidle/ sysfs access ********/
235
236/*
237 * helper function to read file from /sys into given buffer
238 * fname is a relative path under "cpu/cpuidle/" dir
239 */
240static unsigned int sysfs_cpuidle_read_file(const char *fname, char *buf,
241 size_t buflen)
242{
243 char path[SYSFS_PATH_MAX];
244
245 snprintf(path, sizeof(path), PATH_TO_CPU "cpuidle/%s", fname);
246
247 return sysfs_read_file(path, buf, buflen);
248}
249
250
251
252/* read access to files which contain one string */
253
254enum cpuidle_string {
255 CPUIDLE_GOVERNOR,
256 CPUIDLE_GOVERNOR_RO,
257 CPUIDLE_DRIVER,
258 MAX_CPUIDLE_STRING_FILES
259};
260
261static const char *cpuidle_string_files[MAX_CPUIDLE_STRING_FILES] = {
262 [CPUIDLE_GOVERNOR] = "current_governor",
263 [CPUIDLE_GOVERNOR_RO] = "current_governor_ro",
264 [CPUIDLE_DRIVER] = "current_driver",
265};
266
267
268static char *sysfs_cpuidle_get_one_string(enum cpuidle_string which)
269{
270 char linebuf[MAX_LINE_LEN];
271 char *result;
272 unsigned int len;
273
274 if (which >= MAX_CPUIDLE_STRING_FILES)
275 return NULL;
276
277 len = sysfs_cpuidle_read_file(cpuidle_string_files[which],
278 linebuf, sizeof(linebuf));
279 if (len == 0)
280 return NULL;
281
282 result = strdup(linebuf);
283 if (result == NULL)
284 return NULL;
285
286 if (result[strlen(result) - 1] == '\n')
287 result[strlen(result) - 1] = '\0';
288
289 return result;
290}
291
292char *sysfs_get_cpuidle_governor(void)
293{
294 char *tmp = sysfs_cpuidle_get_one_string(CPUIDLE_GOVERNOR_RO);
295 if (!tmp)
296 return sysfs_cpuidle_get_one_string(CPUIDLE_GOVERNOR);
297 else
298 return tmp;
299}
300
301char *sysfs_get_cpuidle_driver(void)
302{
303 return sysfs_cpuidle_get_one_string(CPUIDLE_DRIVER);
304}
305/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */
306
307/*
308 * Get sched_mc or sched_smt settings
309 * Pass "mc" or "smt" as argument
310 *
311 * Returns negative value on failure
312 */
313int sysfs_get_sched(const char *smt_mc)
314{
315 unsigned long value;
316 char linebuf[MAX_LINE_LEN];
317 char *endp;
318 char path[SYSFS_PATH_MAX];
319
320 if (strcmp("mc", smt_mc) && strcmp("smt", smt_mc))
321 return -EINVAL;
322
323 snprintf(path, sizeof(path),
324 PATH_TO_CPU "sched_%s_power_savings", smt_mc);
325 if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0)
326 return -1;
327 value = strtoul(linebuf, &endp, 0);
328 if (endp == linebuf || errno == ERANGE)
329 return -1;
330 return value;
331}
332
333/*
334 * Get sched_mc or sched_smt settings
335 * Pass "mc" or "smt" as argument
336 *
337 * Returns negative value on failure
338 */
339int sysfs_set_sched(const char *smt_mc, int val)
340{
341 char linebuf[MAX_LINE_LEN];
342 char path[SYSFS_PATH_MAX];
343 struct stat statbuf;
344
345 if (strcmp("mc", smt_mc) && strcmp("smt", smt_mc))
346 return -EINVAL;
347
348 snprintf(path, sizeof(path),
349 PATH_TO_CPU "sched_%s_power_savings", smt_mc);
350 sprintf(linebuf, "%d", val);
351
352 if (stat(path, &statbuf) != 0)
353 return -ENODEV;
354
355 if (sysfs_write_file(path, linebuf, MAX_LINE_LEN) == 0)
356 return -1;
357 return 0;
358}
diff --git a/tools/power/cpupower/utils/helpers/sysfs.h b/tools/power/cpupower/utils/helpers/sysfs.h
new file mode 100644
index 000000000000..f9373e090637
--- /dev/null
+++ b/tools/power/cpupower/utils/helpers/sysfs.h
@@ -0,0 +1,28 @@
1#ifndef __CPUPOWER_HELPERS_SYSFS_H__
2#define __CPUPOWER_HELPERS_SYSFS_H__
3
4#define PATH_TO_CPU "/sys/devices/system/cpu/"
5#define MAX_LINE_LEN 255
6#define SYSFS_PATH_MAX 255
7
8extern unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen);
9
10extern unsigned long sysfs_get_idlestate_latency(unsigned int cpu,
11 unsigned int idlestate);
12extern unsigned long sysfs_get_idlestate_usage(unsigned int cpu,
13 unsigned int idlestate);
14extern unsigned long long sysfs_get_idlestate_time(unsigned int cpu,
15 unsigned int idlestate);
16extern char *sysfs_get_idlestate_name(unsigned int cpu,
17 unsigned int idlestate);
18extern char *sysfs_get_idlestate_desc(unsigned int cpu,
19 unsigned int idlestate);
20extern int sysfs_get_idlestate_count(unsigned int cpu);
21
22extern char *sysfs_get_cpuidle_governor(void);
23extern char *sysfs_get_cpuidle_driver(void);
24
25extern int sysfs_get_sched(const char *smt_mc);
26extern int sysfs_set_sched(const char *smt_mc, int val);
27
28#endif /* __CPUPOWER_HELPERS_SYSFS_H__ */
diff --git a/tools/power/cpupower/utils/helpers/topology.c b/tools/power/cpupower/utils/helpers/topology.c
new file mode 100644
index 000000000000..385ee5c7570c
--- /dev/null
+++ b/tools/power/cpupower/utils/helpers/topology.c
@@ -0,0 +1,108 @@
1/*
2 * (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 *
6 * ToDo: Needs to be done more properly for AMD/Intel specifics
7 */
8
9/* Helper struct for qsort, must be in sync with cpupower_topology.cpu_info */
10/* Be careful: Need to pass unsigned to the sort, so that offlined cores are
11 in the end, but double check for -1 for offlined cpus at other places */
12
13#include <stdlib.h>
14#include <stdio.h>
15#include <unistd.h>
16#include <errno.h>
17#include <fcntl.h>
18
19#include <helpers/helpers.h>
20#include <helpers/sysfs.h>
21
22/* returns -1 on failure, 0 on success */
23int sysfs_topology_read_file(unsigned int cpu, const char *fname)
24{
25 unsigned long value;
26 char linebuf[MAX_LINE_LEN];
27 char *endp;
28 char path[SYSFS_PATH_MAX];
29
30 snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/topology/%s",
31 cpu, fname);
32 if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0)
33 return -1;
34 value = strtoul(linebuf, &endp, 0);
35 if (endp == linebuf || errno == ERANGE)
36 return -1;
37 return value;
38}
39
40struct cpuid_core_info {
41 unsigned int pkg;
42 unsigned int thread;
43 unsigned int cpu;
44};
45
46static int __compare(const void *t1, const void *t2)
47{
48 struct cpuid_core_info *top1 = (struct cpuid_core_info *)t1;
49 struct cpuid_core_info *top2 = (struct cpuid_core_info *)t2;
50 if (top1->pkg < top2->pkg)
51 return -1;
52 else if (top1->pkg > top2->pkg)
53 return 1;
54 else if (top1->thread < top2->thread)
55 return -1;
56 else if (top1->thread > top2->thread)
57 return 1;
58 else if (top1->cpu < top2->cpu)
59 return -1;
60 else if (top1->cpu > top2->cpu)
61 return 1;
62 else
63 return 0;
64}
65
66/*
67 * Returns amount of cpus, negative on error, cpu_top must be
68 * passed to cpu_topology_release to free resources
69 *
70 * Array is sorted after ->pkg, ->core, then ->cpu
71 */
72int get_cpu_topology(struct cpupower_topology *cpu_top)
73{
74 int cpu, cpus = sysconf(_SC_NPROCESSORS_CONF);
75
76 cpu_top->core_info = malloc(sizeof(struct cpupower_topology) * cpus);
77 if (cpu_top->core_info == NULL)
78 return -ENOMEM;
79 cpu_top->pkgs = cpu_top->cores = 0;
80 for (cpu = 0; cpu < cpus; cpu++) {
81 cpu_top->core_info[cpu].pkg =
82 sysfs_topology_read_file(cpu, "physical_package_id");
83 if ((int)cpu_top->core_info[cpu].pkg != -1 &&
84 cpu_top->core_info[cpu].pkg > cpu_top->pkgs)
85 cpu_top->pkgs = cpu_top->core_info[cpu].pkg;
86 cpu_top->core_info[cpu].core =
87 sysfs_topology_read_file(cpu, "core_id");
88 cpu_top->core_info[cpu].cpu = cpu;
89 }
90 cpu_top->pkgs++;
91
92 qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info),
93 __compare);
94
95 /* Intel's cores count is not consecutively numbered, there may
96 * be a core_id of 3, but none of 2. Assume there always is 0
97 * Get amount of cores by counting duplicates in a package
98 for (cpu = 0; cpu_top->core_info[cpu].pkg = 0 && cpu < cpus; cpu++) {
99 if (cpu_top->core_info[cpu].core == 0)
100 cpu_top->cores++;
101 */
102 return cpus;
103}
104
105void cpu_topology_release(struct cpupower_topology cpu_top)
106{
107 free(cpu_top.core_info);
108}
diff --git a/tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c b/tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c
new file mode 100644
index 000000000000..202e555988be
--- /dev/null
+++ b/tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c
@@ -0,0 +1,338 @@
1/*
2 * (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 *
6 * PCI initialization based on example code from:
7 * Andreas Herrmann <andreas.herrmann3@amd.com>
8 */
9
10#if defined(__i386__) || defined(__x86_64__)
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <stdint.h>
15#include <time.h>
16#include <string.h>
17
18#include <pci/pci.h>
19
20#include "idle_monitor/cpupower-monitor.h"
21#include "helpers/helpers.h"
22
23/******** PCI parts could go into own file and get shared ***************/
24
25#define PCI_NON_PC0_OFFSET 0xb0
26#define PCI_PC1_OFFSET 0xb4
27#define PCI_PC6_OFFSET 0xb8
28
29#define PCI_MONITOR_ENABLE_REG 0xe0
30
31#define PCI_NON_PC0_ENABLE_BIT 0
32#define PCI_PC1_ENABLE_BIT 1
33#define PCI_PC6_ENABLE_BIT 2
34
35#define PCI_NBP1_STAT_OFFSET 0x98
36#define PCI_NBP1_ACTIVE_BIT 2
37#define PCI_NBP1_ENTERED_BIT 1
38
39#define PCI_NBP1_CAP_OFFSET 0x90
40#define PCI_NBP1_CAPABLE_BIT 31
41
42#define OVERFLOW_MS 343597 /* 32 bit register filled at 12500 HZ
43 (1 tick per 80ns) */
44
45enum amd_fam14h_states {NON_PC0 = 0, PC1, PC6, NBP1,
46 AMD_FAM14H_STATE_NUM};
47
48static int fam14h_get_count_percent(unsigned int self_id, double *percent,
49 unsigned int cpu);
50static int fam14h_nbp1_count(unsigned int id, unsigned long long *count,
51 unsigned int cpu);
52
53static cstate_t amd_fam14h_cstates[AMD_FAM14H_STATE_NUM] = {
54 {
55 .name = "!PC0",
56 .desc = N_("Package in sleep state (PC1 or deeper)"),
57 .id = NON_PC0,
58 .range = RANGE_PACKAGE,
59 .get_count_percent = fam14h_get_count_percent,
60 },
61 {
62 .name = "PC1",
63 .desc = N_("Processor Package C1"),
64 .id = PC1,
65 .range = RANGE_PACKAGE,
66 .get_count_percent = fam14h_get_count_percent,
67 },
68 {
69 .name = "PC6",
70 .desc = N_("Processor Package C6"),
71 .id = PC6,
72 .range = RANGE_PACKAGE,
73 .get_count_percent = fam14h_get_count_percent,
74 },
75 {
76 .name = "NBP1",
77 .desc = N_("North Bridge P1 boolean counter (returns 0 or 1)"),
78 .id = NBP1,
79 .range = RANGE_PACKAGE,
80 .get_count = fam14h_nbp1_count,
81 },
82};
83
84static struct pci_access *pci_acc;
85static int pci_vendor_id = 0x1022;
86static int pci_dev_ids[2] = {0x1716, 0};
87static struct pci_dev *amd_fam14h_pci_dev;
88
89static int nbp1_entered;
90
91struct timespec start_time;
92static unsigned long long timediff;
93
94#ifdef DEBUG
95struct timespec dbg_time;
96long dbg_timediff;
97#endif
98
99static unsigned long long *previous_count[AMD_FAM14H_STATE_NUM];
100static unsigned long long *current_count[AMD_FAM14H_STATE_NUM];
101
102static int amd_fam14h_get_pci_info(struct cstate *state,
103 unsigned int *pci_offset,
104 unsigned int *enable_bit,
105 unsigned int cpu)
106{
107 switch (state->id) {
108 case NON_PC0:
109 *enable_bit = PCI_NON_PC0_ENABLE_BIT;
110 *pci_offset = PCI_NON_PC0_OFFSET;
111 break;
112 case PC1:
113 *enable_bit = PCI_PC1_ENABLE_BIT;
114 *pci_offset = PCI_PC1_OFFSET;
115 break;
116 case PC6:
117 *enable_bit = PCI_PC6_ENABLE_BIT;
118 *pci_offset = PCI_PC6_OFFSET;
119 break;
120 case NBP1:
121 *enable_bit = PCI_NBP1_ENTERED_BIT;
122 *pci_offset = PCI_NBP1_STAT_OFFSET;
123 break;
124 default:
125 return -1;
126 };
127 return 0;
128}
129
130static int amd_fam14h_init(cstate_t *state, unsigned int cpu)
131{
132 int enable_bit, pci_offset, ret;
133 uint32_t val;
134
135 ret = amd_fam14h_get_pci_info(state, &pci_offset, &enable_bit, cpu);
136 if (ret)
137 return ret;
138
139 /* NBP1 needs extra treating -> write 1 to D18F6x98 bit 1 for init */
140 if (state->id == NBP1) {
141 val = pci_read_long(amd_fam14h_pci_dev, pci_offset);
142 val |= 1 << enable_bit;
143 val = pci_write_long(amd_fam14h_pci_dev, pci_offset, val);
144 return ret;
145 }
146
147 /* Enable monitor */
148 val = pci_read_long(amd_fam14h_pci_dev, PCI_MONITOR_ENABLE_REG);
149 dprint("Init %s: read at offset: 0x%x val: %u\n", state->name,
150 PCI_MONITOR_ENABLE_REG, (unsigned int) val);
151 val |= 1 << enable_bit;
152 pci_write_long(amd_fam14h_pci_dev, PCI_MONITOR_ENABLE_REG, val);
153
154 dprint("Init %s: offset: 0x%x enable_bit: %d - val: %u (%u)\n",
155 state->name, PCI_MONITOR_ENABLE_REG, enable_bit,
156 (unsigned int) val, cpu);
157
158 /* Set counter to zero */
159 pci_write_long(amd_fam14h_pci_dev, pci_offset, 0);
160 previous_count[state->id][cpu] = 0;
161
162 return 0;
163}
164
165static int amd_fam14h_disable(cstate_t *state, unsigned int cpu)
166{
167 int enable_bit, pci_offset, ret;
168 uint32_t val;
169
170 ret = amd_fam14h_get_pci_info(state, &pci_offset, &enable_bit, cpu);
171 if (ret)
172 return ret;
173
174 val = pci_read_long(amd_fam14h_pci_dev, pci_offset);
175 dprint("%s: offset: 0x%x %u\n", state->name, pci_offset, val);
176 if (state->id == NBP1) {
177 /* was the bit whether NBP1 got entered set? */
178 nbp1_entered = (val & (1 << PCI_NBP1_ACTIVE_BIT)) |
179 (val & (1 << PCI_NBP1_ENTERED_BIT));
180
181 dprint("NBP1 was %sentered - 0x%x - enable_bit: "
182 "%d - pci_offset: 0x%x\n",
183 nbp1_entered ? "" : "not ",
184 val, enable_bit, pci_offset);
185 return ret;
186 }
187 current_count[state->id][cpu] = val;
188
189 dprint("%s: Current - %llu (%u)\n", state->name,
190 current_count[state->id][cpu], cpu);
191 dprint("%s: Previous - %llu (%u)\n", state->name,
192 previous_count[state->id][cpu], cpu);
193
194 val = pci_read_long(amd_fam14h_pci_dev, PCI_MONITOR_ENABLE_REG);
195 val &= ~(1 << enable_bit);
196 pci_write_long(amd_fam14h_pci_dev, PCI_MONITOR_ENABLE_REG, val);
197
198 return 0;
199}
200
201static int fam14h_nbp1_count(unsigned int id, unsigned long long *count,
202 unsigned int cpu)
203{
204 if (id == NBP1) {
205 if (nbp1_entered)
206 *count = 1;
207 else
208 *count = 0;
209 return 0;
210 }
211 return -1;
212}
213static int fam14h_get_count_percent(unsigned int id, double *percent,
214 unsigned int cpu)
215{
216 unsigned long diff;
217
218 if (id >= AMD_FAM14H_STATE_NUM)
219 return -1;
220 /* residency count in 80ns -> divide through 12.5 to get us residency */
221 diff = current_count[id][cpu] - previous_count[id][cpu];
222
223 if (timediff == 0)
224 *percent = 0.0;
225 else
226 *percent = 100.0 * diff / timediff / 12.5;
227
228 dprint("Timediff: %llu - res~: %lu us - percent: %.2f %%\n",
229 timediff, diff * 10 / 125, *percent);
230
231 return 0;
232}
233
234static int amd_fam14h_start(void)
235{
236 int num, cpu;
237 clock_gettime(CLOCK_REALTIME, &start_time);
238 for (num = 0; num < AMD_FAM14H_STATE_NUM; num++) {
239 for (cpu = 0; cpu < cpu_count; cpu++)
240 amd_fam14h_init(&amd_fam14h_cstates[num], cpu);
241 }
242#ifdef DEBUG
243 clock_gettime(CLOCK_REALTIME, &dbg_time);
244 dbg_timediff = timespec_diff_us(start_time, dbg_time);
245 dprint("Enabling counters took: %lu us\n",
246 dbg_timediff);
247#endif
248 return 0;
249}
250
251static int amd_fam14h_stop(void)
252{
253 int num, cpu;
254 struct timespec end_time;
255
256 clock_gettime(CLOCK_REALTIME, &end_time);
257
258 for (num = 0; num < AMD_FAM14H_STATE_NUM; num++) {
259 for (cpu = 0; cpu < cpu_count; cpu++)
260 amd_fam14h_disable(&amd_fam14h_cstates[num], cpu);
261 }
262#ifdef DEBUG
263 clock_gettime(CLOCK_REALTIME, &dbg_time);
264 dbg_timediff = timespec_diff_us(end_time, dbg_time);
265 dprint("Disabling counters took: %lu ns\n", dbg_timediff);
266#endif
267 timediff = timespec_diff_us(start_time, end_time);
268 if (timediff / 1000 > OVERFLOW_MS)
269 print_overflow_err((unsigned int)timediff / 1000000,
270 OVERFLOW_MS / 1000);
271
272 return 0;
273}
274
275static int is_nbp1_capable(void)
276{
277 uint32_t val;
278 val = pci_read_long(amd_fam14h_pci_dev, PCI_NBP1_CAP_OFFSET);
279 return val & (1 << 31);
280}
281
282struct cpuidle_monitor *amd_fam14h_register(void)
283{
284 int num;
285
286 if (cpupower_cpu_info.vendor != X86_VENDOR_AMD)
287 return NULL;
288
289 if (cpupower_cpu_info.family == 0x14) {
290 if (cpu_count <= 0 || cpu_count > 2) {
291 fprintf(stderr, "AMD fam14h: Invalid cpu count: %d\n",
292 cpu_count);
293 return NULL;
294 }
295 } else
296 return NULL;
297
298 /* We do not alloc for nbp1 machine wide counter */
299 for (num = 0; num < AMD_FAM14H_STATE_NUM - 1; num++) {
300 previous_count[num] = calloc(cpu_count,
301 sizeof(unsigned long long));
302 current_count[num] = calloc(cpu_count,
303 sizeof(unsigned long long));
304 }
305
306 amd_fam14h_pci_dev = pci_acc_init(&pci_acc, pci_vendor_id, pci_dev_ids);
307 if (amd_fam14h_pci_dev == NULL || pci_acc == NULL)
308 return NULL;
309
310 if (!is_nbp1_capable())
311 amd_fam14h_monitor.hw_states_num = AMD_FAM14H_STATE_NUM - 1;
312
313 amd_fam14h_monitor.name_len = strlen(amd_fam14h_monitor.name);
314 return &amd_fam14h_monitor;
315}
316
317static void amd_fam14h_unregister(void)
318{
319 int num;
320 for (num = 0; num < AMD_FAM14H_STATE_NUM - 1; num++) {
321 free(previous_count[num]);
322 free(current_count[num]);
323 }
324 pci_cleanup(pci_acc);
325}
326
327struct cpuidle_monitor amd_fam14h_monitor = {
328 .name = "Ontario",
329 .hw_states = amd_fam14h_cstates,
330 .hw_states_num = AMD_FAM14H_STATE_NUM,
331 .start = amd_fam14h_start,
332 .stop = amd_fam14h_stop,
333 .do_register = amd_fam14h_register,
334 .unregister = amd_fam14h_unregister,
335 .needs_root = 1,
336 .overflow_s = OVERFLOW_MS / 1000,
337};
338#endif /* #if defined(__i386__) || defined(__x86_64__) */
diff --git a/tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c b/tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c
new file mode 100644
index 000000000000..d048b96a6155
--- /dev/null
+++ b/tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c
@@ -0,0 +1,196 @@
1/*
2 * (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 *
6 */
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <stdint.h>
11#include <string.h>
12#include <limits.h>
13
14#include "helpers/sysfs.h"
15#include "helpers/helpers.h"
16#include "idle_monitor/cpupower-monitor.h"
17
18#define CPUIDLE_STATES_MAX 10
19static cstate_t cpuidle_cstates[CPUIDLE_STATES_MAX];
20struct cpuidle_monitor cpuidle_sysfs_monitor;
21
22static unsigned long long **previous_count;
23static unsigned long long **current_count;
24struct timespec start_time;
25static unsigned long long timediff;
26
27static int cpuidle_get_count_percent(unsigned int id, double *percent,
28 unsigned int cpu)
29{
30 unsigned long long statediff = current_count[cpu][id]
31 - previous_count[cpu][id];
32 dprint("%s: - diff: %llu - percent: %f (%u)\n",
33 cpuidle_cstates[id].name, timediff, *percent, cpu);
34
35 if (timediff == 0)
36 *percent = 0.0;
37 else
38 *percent = ((100.0 * statediff) / timediff);
39
40 dprint("%s: - timediff: %llu - statediff: %llu - percent: %f (%u)\n",
41 cpuidle_cstates[id].name, timediff, statediff, *percent, cpu);
42
43 return 0;
44}
45
46static int cpuidle_start(void)
47{
48 int cpu, state;
49 clock_gettime(CLOCK_REALTIME, &start_time);
50 for (cpu = 0; cpu < cpu_count; cpu++) {
51 for (state = 0; state < cpuidle_sysfs_monitor.hw_states_num;
52 state++) {
53 previous_count[cpu][state] =
54 sysfs_get_idlestate_time(cpu, state);
55 dprint("CPU %d - State: %d - Val: %llu\n",
56 cpu, state, previous_count[cpu][state]);
57 }
58 };
59 return 0;
60}
61
62static int cpuidle_stop(void)
63{
64 int cpu, state;
65 struct timespec end_time;
66 clock_gettime(CLOCK_REALTIME, &end_time);
67 timediff = timespec_diff_us(start_time, end_time);
68
69 for (cpu = 0; cpu < cpu_count; cpu++) {
70 for (state = 0; state < cpuidle_sysfs_monitor.hw_states_num;
71 state++) {
72 current_count[cpu][state] =
73 sysfs_get_idlestate_time(cpu, state);
74 dprint("CPU %d - State: %d - Val: %llu\n",
75 cpu, state, previous_count[cpu][state]);
76 }
77 };
78 return 0;
79}
80
81void fix_up_intel_idle_driver_name(char *tmp, int num)
82{
83 /* fix up cpuidle name for intel idle driver */
84 if (!strncmp(tmp, "NHM-", 4)) {
85 switch (num) {
86 case 1:
87 strcpy(tmp, "C1");
88 break;
89 case 2:
90 strcpy(tmp, "C3");
91 break;
92 case 3:
93 strcpy(tmp, "C6");
94 break;
95 }
96 } else if (!strncmp(tmp, "SNB-", 4)) {
97 switch (num) {
98 case 1:
99 strcpy(tmp, "C1");
100 break;
101 case 2:
102 strcpy(tmp, "C3");
103 break;
104 case 3:
105 strcpy(tmp, "C6");
106 break;
107 case 4:
108 strcpy(tmp, "C7");
109 break;
110 }
111 } else if (!strncmp(tmp, "ATM-", 4)) {
112 switch (num) {
113 case 1:
114 strcpy(tmp, "C1");
115 break;
116 case 2:
117 strcpy(tmp, "C2");
118 break;
119 case 3:
120 strcpy(tmp, "C4");
121 break;
122 case 4:
123 strcpy(tmp, "C6");
124 break;
125 }
126 }
127}
128
129static struct cpuidle_monitor *cpuidle_register(void)
130{
131 int num;
132 char *tmp;
133
134 /* Assume idle state count is the same for all CPUs */
135 cpuidle_sysfs_monitor.hw_states_num = sysfs_get_idlestate_count(0);
136
137 if (cpuidle_sysfs_monitor.hw_states_num == 0)
138 return NULL;
139
140 for (num = 0; num < cpuidle_sysfs_monitor.hw_states_num; num++) {
141 tmp = sysfs_get_idlestate_name(0, num);
142 if (tmp == NULL)
143 continue;
144
145 fix_up_intel_idle_driver_name(tmp, num);
146 strncpy(cpuidle_cstates[num].name, tmp, CSTATE_NAME_LEN - 1);
147 free(tmp);
148
149 tmp = sysfs_get_idlestate_desc(0, num);
150 if (tmp == NULL)
151 continue;
152 strncpy(cpuidle_cstates[num].desc, tmp, CSTATE_DESC_LEN - 1);
153 free(tmp);
154
155 cpuidle_cstates[num].range = RANGE_THREAD;
156 cpuidle_cstates[num].id = num;
157 cpuidle_cstates[num].get_count_percent =
158 cpuidle_get_count_percent;
159 };
160
161 /* Free this at program termination */
162 previous_count = malloc(sizeof(long long *) * cpu_count);
163 current_count = malloc(sizeof(long long *) * cpu_count);
164 for (num = 0; num < cpu_count; num++) {
165 previous_count[num] = malloc(sizeof(long long) *
166 cpuidle_sysfs_monitor.hw_states_num);
167 current_count[num] = malloc(sizeof(long long) *
168 cpuidle_sysfs_monitor.hw_states_num);
169 }
170
171 cpuidle_sysfs_monitor.name_len = strlen(cpuidle_sysfs_monitor.name);
172 return &cpuidle_sysfs_monitor;
173}
174
175void cpuidle_unregister(void)
176{
177 int num;
178
179 for (num = 0; num < cpu_count; num++) {
180 free(previous_count[num]);
181 free(current_count[num]);
182 }
183 free(previous_count);
184 free(current_count);
185}
186
187struct cpuidle_monitor cpuidle_sysfs_monitor = {
188 .name = "Idle_Stats",
189 .hw_states = cpuidle_cstates,
190 .start = cpuidle_start,
191 .stop = cpuidle_stop,
192 .do_register = cpuidle_register,
193 .unregister = cpuidle_unregister,
194 .needs_root = 0,
195 .overflow_s = UINT_MAX,
196};
diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
new file mode 100644
index 000000000000..ba4bf068380d
--- /dev/null
+++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
@@ -0,0 +1,448 @@
1/*
2 * (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 *
6 * Output format inspired by Len Brown's <lenb@kernel.org> turbostat tool.
7 *
8 */
9
10
11#include <stdio.h>
12#include <unistd.h>
13#include <stdlib.h>
14#include <string.h>
15#include <time.h>
16#include <signal.h>
17#include <sys/types.h>
18#include <sys/wait.h>
19#include <libgen.h>
20
21#include "idle_monitor/cpupower-monitor.h"
22#include "idle_monitor/idle_monitors.h"
23#include "helpers/helpers.h"
24
25/* Define pointers to all monitors. */
26#define DEF(x) & x ## _monitor ,
27struct cpuidle_monitor *all_monitors[] = {
28#include "idle_monitors.def"
290
30};
31
32static struct cpuidle_monitor *monitors[MONITORS_MAX];
33static unsigned int avail_monitors;
34
35static char *progname;
36
37enum operation_mode_e { list = 1, show, show_all };
38static int mode;
39static int interval = 1;
40static char *show_monitors_param;
41static struct cpupower_topology cpu_top;
42
43/* ToDo: Document this in the manpage */
44static char range_abbr[RANGE_MAX] = { 'T', 'C', 'P', 'M', };
45
46long long timespec_diff_us(struct timespec start, struct timespec end)
47{
48 struct timespec temp;
49 if ((end.tv_nsec - start.tv_nsec) < 0) {
50 temp.tv_sec = end.tv_sec - start.tv_sec - 1;
51 temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
52 } else {
53 temp.tv_sec = end.tv_sec - start.tv_sec;
54 temp.tv_nsec = end.tv_nsec - start.tv_nsec;
55 }
56 return (temp.tv_sec * 1000000) + (temp.tv_nsec / 1000);
57}
58
59void monitor_help(void)
60{
61 printf(_("cpupower monitor: [-m <mon1>,[<mon2>],.. ] command\n"));
62 printf(_("cpupower monitor: [-m <mon1>,[<mon2>],.. ] [ -i interval_sec ]\n"));
63 printf(_("cpupower monitor: -l\n"));
64 printf(_("\t command: pass an arbitrary command to measure specific workload\n"));
65 printf(_("\t -i: time intervall to measure for in seconds (default 1)\n"));
66 printf(_("\t -l: list available CPU sleep monitors (for use with -m)\n"));
67 printf(_("\t -m: show specific CPU sleep monitors only (in same order)\n"));
68 printf(_("\t -h: print this help\n"));
69 printf("\n");
70 printf(_("only one of: -l, -m are allowed\nIf none of them is passed,"));
71 printf(_(" all supported monitors are shown\n"));
72}
73
74void print_n_spaces(int n)
75{
76 int x;
77 for (x = 0; x < n; x++)
78 printf(" ");
79}
80
81/* size of s must be at least n + 1 */
82int fill_string_with_spaces(char *s, int n)
83{
84 int len = strlen(s);
85 if (len > n)
86 return -1;
87 for (; len < n; len++)
88 s[len] = ' ';
89 s[len] = '\0';
90 return 0;
91}
92
93void print_header(int topology_depth)
94{
95 int unsigned mon;
96 int state, need_len, pr_mon_len;
97 cstate_t s;
98 char buf[128] = "";
99 int percent_width = 4;
100
101 fill_string_with_spaces(buf, topology_depth * 5 - 1);
102 printf("%s|", buf);
103
104 for (mon = 0; mon < avail_monitors; mon++) {
105 pr_mon_len = 0;
106 need_len = monitors[mon]->hw_states_num * (percent_width + 3)
107 - 1;
108 if (mon != 0) {
109 printf("|| ");
110 need_len--;
111 }
112 sprintf(buf, "%s", monitors[mon]->name);
113 fill_string_with_spaces(buf, need_len);
114 printf("%s", buf);
115 }
116 printf("\n");
117
118 if (topology_depth > 2)
119 printf("PKG |");
120 if (topology_depth > 1)
121 printf("CORE|");
122 if (topology_depth > 0)
123 printf("CPU |");
124
125 for (mon = 0; mon < avail_monitors; mon++) {
126 if (mon != 0)
127 printf("|| ");
128 else
129 printf(" ");
130 for (state = 0; state < monitors[mon]->hw_states_num; state++) {
131 if (state != 0)
132 printf(" | ");
133 s = monitors[mon]->hw_states[state];
134 sprintf(buf, "%s", s.name);
135 fill_string_with_spaces(buf, percent_width);
136 printf("%s", buf);
137 }
138 printf(" ");
139 }
140 printf("\n");
141}
142
143
144void print_results(int topology_depth, int cpu)
145{
146 unsigned int mon;
147 int state, ret;
148 double percent;
149 unsigned long long result;
150 cstate_t s;
151
152 if (topology_depth > 2)
153 printf("%4d|", cpu_top.core_info[cpu].pkg);
154 if (topology_depth > 1)
155 printf("%4d|", cpu_top.core_info[cpu].core);
156 if (topology_depth > 0)
157 printf("%4d|", cpu_top.core_info[cpu].cpu);
158
159 for (mon = 0; mon < avail_monitors; mon++) {
160 if (mon != 0)
161 printf("||");
162
163 for (state = 0; state < monitors[mon]->hw_states_num; state++) {
164 if (state != 0)
165 printf("|");
166
167 s = monitors[mon]->hw_states[state];
168
169 if (s.get_count_percent) {
170 ret = s.get_count_percent(s.id, &percent,
171 cpu_top.core_info[cpu].cpu);
172 if (ret)
173 printf("******");
174 else if (percent >= 100.0)
175 printf("%6.1f", percent);
176 else
177 printf("%6.2f", percent);
178 } else if (s.get_count) {
179 ret = s.get_count(s.id, &result,
180 cpu_top.core_info[cpu].cpu);
181 if (ret)
182 printf("******");
183 else
184 printf("%6llu", result);
185 } else {
186 printf(_("Monitor %s, Counter %s has no count "
187 "function. Implementation error\n"),
188 monitors[mon]->name, s.name);
189 exit(EXIT_FAILURE);
190 }
191 }
192 }
193 /* cpu offline */
194 if (cpu_top.core_info[cpu].pkg == -1 ||
195 cpu_top.core_info[cpu].core == -1) {
196 printf(_(" *is offline\n"));
197 return;
198 } else
199 printf("\n");
200}
201
202
203/* param: string passed by -m param (The list of monitors to show)
204 *
205 * Monitors must have been registered already, matching monitors
206 * are picked out and available monitors array is overridden
207 * with matching ones
208 *
209 * Monitors get sorted in the same order the user passes them
210*/
211
212static void parse_monitor_param(char *param)
213{
214 unsigned int num;
215 int mon, hits = 0;
216 char *tmp = param, *token;
217 struct cpuidle_monitor *tmp_mons[MONITORS_MAX];
218
219
220 for (mon = 0; mon < MONITORS_MAX; mon++, tmp = NULL) {
221 token = strtok(tmp, ",");
222 if (token == NULL)
223 break;
224 if (strlen(token) >= MONITOR_NAME_LEN) {
225 printf(_("%s: max monitor name length"
226 " (%d) exceeded\n"), token, MONITOR_NAME_LEN);
227 continue;
228 }
229
230 for (num = 0; num < avail_monitors; num++) {
231 if (!strcmp(monitors[num]->name, token)) {
232 dprint("Found requested monitor: %s\n", token);
233 tmp_mons[hits] = monitors[num];
234 hits++;
235 }
236 }
237 }
238 if (hits == 0) {
239 printf(_("No matching monitor found in %s, "
240 "try -l option\n"), param);
241 monitor_help();
242 exit(EXIT_FAILURE);
243 }
244 /* Override detected/registerd monitors array with requested one */
245 memcpy(monitors, tmp_mons,
246 sizeof(struct cpuidle_monitor *) * MONITORS_MAX);
247 avail_monitors = hits;
248}
249
250void list_monitors(void)
251{
252 unsigned int mon;
253 int state;
254 cstate_t s;
255
256 for (mon = 0; mon < avail_monitors; mon++) {
257 printf(_("Monitor \"%s\" (%d states) - Might overflow after %u "
258 "s\n"),
259 monitors[mon]->name, monitors[mon]->hw_states_num,
260 monitors[mon]->overflow_s);
261
262 for (state = 0; state < monitors[mon]->hw_states_num; state++) {
263 s = monitors[mon]->hw_states[state];
264 /*
265 * ToDo show more state capabilities:
266 * percent, time (granlarity)
267 */
268 printf("%s\t[%c] -> %s\n", s.name, range_abbr[s.range],
269 gettext(s.desc));
270 }
271 }
272}
273
274int fork_it(char **argv)
275{
276 int status;
277 unsigned int num;
278 unsigned long long timediff;
279 pid_t child_pid;
280 struct timespec start, end;
281
282 child_pid = fork();
283 clock_gettime(CLOCK_REALTIME, &start);
284
285 for (num = 0; num < avail_monitors; num++)
286 monitors[num]->start();
287
288 if (!child_pid) {
289 /* child */
290 execvp(argv[0], argv);
291 } else {
292 /* parent */
293 if (child_pid == -1) {
294 perror("fork");
295 exit(1);
296 }
297
298 signal(SIGINT, SIG_IGN);
299 signal(SIGQUIT, SIG_IGN);
300 if (waitpid(child_pid, &status, 0) == -1) {
301 perror("wait");
302 exit(1);
303 }
304 }
305 clock_gettime(CLOCK_REALTIME, &end);
306 for (num = 0; num < avail_monitors; num++)
307 monitors[num]->stop();
308
309 timediff = timespec_diff_us(start, end);
310 if (WIFEXITED(status))
311 printf(_("%s took %.5f seconds and exited with status %d\n"),
312 argv[0], timediff / (1000.0 * 1000),
313 WEXITSTATUS(status));
314 return 0;
315}
316
317int do_interval_measure(int i)
318{
319 unsigned int num;
320
321 for (num = 0; num < avail_monitors; num++) {
322 dprint("HW C-state residency monitor: %s - States: %d\n",
323 monitors[num]->name, monitors[num]->hw_states_num);
324 monitors[num]->start();
325 }
326 sleep(i);
327 for (num = 0; num < avail_monitors; num++)
328 monitors[num]->stop();
329
330 return 0;
331}
332
333static void cmdline(int argc, char *argv[])
334{
335 int opt;
336 progname = basename(argv[0]);
337
338 while ((opt = getopt(argc, argv, "+hli:m:")) != -1) {
339 switch (opt) {
340 case 'h':
341 monitor_help();
342 exit(EXIT_SUCCESS);
343 case 'l':
344 if (mode) {
345 monitor_help();
346 exit(EXIT_FAILURE);
347 }
348 mode = list;
349 break;
350 case 'i':
351 /* only allow -i with -m or no option */
352 if (mode && mode != show) {
353 monitor_help();
354 exit(EXIT_FAILURE);
355 }
356 interval = atoi(optarg);
357 break;
358 case 'm':
359 if (mode) {
360 monitor_help();
361 exit(EXIT_FAILURE);
362 }
363 mode = show;
364 show_monitors_param = optarg;
365 break;
366 default:
367 monitor_help();
368 exit(EXIT_FAILURE);
369 }
370 }
371 if (!mode)
372 mode = show_all;
373}
374
375int cmd_monitor(int argc, char **argv)
376{
377 unsigned int num;
378 struct cpuidle_monitor *test_mon;
379 int cpu;
380
381 cmdline(argc, argv);
382 cpu_count = get_cpu_topology(&cpu_top);
383 if (cpu_count < 0) {
384 printf(_("Cannot read number of available processors\n"));
385 return EXIT_FAILURE;
386 }
387
388 dprint("System has up to %d CPU cores\n", cpu_count);
389
390 for (num = 0; all_monitors[num]; num++) {
391 dprint("Try to register: %s\n", all_monitors[num]->name);
392 test_mon = all_monitors[num]->do_register();
393 if (test_mon) {
394 if (test_mon->needs_root && !run_as_root) {
395 fprintf(stderr, _("Available monitor %s needs "
396 "root access\n"), test_mon->name);
397 continue;
398 }
399 monitors[avail_monitors] = test_mon;
400 dprint("%s registered\n", all_monitors[num]->name);
401 avail_monitors++;
402 }
403 }
404
405 if (avail_monitors == 0) {
406 printf(_("No HW Cstate monitors found\n"));
407 return 1;
408 }
409
410 if (mode == list) {
411 list_monitors();
412 exit(EXIT_SUCCESS);
413 }
414
415 if (mode == show)
416 parse_monitor_param(show_monitors_param);
417
418 dprint("Packages: %d - Cores: %d - CPUs: %d\n",
419 cpu_top.pkgs, cpu_top.cores, cpu_count);
420
421 /*
422 * if any params left, it must be a command to fork
423 */
424 if (argc - optind)
425 fork_it(argv + optind);
426 else
427 do_interval_measure(interval);
428
429 /* ToDo: Topology parsing needs fixing first to do
430 this more generically */
431 if (cpu_top.pkgs > 1)
432 print_header(3);
433 else
434 print_header(1);
435
436 for (cpu = 0; cpu < cpu_count; cpu++) {
437 if (cpu_top.pkgs > 1)
438 print_results(3, cpu);
439 else
440 print_results(1, cpu);
441 }
442
443 for (num = 0; num < avail_monitors; num++)
444 monitors[num]->unregister();
445
446 cpu_topology_release(cpu_top);
447 return 0;
448}
diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h
new file mode 100644
index 000000000000..9312ee1f2dbc
--- /dev/null
+++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h
@@ -0,0 +1,68 @@
1/*
2 * (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 *
6 */
7
8#ifndef __CPUIDLE_INFO_HW__
9#define __CPUIDLE_INFO_HW__
10
11#include <stdarg.h>
12#include <time.h>
13
14#include "idle_monitor/idle_monitors.h"
15
16#define MONITORS_MAX 20
17#define MONITOR_NAME_LEN 20
18#define CSTATE_NAME_LEN 5
19#define CSTATE_DESC_LEN 60
20
21int cpu_count;
22
23/* Hard to define the right names ...: */
24enum power_range_e {
25 RANGE_THREAD, /* Lowest in topology hierarcy, AMD: core, Intel: thread
26 kernel sysfs: cpu */
27 RANGE_CORE, /* AMD: unit, Intel: core, kernel_sysfs: core_id */
28 RANGE_PACKAGE, /* Package, processor socket */
29 RANGE_MACHINE, /* Machine, platform wide */
30 RANGE_MAX };
31
32typedef struct cstate {
33 int id;
34 enum power_range_e range;
35 char name[CSTATE_NAME_LEN];
36 char desc[CSTATE_DESC_LEN];
37
38 /* either provide a percentage or a general count */
39 int (*get_count_percent)(unsigned int self_id, double *percent,
40 unsigned int cpu);
41 int (*get_count)(unsigned int self_id, unsigned long long *count,
42 unsigned int cpu);
43} cstate_t;
44
45struct cpuidle_monitor {
46 /* Name must not contain whitespaces */
47 char name[MONITOR_NAME_LEN];
48 int name_len;
49 int hw_states_num;
50 cstate_t *hw_states;
51 int (*start) (void);
52 int (*stop) (void);
53 struct cpuidle_monitor* (*do_register) (void);
54 void (*unregister)(void);
55 unsigned int overflow_s;
56 int needs_root;
57};
58
59extern long long timespec_diff_us(struct timespec start, struct timespec end);
60
61#define print_overflow_err(mes, ov) \
62{ \
63 fprintf(stderr, gettext("Measure took %u seconds, but registers could " \
64 "overflow at %u seconds, results " \
65 "could be inaccurate\n"), mes, ov); \
66}
67
68#endif /* __CPUIDLE_INFO_HW__ */
diff --git a/tools/power/cpupower/utils/idle_monitor/idle_monitors.def b/tools/power/cpupower/utils/idle_monitor/idle_monitors.def
new file mode 100644
index 000000000000..e3f8d9b2b18f
--- /dev/null
+++ b/tools/power/cpupower/utils/idle_monitor/idle_monitors.def
@@ -0,0 +1,7 @@
1#if defined(__i386__) || defined(__x86_64__)
2DEF(amd_fam14h)
3DEF(intel_nhm)
4DEF(intel_snb)
5DEF(mperf)
6#endif
7DEF(cpuidle_sysfs)
diff --git a/tools/power/cpupower/utils/idle_monitor/idle_monitors.h b/tools/power/cpupower/utils/idle_monitor/idle_monitors.h
new file mode 100644
index 000000000000..4fcdeb1e07e8
--- /dev/null
+++ b/tools/power/cpupower/utils/idle_monitor/idle_monitors.h
@@ -0,0 +1,18 @@
1/*
2 * (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 *
6 * Based on the idea from Michael Matz <matz@suse.de>
7 *
8 */
9
10#ifndef _CPUIDLE_IDLE_MONITORS_H_
11#define _CPUIDLE_IDLE_MONITORS_H_
12
13#define DEF(x) extern struct cpuidle_monitor x ##_monitor;
14#include "idle_monitors.def"
15#undef DEF
16extern struct cpuidle_monitor *all_monitors[];
17
18#endif /* _CPUIDLE_IDLE_MONITORS_H_ */
diff --git a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
new file mode 100644
index 000000000000..63ca87a05e5f
--- /dev/null
+++ b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
@@ -0,0 +1,255 @@
1/*
2 * (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 */
6
7#if defined(__i386__) || defined(__x86_64__)
8
9#include <stdio.h>
10#include <stdint.h>
11#include <stdlib.h>
12#include <string.h>
13#include <limits.h>
14
15#include <cpufreq.h>
16
17#include "helpers/helpers.h"
18#include "idle_monitor/cpupower-monitor.h"
19
20#define MSR_APERF 0xE8
21#define MSR_MPERF 0xE7
22
23#define MSR_TSC 0x10
24
25enum mperf_id { C0 = 0, Cx, AVG_FREQ, MPERF_CSTATE_COUNT };
26
27static int mperf_get_count_percent(unsigned int self_id, double *percent,
28 unsigned int cpu);
29static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
30 unsigned int cpu);
31
32static cstate_t mperf_cstates[MPERF_CSTATE_COUNT] = {
33 {
34 .name = "C0",
35 .desc = N_("Processor Core not idle"),
36 .id = C0,
37 .range = RANGE_THREAD,
38 .get_count_percent = mperf_get_count_percent,
39 },
40 {
41 .name = "Cx",
42 .desc = N_("Processor Core in an idle state"),
43 .id = Cx,
44 .range = RANGE_THREAD,
45 .get_count_percent = mperf_get_count_percent,
46 },
47
48 {
49 .name = "Freq",
50 .desc = N_("Average Frequency (including boost) in MHz"),
51 .id = AVG_FREQ,
52 .range = RANGE_THREAD,
53 .get_count = mperf_get_count_freq,
54 },
55};
56
57static unsigned long long tsc_at_measure_start;
58static unsigned long long tsc_at_measure_end;
59static unsigned long max_frequency;
60static unsigned long long *mperf_previous_count;
61static unsigned long long *aperf_previous_count;
62static unsigned long long *mperf_current_count;
63static unsigned long long *aperf_current_count;
64/* valid flag for all CPUs. If a MSR read failed it will be zero */
65static int *is_valid;
66
67static int mperf_get_tsc(unsigned long long *tsc)
68{
69 return read_msr(0, MSR_TSC, tsc);
70}
71
72static int mperf_init_stats(unsigned int cpu)
73{
74 unsigned long long val;
75 int ret;
76
77 ret = read_msr(cpu, MSR_APERF, &val);
78 aperf_previous_count[cpu] = val;
79 ret |= read_msr(cpu, MSR_MPERF, &val);
80 mperf_previous_count[cpu] = val;
81 is_valid[cpu] = !ret;
82
83 return 0;
84}
85
86static int mperf_measure_stats(unsigned int cpu)
87{
88 unsigned long long val;
89 int ret;
90
91 ret = read_msr(cpu, MSR_APERF, &val);
92 aperf_current_count[cpu] = val;
93 ret |= read_msr(cpu, MSR_MPERF, &val);
94 mperf_current_count[cpu] = val;
95 is_valid[cpu] = !ret;
96
97 return 0;
98}
99
100/*
101 * get_average_perf()
102 *
103 * Returns the average performance (also considers boosted frequencies)
104 *
105 * Input:
106 * aperf_diff: Difference of the aperf register over a time period
107 * mperf_diff: Difference of the mperf register over the same time period
108 * max_freq: Maximum frequency (P0)
109 *
110 * Returns:
111 * Average performance over the time period
112 */
113static unsigned long get_average_perf(unsigned long long aperf_diff,
114 unsigned long long mperf_diff)
115{
116 unsigned int perf_percent = 0;
117 if (((unsigned long)(-1) / 100) < aperf_diff) {
118 int shift_count = 7;
119 aperf_diff >>= shift_count;
120 mperf_diff >>= shift_count;
121 }
122 perf_percent = (aperf_diff * 100) / mperf_diff;
123 return (max_frequency * perf_percent) / 100;
124}
125
126static int mperf_get_count_percent(unsigned int id, double *percent,
127 unsigned int cpu)
128{
129 unsigned long long aperf_diff, mperf_diff, tsc_diff;
130
131 if (!is_valid[cpu])
132 return -1;
133
134 if (id != C0 && id != Cx)
135 return -1;
136
137 mperf_diff = mperf_current_count[cpu] - mperf_previous_count[cpu];
138 aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];
139 tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
140
141 *percent = 100.0 * mperf_diff / tsc_diff;
142 dprint("%s: mperf_diff: %llu, tsc_diff: %llu\n",
143 mperf_cstates[id].name, mperf_diff, tsc_diff);
144
145 if (id == Cx)
146 *percent = 100.0 - *percent;
147
148 dprint("%s: previous: %llu - current: %llu - (%u)\n",
149 mperf_cstates[id].name, mperf_diff, aperf_diff, cpu);
150 dprint("%s: %f\n", mperf_cstates[id].name, *percent);
151 return 0;
152}
153
154static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
155 unsigned int cpu)
156{
157 unsigned long long aperf_diff, mperf_diff;
158
159 if (id != AVG_FREQ)
160 return 1;
161
162 if (!is_valid[cpu])
163 return -1;
164
165 mperf_diff = mperf_current_count[cpu] - mperf_previous_count[cpu];
166 aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];
167
168 /* Return MHz for now, might want to return KHz if column width is more
169 generic */
170 *count = get_average_perf(aperf_diff, mperf_diff) / 1000;
171 dprint("%s: %llu\n", mperf_cstates[id].name, *count);
172
173 return 0;
174}
175
176static int mperf_start(void)
177{
178 int cpu;
179 unsigned long long dbg;
180
181 mperf_get_tsc(&tsc_at_measure_start);
182
183 for (cpu = 0; cpu < cpu_count; cpu++)
184 mperf_init_stats(cpu);
185
186 mperf_get_tsc(&dbg);
187 dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start);
188 return 0;
189}
190
191static int mperf_stop(void)
192{
193 unsigned long long dbg;
194 int cpu;
195
196 mperf_get_tsc(&tsc_at_measure_end);
197
198 for (cpu = 0; cpu < cpu_count; cpu++)
199 mperf_measure_stats(cpu);
200
201 mperf_get_tsc(&dbg);
202 dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end);
203
204 return 0;
205}
206
207struct cpuidle_monitor mperf_monitor;
208
209struct cpuidle_monitor *mperf_register(void)
210{
211 unsigned long min;
212
213 if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF))
214 return NULL;
215
216 /* Assume min/max all the same on all cores */
217 if (cpufreq_get_hardware_limits(0, &min, &max_frequency)) {
218 dprint("Cannot retrieve max freq from cpufreq kernel "
219 "subsystem\n");
220 return NULL;
221 }
222
223 /* Free this at program termination */
224 is_valid = calloc(cpu_count, sizeof(int));
225 mperf_previous_count = calloc(cpu_count, sizeof(unsigned long long));
226 aperf_previous_count = calloc(cpu_count, sizeof(unsigned long long));
227 mperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
228 aperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
229
230 mperf_monitor.name_len = strlen(mperf_monitor.name);
231 return &mperf_monitor;
232}
233
234void mperf_unregister(void)
235{
236 free(mperf_previous_count);
237 free(aperf_previous_count);
238 free(mperf_current_count);
239 free(aperf_current_count);
240 free(is_valid);
241}
242
243struct cpuidle_monitor mperf_monitor = {
244 .name = "Mperf",
245 .hw_states_num = MPERF_CSTATE_COUNT,
246 .hw_states = mperf_cstates,
247 .start = mperf_start,
248 .stop = mperf_stop,
249 .do_register = mperf_register,
250 .unregister = mperf_unregister,
251 .needs_root = 1,
252 .overflow_s = 922000000 /* 922337203 seconds TSC overflow
253 at 20GHz */
254};
255#endif /* #if defined(__i386__) || defined(__x86_64__) */
diff --git a/tools/power/cpupower/utils/idle_monitor/nhm_idle.c b/tools/power/cpupower/utils/idle_monitor/nhm_idle.c
new file mode 100644
index 000000000000..d2a91dd0d563
--- /dev/null
+++ b/tools/power/cpupower/utils/idle_monitor/nhm_idle.c
@@ -0,0 +1,216 @@
1/*
2 * (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 *
6 * Based on Len Brown's <lenb@kernel.org> turbostat tool.
7 */
8
9#if defined(__i386__) || defined(__x86_64__)
10
11#include <stdio.h>
12#include <stdint.h>
13#include <stdlib.h>
14#include <string.h>
15
16#include "helpers/helpers.h"
17#include "idle_monitor/cpupower-monitor.h"
18
19#define MSR_PKG_C3_RESIDENCY 0x3F8
20#define MSR_PKG_C6_RESIDENCY 0x3F9
21#define MSR_CORE_C3_RESIDENCY 0x3FC
22#define MSR_CORE_C6_RESIDENCY 0x3FD
23
24#define MSR_TSC 0x10
25
26#define NHM_CSTATE_COUNT 4
27
28enum intel_nhm_id { C3 = 0, C6, PC3, PC6, TSC = 0xFFFF };
29
30static int nhm_get_count_percent(unsigned int self_id, double *percent,
31 unsigned int cpu);
32
33static cstate_t nhm_cstates[NHM_CSTATE_COUNT] = {
34 {
35 .name = "C3",
36 .desc = N_("Processor Core C3"),
37 .id = C3,
38 .range = RANGE_CORE,
39 .get_count_percent = nhm_get_count_percent,
40 },
41 {
42 .name = "C6",
43 .desc = N_("Processor Core C6"),
44 .id = C6,
45 .range = RANGE_CORE,
46 .get_count_percent = nhm_get_count_percent,
47 },
48
49 {
50 .name = "PC3",
51 .desc = N_("Processor Package C3"),
52 .id = PC3,
53 .range = RANGE_PACKAGE,
54 .get_count_percent = nhm_get_count_percent,
55 },
56 {
57 .name = "PC6",
58 .desc = N_("Processor Package C6"),
59 .id = PC6,
60 .range = RANGE_PACKAGE,
61 .get_count_percent = nhm_get_count_percent,
62 },
63};
64
65static unsigned long long tsc_at_measure_start;
66static unsigned long long tsc_at_measure_end;
67static unsigned long long *previous_count[NHM_CSTATE_COUNT];
68static unsigned long long *current_count[NHM_CSTATE_COUNT];
69/* valid flag for all CPUs. If a MSR read failed it will be zero */
70static int *is_valid;
71
72static int nhm_get_count(enum intel_nhm_id id, unsigned long long *val,
73 unsigned int cpu)
74{
75 int msr;
76
77 switch (id) {
78 case C3:
79 msr = MSR_CORE_C3_RESIDENCY;
80 break;
81 case C6:
82 msr = MSR_CORE_C6_RESIDENCY;
83 break;
84 case PC3:
85 msr = MSR_PKG_C3_RESIDENCY;
86 break;
87 case PC6:
88 msr = MSR_PKG_C6_RESIDENCY;
89 break;
90 case TSC:
91 msr = MSR_TSC;
92 break;
93 default:
94 return -1;
95 };
96 if (read_msr(cpu, msr, val))
97 return -1;
98
99 return 0;
100}
101
102static int nhm_get_count_percent(unsigned int id, double *percent,
103 unsigned int cpu)
104{
105 *percent = 0.0;
106
107 if (!is_valid[cpu])
108 return -1;
109
110 *percent = (100.0 *
111 (current_count[id][cpu] - previous_count[id][cpu])) /
112 (tsc_at_measure_end - tsc_at_measure_start);
113
114 dprint("%s: previous: %llu - current: %llu - (%u)\n",
115 nhm_cstates[id].name, previous_count[id][cpu],
116 current_count[id][cpu], cpu);
117
118 dprint("%s: tsc_diff: %llu - count_diff: %llu - percent: %2.f (%u)\n",
119 nhm_cstates[id].name,
120 (unsigned long long) tsc_at_measure_end - tsc_at_measure_start,
121 current_count[id][cpu] - previous_count[id][cpu],
122 *percent, cpu);
123
124 return 0;
125}
126
127static int nhm_start(void)
128{
129 int num, cpu;
130 unsigned long long dbg, val;
131
132 nhm_get_count(TSC, &tsc_at_measure_start, 0);
133
134 for (num = 0; num < NHM_CSTATE_COUNT; num++) {
135 for (cpu = 0; cpu < cpu_count; cpu++) {
136 is_valid[cpu] = !nhm_get_count(num, &val, cpu);
137 previous_count[num][cpu] = val;
138 }
139 }
140 nhm_get_count(TSC, &dbg, 0);
141 dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start);
142 return 0;
143}
144
145static int nhm_stop(void)
146{
147 unsigned long long val;
148 unsigned long long dbg;
149 int num, cpu;
150
151 nhm_get_count(TSC, &tsc_at_measure_end, 0);
152
153 for (num = 0; num < NHM_CSTATE_COUNT; num++) {
154 for (cpu = 0; cpu < cpu_count; cpu++) {
155 is_valid[cpu] = !nhm_get_count(num, &val, cpu);
156 current_count[num][cpu] = val;
157 }
158 }
159 nhm_get_count(TSC, &dbg, 0);
160 dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end);
161
162 return 0;
163}
164
165struct cpuidle_monitor intel_nhm_monitor;
166
167struct cpuidle_monitor *intel_nhm_register(void)
168{
169 int num;
170
171 if (cpupower_cpu_info.vendor != X86_VENDOR_INTEL)
172 return NULL;
173
174 if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_INV_TSC))
175 return NULL;
176
177 if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF))
178 return NULL;
179
180 /* Free this at program termination */
181 is_valid = calloc(cpu_count, sizeof(int));
182 for (num = 0; num < NHM_CSTATE_COUNT; num++) {
183 previous_count[num] = calloc(cpu_count,
184 sizeof(unsigned long long));
185 current_count[num] = calloc(cpu_count,
186 sizeof(unsigned long long));
187 }
188
189 intel_nhm_monitor.name_len = strlen(intel_nhm_monitor.name);
190 return &intel_nhm_monitor;
191}
192
193void intel_nhm_unregister(void)
194{
195 int num;
196
197 for (num = 0; num < NHM_CSTATE_COUNT; num++) {
198 free(previous_count[num]);
199 free(current_count[num]);
200 }
201 free(is_valid);
202}
203
204struct cpuidle_monitor intel_nhm_monitor = {
205 .name = "Nehalem",
206 .hw_states_num = NHM_CSTATE_COUNT,
207 .hw_states = nhm_cstates,
208 .start = nhm_start,
209 .stop = nhm_stop,
210 .do_register = intel_nhm_register,
211 .unregister = intel_nhm_unregister,
212 .needs_root = 1,
213 .overflow_s = 922000000 /* 922337203 seconds TSC overflow
214 at 20GHz */
215};
216#endif
diff --git a/tools/power/cpupower/utils/idle_monitor/snb_idle.c b/tools/power/cpupower/utils/idle_monitor/snb_idle.c
new file mode 100644
index 000000000000..a1bc07cd53e1
--- /dev/null
+++ b/tools/power/cpupower/utils/idle_monitor/snb_idle.c
@@ -0,0 +1,190 @@
1/*
2 * (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 *
6 * Based on Len Brown's <lenb@kernel.org> turbostat tool.
7 */
8
9#if defined(__i386__) || defined(__x86_64__)
10
11#include <stdio.h>
12#include <stdint.h>
13#include <stdlib.h>
14#include <string.h>
15
16#include "helpers/helpers.h"
17#include "idle_monitor/cpupower-monitor.h"
18
19#define MSR_PKG_C2_RESIDENCY 0x60D
20#define MSR_PKG_C7_RESIDENCY 0x3FA
21#define MSR_CORE_C7_RESIDENCY 0x3FE
22
23#define MSR_TSC 0x10
24
25enum intel_snb_id { C7 = 0, PC2, PC7, SNB_CSTATE_COUNT, TSC = 0xFFFF };
26
27static int snb_get_count_percent(unsigned int self_id, double *percent,
28 unsigned int cpu);
29
30static cstate_t snb_cstates[SNB_CSTATE_COUNT] = {
31 {
32 .name = "C7",
33 .desc = N_("Processor Core C7"),
34 .id = C7,
35 .range = RANGE_CORE,
36 .get_count_percent = snb_get_count_percent,
37 },
38 {
39 .name = "PC2",
40 .desc = N_("Processor Package C2"),
41 .id = PC2,
42 .range = RANGE_PACKAGE,
43 .get_count_percent = snb_get_count_percent,
44 },
45 {
46 .name = "PC7",
47 .desc = N_("Processor Package C7"),
48 .id = PC7,
49 .range = RANGE_PACKAGE,
50 .get_count_percent = snb_get_count_percent,
51 },
52};
53
54static unsigned long long tsc_at_measure_start;
55static unsigned long long tsc_at_measure_end;
56static unsigned long long *previous_count[SNB_CSTATE_COUNT];
57static unsigned long long *current_count[SNB_CSTATE_COUNT];
58/* valid flag for all CPUs. If a MSR read failed it will be zero */
59static int *is_valid;
60
61static int snb_get_count(enum intel_snb_id id, unsigned long long *val,
62 unsigned int cpu)
63{
64 int msr;
65
66 switch (id) {
67 case C7:
68 msr = MSR_CORE_C7_RESIDENCY;
69 break;
70 case PC2:
71 msr = MSR_PKG_C2_RESIDENCY;
72 break;
73 case PC7:
74 msr = MSR_PKG_C7_RESIDENCY;
75 break;
76 case TSC:
77 msr = MSR_TSC;
78 break;
79 default:
80 return -1;
81 };
82 if (read_msr(cpu, msr, val))
83 return -1;
84 return 0;
85}
86
87static int snb_get_count_percent(unsigned int id, double *percent,
88 unsigned int cpu)
89{
90 *percent = 0.0;
91
92 if (!is_valid[cpu])
93 return -1;
94
95 *percent = (100.0 *
96 (current_count[id][cpu] - previous_count[id][cpu])) /
97 (tsc_at_measure_end - tsc_at_measure_start);
98
99 dprint("%s: previous: %llu - current: %llu - (%u)\n",
100 snb_cstates[id].name, previous_count[id][cpu],
101 current_count[id][cpu], cpu);
102
103 dprint("%s: tsc_diff: %llu - count_diff: %llu - percent: %2.f (%u)\n",
104 snb_cstates[id].name,
105 (unsigned long long) tsc_at_measure_end - tsc_at_measure_start,
106 current_count[id][cpu] - previous_count[id][cpu],
107 *percent, cpu);
108
109 return 0;
110}
111
112static int snb_start(void)
113{
114 int num, cpu;
115 unsigned long long val;
116
117 for (num = 0; num < SNB_CSTATE_COUNT; num++) {
118 for (cpu = 0; cpu < cpu_count; cpu++) {
119 snb_get_count(num, &val, cpu);
120 previous_count[num][cpu] = val;
121 }
122 }
123 snb_get_count(TSC, &tsc_at_measure_start, 0);
124 return 0;
125}
126
127static int snb_stop(void)
128{
129 unsigned long long val;
130 int num, cpu;
131
132 snb_get_count(TSC, &tsc_at_measure_end, 0);
133
134 for (num = 0; num < SNB_CSTATE_COUNT; num++) {
135 for (cpu = 0; cpu < cpu_count; cpu++) {
136 is_valid[cpu] = !snb_get_count(num, &val, cpu);
137 current_count[num][cpu] = val;
138 }
139 }
140 return 0;
141}
142
143struct cpuidle_monitor intel_snb_monitor;
144
145static struct cpuidle_monitor *snb_register(void)
146{
147 int num;
148
149 if (cpupower_cpu_info.vendor != X86_VENDOR_INTEL
150 || cpupower_cpu_info.family != 6)
151 return NULL;
152
153 if (cpupower_cpu_info.model != 0x2A
154 && cpupower_cpu_info.model != 0x2D)
155 return NULL;
156
157 is_valid = calloc(cpu_count, sizeof(int));
158 for (num = 0; num < SNB_CSTATE_COUNT; num++) {
159 previous_count[num] = calloc(cpu_count,
160 sizeof(unsigned long long));
161 current_count[num] = calloc(cpu_count,
162 sizeof(unsigned long long));
163 }
164 intel_snb_monitor.name_len = strlen(intel_snb_monitor.name);
165 return &intel_snb_monitor;
166}
167
168void snb_unregister(void)
169{
170 int num;
171 free(is_valid);
172 for (num = 0; num < SNB_CSTATE_COUNT; num++) {
173 free(previous_count[num]);
174 free(current_count[num]);
175 }
176}
177
178struct cpuidle_monitor intel_snb_monitor = {
179 .name = "SandyBridge",
180 .hw_states = snb_cstates,
181 .hw_states_num = SNB_CSTATE_COUNT,
182 .start = snb_start,
183 .stop = snb_stop,
184 .do_register = snb_register,
185 .unregister = snb_unregister,
186 .needs_root = 1,
187 .overflow_s = 922000000 /* 922337203 seconds TSC overflow
188 at 20GHz */
189};
190#endif /* defined(__i386__) || defined(__x86_64__) */
diff --git a/tools/power/cpupower/utils/version-gen.sh b/tools/power/cpupower/utils/version-gen.sh
new file mode 100755
index 000000000000..5ec41c556992
--- /dev/null
+++ b/tools/power/cpupower/utils/version-gen.sh
@@ -0,0 +1,35 @@
1#!/bin/sh
2#
3# Script which prints out the version to use for building cpupowerutils.
4# Must be called from tools/power/cpupower/
5#
6# Heavily based on tools/perf/util/PERF-VERSION-GEN .
7
8LF='
9'
10
11# First check if there is a .git to get the version from git describe
12# otherwise try to get the version from the kernel makefile
13if test -d ../../../.git -o -f ../../../.git &&
14 VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
15 case "$VN" in
16 *$LF*) (exit 1) ;;
17 v[0-9]*)
18 git update-index -q --refresh
19 test -z "$(git diff-index --name-only HEAD --)" ||
20 VN="$VN-dirty" ;;
21 esac
22then
23 VN=$(echo "$VN" | sed -e 's/-/./g');
24else
25 eval $(grep '^VERSION[[:space:]]*=' ../../../Makefile|tr -d ' ')
26 eval $(grep '^PATCHLEVEL[[:space:]]*=' ../../../Makefile|tr -d ' ')
27 eval $(grep '^SUBLEVEL[[:space:]]*=' ../../../Makefile|tr -d ' ')
28 eval $(grep '^EXTRAVERSION[[:space:]]*=' ../../../Makefile|tr -d ' ')
29
30 VN="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}"
31fi
32
33VN=$(expr "$VN" : v*'\(.*\)')
34
35echo $VN
diff --git a/tools/slub/slabinfo.c b/tools/slub/slabinfo.c
index 516551c9f172..868cc93f7ac2 100644
--- a/tools/slub/slabinfo.c
+++ b/tools/slub/slabinfo.c
@@ -2,8 +2,9 @@
2 * Slabinfo: Tool to get reports about slabs 2 * Slabinfo: Tool to get reports about slabs
3 * 3 *
4 * (C) 2007 sgi, Christoph Lameter 4 * (C) 2007 sgi, Christoph Lameter
5 * (C) 2011 Linux Foundation, Christoph Lameter
5 * 6 *
6 * Compile by: 7 * Compile with:
7 * 8 *
8 * gcc -o slabinfo slabinfo.c 9 * gcc -o slabinfo slabinfo.c
9 */ 10 */
@@ -39,6 +40,8 @@ struct slabinfo {
39 unsigned long cpuslab_flush, deactivate_full, deactivate_empty; 40 unsigned long cpuslab_flush, deactivate_full, deactivate_empty;
40 unsigned long deactivate_to_head, deactivate_to_tail; 41 unsigned long deactivate_to_head, deactivate_to_tail;
41 unsigned long deactivate_remote_frees, order_fallback; 42 unsigned long deactivate_remote_frees, order_fallback;
43 unsigned long cmpxchg_double_cpu_fail, cmpxchg_double_fail;
44 unsigned long alloc_node_mismatch, deactivate_bypass;
42 int numa[MAX_NODES]; 45 int numa[MAX_NODES];
43 int numa_partial[MAX_NODES]; 46 int numa_partial[MAX_NODES];
44} slabinfo[MAX_SLABS]; 47} slabinfo[MAX_SLABS];
@@ -99,7 +102,7 @@ static void fatal(const char *x, ...)
99 102
100static void usage(void) 103static void usage(void)
101{ 104{
102 printf("slabinfo 5/7/2007. (c) 2007 sgi.\n\n" 105 printf("slabinfo 4/15/2011. (c) 2007 sgi/(c) 2011 Linux Foundation.\n\n"
103 "slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]\n" 106 "slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]\n"
104 "-a|--aliases Show aliases\n" 107 "-a|--aliases Show aliases\n"
105 "-A|--activity Most active slabs first\n" 108 "-A|--activity Most active slabs first\n"
@@ -293,7 +296,7 @@ int line = 0;
293static void first_line(void) 296static void first_line(void)
294{ 297{
295 if (show_activity) 298 if (show_activity)
296 printf("Name Objects Alloc Free %%Fast Fallb O\n"); 299 printf("Name Objects Alloc Free %%Fast Fallb O CmpX UL\n");
297 else 300 else
298 printf("Name Objects Objsize Space " 301 printf("Name Objects Objsize Space "
299 "Slabs/Part/Cpu O/S O %%Fr %%Ef Flg\n"); 302 "Slabs/Part/Cpu O/S O %%Fr %%Ef Flg\n");
@@ -379,14 +382,14 @@ static void show_tracking(struct slabinfo *s)
379 printf("\n%s: Kernel object allocation\n", s->name); 382 printf("\n%s: Kernel object allocation\n", s->name);
380 printf("-----------------------------------------------------------------------\n"); 383 printf("-----------------------------------------------------------------------\n");
381 if (read_slab_obj(s, "alloc_calls")) 384 if (read_slab_obj(s, "alloc_calls"))
382 printf(buffer); 385 printf("%s", buffer);
383 else 386 else
384 printf("No Data\n"); 387 printf("No Data\n");
385 388
386 printf("\n%s: Kernel object freeing\n", s->name); 389 printf("\n%s: Kernel object freeing\n", s->name);
387 printf("------------------------------------------------------------------------\n"); 390 printf("------------------------------------------------------------------------\n");
388 if (read_slab_obj(s, "free_calls")) 391 if (read_slab_obj(s, "free_calls"))
389 printf(buffer); 392 printf("%s", buffer);
390 else 393 else
391 printf("No Data\n"); 394 printf("No Data\n");
392 395
@@ -400,7 +403,7 @@ static void ops(struct slabinfo *s)
400 if (read_slab_obj(s, "ops")) { 403 if (read_slab_obj(s, "ops")) {
401 printf("\n%s: kmem_cache operations\n", s->name); 404 printf("\n%s: kmem_cache operations\n", s->name);
402 printf("--------------------------------------------\n"); 405 printf("--------------------------------------------\n");
403 printf(buffer); 406 printf("%s", buffer);
404 } else 407 } else
405 printf("\n%s has no kmem_cache operations\n", s->name); 408 printf("\n%s has no kmem_cache operations\n", s->name);
406} 409}
@@ -462,19 +465,32 @@ static void slab_stats(struct slabinfo *s)
462 if (s->cpuslab_flush) 465 if (s->cpuslab_flush)
463 printf("Flushes %8lu\n", s->cpuslab_flush); 466 printf("Flushes %8lu\n", s->cpuslab_flush);
464 467
465 if (s->alloc_refill)
466 printf("Refill %8lu\n", s->alloc_refill);
467
468 total = s->deactivate_full + s->deactivate_empty + 468 total = s->deactivate_full + s->deactivate_empty +
469 s->deactivate_to_head + s->deactivate_to_tail; 469 s->deactivate_to_head + s->deactivate_to_tail + s->deactivate_bypass;
470 470
471 if (total) 471 if (total) {
472 printf("Deactivate Full=%lu(%lu%%) Empty=%lu(%lu%%) " 472 printf("\nSlab Deactivation Ocurrences %%\n");
473 "ToHead=%lu(%lu%%) ToTail=%lu(%lu%%)\n", 473 printf("-------------------------------------------------\n");
474 s->deactivate_full, (s->deactivate_full * 100) / total, 474 printf("Slab full %7lu %3lu%%\n",
475 s->deactivate_empty, (s->deactivate_empty * 100) / total, 475 s->deactivate_full, (s->deactivate_full * 100) / total);
476 s->deactivate_to_head, (s->deactivate_to_head * 100) / total, 476 printf("Slab empty %7lu %3lu%%\n",
477 s->deactivate_empty, (s->deactivate_empty * 100) / total);
478 printf("Moved to head of partial list %7lu %3lu%%\n",
479 s->deactivate_to_head, (s->deactivate_to_head * 100) / total);
480 printf("Moved to tail of partial list %7lu %3lu%%\n",
477 s->deactivate_to_tail, (s->deactivate_to_tail * 100) / total); 481 s->deactivate_to_tail, (s->deactivate_to_tail * 100) / total);
482 printf("Deactivation bypass %7lu %3lu%%\n",
483 s->deactivate_bypass, (s->deactivate_bypass * 100) / total);
484 printf("Refilled from foreign frees %7lu %3lu%%\n",
485 s->alloc_refill, (s->alloc_refill * 100) / total);
486 printf("Node mismatch %7lu %3lu%%\n",
487 s->alloc_node_mismatch, (s->alloc_node_mismatch * 100) / total);
488 }
489
490 if (s->cmpxchg_double_fail || s->cmpxchg_double_cpu_fail)
491 printf("\nCmpxchg_double Looping\n------------------------\n");
492 printf("Locked Cmpxchg Double redos %lu\nUnlocked Cmpxchg Double redos %lu\n",
493 s->cmpxchg_double_fail, s->cmpxchg_double_cpu_fail);
478} 494}
479 495
480static void report(struct slabinfo *s) 496static void report(struct slabinfo *s)
@@ -573,12 +589,13 @@ static void slabcache(struct slabinfo *s)
573 total_alloc = s->alloc_fastpath + s->alloc_slowpath; 589 total_alloc = s->alloc_fastpath + s->alloc_slowpath;
574 total_free = s->free_fastpath + s->free_slowpath; 590 total_free = s->free_fastpath + s->free_slowpath;
575 591
576 printf("%-21s %8ld %10ld %10ld %3ld %3ld %5ld %1d\n", 592 printf("%-21s %8ld %10ld %10ld %3ld %3ld %5ld %1d %4ld %4ld\n",
577 s->name, s->objects, 593 s->name, s->objects,
578 total_alloc, total_free, 594 total_alloc, total_free,
579 total_alloc ? (s->alloc_fastpath * 100 / total_alloc) : 0, 595 total_alloc ? (s->alloc_fastpath * 100 / total_alloc) : 0,
580 total_free ? (s->free_fastpath * 100 / total_free) : 0, 596 total_free ? (s->free_fastpath * 100 / total_free) : 0,
581 s->order_fallback, s->order); 597 s->order_fallback, s->order, s->cmpxchg_double_fail,
598 s->cmpxchg_double_cpu_fail);
582 } 599 }
583 else 600 else
584 printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n", 601 printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n",
@@ -1190,6 +1207,10 @@ static void read_slab_dir(void)
1190 slab->deactivate_to_tail = get_obj("deactivate_to_tail"); 1207 slab->deactivate_to_tail = get_obj("deactivate_to_tail");
1191 slab->deactivate_remote_frees = get_obj("deactivate_remote_frees"); 1208 slab->deactivate_remote_frees = get_obj("deactivate_remote_frees");
1192 slab->order_fallback = get_obj("order_fallback"); 1209 slab->order_fallback = get_obj("order_fallback");
1210 slab->cmpxchg_double_cpu_fail = get_obj("cmpxchg_double_cpu_fail");
1211 slab->cmpxchg_double_fail = get_obj("cmpxchg_double_fail");
1212 slab->alloc_node_mismatch = get_obj("alloc_node_mismatch");
1213 slab->deactivate_bypass = get_obj("deactivate_bypass");
1193 chdir(".."); 1214 chdir("..");
1194 if (slab->name[0] == ':') 1215 if (slab->name[0] == ':')
1195 alias_targets++; 1216 alias_targets++;
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index cef28e6632b9..8d02ccb10c59 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -27,7 +27,7 @@ $default{"TEST_TYPE"} = "test";
27$default{"BUILD_TYPE"} = "randconfig"; 27$default{"BUILD_TYPE"} = "randconfig";
28$default{"MAKE_CMD"} = "make"; 28$default{"MAKE_CMD"} = "make";
29$default{"TIMEOUT"} = 120; 29$default{"TIMEOUT"} = 120;
30$default{"TMP_DIR"} = "/tmp/ktest"; 30$default{"TMP_DIR"} = "/tmp/ktest/\${MACHINE}";
31$default{"SLEEP_TIME"} = 60; # sleep time between tests 31$default{"SLEEP_TIME"} = 60; # sleep time between tests
32$default{"BUILD_NOCLEAN"} = 0; 32$default{"BUILD_NOCLEAN"} = 0;
33$default{"REBOOT_ON_ERROR"} = 0; 33$default{"REBOOT_ON_ERROR"} = 0;
@@ -41,6 +41,7 @@ $default{"CLEAR_LOG"} = 0;
41$default{"BISECT_MANUAL"} = 0; 41$default{"BISECT_MANUAL"} = 0;
42$default{"BISECT_SKIP"} = 1; 42$default{"BISECT_SKIP"} = 1;
43$default{"SUCCESS_LINE"} = "login:"; 43$default{"SUCCESS_LINE"} = "login:";
44$default{"DETECT_TRIPLE_FAULT"} = 1;
44$default{"BOOTED_TIMEOUT"} = 1; 45$default{"BOOTED_TIMEOUT"} = 1;
45$default{"DIE_ON_FAILURE"} = 1; 46$default{"DIE_ON_FAILURE"} = 1;
46$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND"; 47$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
@@ -62,6 +63,10 @@ my $output_config;
62my $test_type; 63my $test_type;
63my $build_type; 64my $build_type;
64my $build_options; 65my $build_options;
66my $pre_build;
67my $post_build;
68my $pre_build_die;
69my $post_build_die;
65my $reboot_type; 70my $reboot_type;
66my $reboot_script; 71my $reboot_script;
67my $power_cycle; 72my $power_cycle;
@@ -81,12 +86,17 @@ my $make;
81my $post_install; 86my $post_install;
82my $noclean; 87my $noclean;
83my $minconfig; 88my $minconfig;
89my $start_minconfig;
90my $start_minconfig_defined;
91my $output_minconfig;
92my $ignore_config;
84my $addconfig; 93my $addconfig;
85my $in_bisect = 0; 94my $in_bisect = 0;
86my $bisect_bad = ""; 95my $bisect_bad = "";
87my $reverse_bisect; 96my $reverse_bisect;
88my $bisect_manual; 97my $bisect_manual;
89my $bisect_skip; 98my $bisect_skip;
99my $config_bisect_good;
90my $in_patchcheck = 0; 100my $in_patchcheck = 0;
91my $run_test; 101my $run_test;
92my $redirect; 102my $redirect;
@@ -98,9 +108,12 @@ my $monitor_cnt = 0;
98my $sleep_time; 108my $sleep_time;
99my $bisect_sleep_time; 109my $bisect_sleep_time;
100my $patchcheck_sleep_time; 110my $patchcheck_sleep_time;
111my $ignore_warnings;
101my $store_failures; 112my $store_failures;
113my $test_name;
102my $timeout; 114my $timeout;
103my $booted_timeout; 115my $booted_timeout;
116my $detect_triplefault;
104my $console; 117my $console;
105my $success_line; 118my $success_line;
106my $stop_after_success; 119my $stop_after_success;
@@ -115,6 +128,7 @@ my $successes = 0;
115my %entered_configs; 128my %entered_configs;
116my %config_help; 129my %config_help;
117my %variable; 130my %variable;
131my %force_config;
118 132
119$config_help{"MACHINE"} = << "EOF" 133$config_help{"MACHINE"} = << "EOF"
120 The machine hostname that you will test. 134 The machine hostname that you will test.
@@ -204,6 +218,26 @@ $config_help{"REBOOT_SCRIPT"} = << "EOF"
204EOF 218EOF
205 ; 219 ;
206 220
221sub read_yn {
222 my ($prompt) = @_;
223
224 my $ans;
225
226 for (;;) {
227 print "$prompt [Y/n] ";
228 $ans = <STDIN>;
229 chomp $ans;
230 if ($ans =~ /^\s*$/) {
231 $ans = "y";
232 }
233 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
234 print "Please answer either 'y' or 'n'.\n";
235 }
236 if ($ans !~ /^y$/i) {
237 return 0;
238 }
239 return 1;
240}
207 241
208sub get_ktest_config { 242sub get_ktest_config {
209 my ($config) = @_; 243 my ($config) = @_;
@@ -335,6 +369,7 @@ sub read_config {
335 my $num_tests_set = 0; 369 my $num_tests_set = 0;
336 my $skip = 0; 370 my $skip = 0;
337 my $rest; 371 my $rest;
372 my $test_case = 0;
338 373
339 while (<IN>) { 374 while (<IN>) {
340 375
@@ -360,6 +395,7 @@ sub read_config {
360 $rest = $1; 395 $rest = $1;
361 $skip = 1; 396 $skip = 1;
362 } else { 397 } else {
398 $test_case = 1;
363 $skip = 0; 399 $skip = 0;
364 } 400 }
365 401
@@ -464,6 +500,15 @@ sub read_config {
464 # make sure we have all mandatory configs 500 # make sure we have all mandatory configs
465 get_ktest_configs; 501 get_ktest_configs;
466 502
503 # was a test specified?
504 if (!$test_case) {
505 print "No test case specified.\n";
506 print "What test case would you like to run?\n";
507 my $ans = <STDIN>;
508 chomp $ans;
509 $default{"TEST_TYPE"} = $ans;
510 }
511
467 # set any defaults 512 # set any defaults
468 513
469 foreach my $default (keys %default) { 514 foreach my $default (keys %default) {
@@ -473,6 +518,69 @@ sub read_config {
473 } 518 }
474} 519}
475 520
521sub __eval_option {
522 my ($option, $i) = @_;
523
524 # Add space to evaluate the character before $
525 $option = " $option";
526 my $retval = "";
527
528 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
529 my $start = $1;
530 my $var = $2;
531 my $end = $3;
532
533 # Append beginning of line
534 $retval = "$retval$start";
535
536 # If the iteration option OPT[$i] exists, then use that.
537 # otherwise see if the default OPT (without [$i]) exists.
538
539 my $o = "$var\[$i\]";
540
541 if (defined($opt{$o})) {
542 $o = $opt{$o};
543 $retval = "$retval$o";
544 } elsif (defined($opt{$var})) {
545 $o = $opt{$var};
546 $retval = "$retval$o";
547 } else {
548 $retval = "$retval\$\{$var\}";
549 }
550
551 $option = $end;
552 }
553
554 $retval = "$retval$option";
555
556 $retval =~ s/^ //;
557
558 return $retval;
559}
560
561sub eval_option {
562 my ($option, $i) = @_;
563
564 my $prev = "";
565
566 # Since an option can evaluate to another option,
567 # keep iterating until we do not evaluate any more
568 # options.
569 my $r = 0;
570 while ($prev ne $option) {
571 # Check for recursive evaluations.
572 # 100 deep should be more than enough.
573 if ($r++ > 100) {
574 die "Over 100 evaluations accurred with $option\n" .
575 "Check for recursive variables\n";
576 }
577 $prev = $option;
578 $option = __eval_option($option, $i);
579 }
580
581 return $option;
582}
583
476sub _logit { 584sub _logit {
477 if (defined($opt{"LOG_FILE"})) { 585 if (defined($opt{"LOG_FILE"})) {
478 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; 586 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
@@ -617,9 +725,15 @@ sub fail {
617 end_monitor; 725 end_monitor;
618 } 726 }
619 727
728 my $name = "";
729
730 if (defined($test_name)) {
731 $name = " ($test_name)";
732 }
733
620 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 734 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
621 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 735 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
622 doprint "KTEST RESULT: TEST $i Failed: ", @_, "\n"; 736 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
623 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 737 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
624 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 738 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
625 739
@@ -836,17 +950,35 @@ sub monitor {
836 my $failure_start; 950 my $failure_start;
837 my $monitor_start = time; 951 my $monitor_start = time;
838 my $done = 0; 952 my $done = 0;
953 my $version_found = 0;
839 954
840 while (!$done) { 955 while (!$done) {
841 956
842 if ($booted) { 957 if ($bug && defined($stop_after_failure) &&
958 $stop_after_failure >= 0) {
959 my $time = $stop_after_failure - (time - $failure_start);
960 $line = wait_for_input($monitor_fp, $time);
961 if (!defined($line)) {
962 doprint "bug timed out after $booted_timeout seconds\n";
963 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
964 last;
965 }
966 } elsif ($booted) {
843 $line = wait_for_input($monitor_fp, $booted_timeout); 967 $line = wait_for_input($monitor_fp, $booted_timeout);
968 if (!defined($line)) {
969 my $s = $booted_timeout == 1 ? "" : "s";
970 doprint "Successful boot found: break after $booted_timeout second$s\n";
971 last;
972 }
844 } else { 973 } else {
845 $line = wait_for_input($monitor_fp); 974 $line = wait_for_input($monitor_fp);
975 if (!defined($line)) {
976 my $s = $timeout == 1 ? "" : "s";
977 doprint "Timed out after $timeout second$s\n";
978 last;
979 }
846 } 980 }
847 981
848 last if (!defined($line));
849
850 doprint $line; 982 doprint $line;
851 print DMESG $line; 983 print DMESG $line;
852 984
@@ -896,6 +1028,22 @@ sub monitor {
896 $bug = 1; 1028 $bug = 1;
897 } 1029 }
898 1030
1031 # Detect triple faults by testing the banner
1032 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1033 if ($1 eq $version) {
1034 $version_found = 1;
1035 } elsif ($version_found && $detect_triplefault) {
1036 # We already booted into the kernel we are testing,
1037 # but now we booted into another kernel?
1038 # Consider this a triple fault.
1039 doprint "Aleady booted in Linux kernel $version, but now\n";
1040 doprint "we booted into Linux kernel $1.\n";
1041 doprint "Assuming that this is a triple fault.\n";
1042 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1043 last;
1044 }
1045 }
1046
899 if ($line =~ /\n/) { 1047 if ($line =~ /\n/) {
900 $full_line = ""; 1048 $full_line = "";
901 } 1049 }
@@ -923,6 +1071,16 @@ sub monitor {
923 return 1; 1071 return 1;
924} 1072}
925 1073
1074sub do_post_install {
1075
1076 return if (!defined($post_install));
1077
1078 my $cp_post_install = $post_install;
1079 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1080 run_command "$cp_post_install" or
1081 dodie "Failed to run post install";
1082}
1083
926sub install { 1084sub install {
927 1085
928 run_scp "$outputdir/$build_target", "$target_image" or 1086 run_scp "$outputdir/$build_target", "$target_image" or
@@ -942,6 +1100,7 @@ sub install {
942 close(IN); 1100 close(IN);
943 1101
944 if (!$install_mods) { 1102 if (!$install_mods) {
1103 do_post_install;
945 doprint "No modules needed\n"; 1104 doprint "No modules needed\n";
946 return; 1105 return;
947 } 1106 }
@@ -964,17 +1123,29 @@ sub install {
964 1123
965 unlink "$tmpdir/$modtar"; 1124 unlink "$tmpdir/$modtar";
966 1125
967 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or 1126 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
968 dodie "failed to tar modules"; 1127 dodie "failed to tar modules";
969 1128
970 run_ssh "rm -f /tmp/$modtar"; 1129 run_ssh "rm -f /tmp/$modtar";
971 1130
972 return if (!defined($post_install)); 1131 do_post_install;
1132}
973 1133
974 my $cp_post_install = $post_install; 1134sub get_version {
975 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g; 1135 # get the release name
976 run_command "$cp_post_install" or 1136 doprint "$make kernelrelease ... ";
977 dodie "Failed to run post install"; 1137 $version = `$make kernelrelease | tail -1`;
1138 chomp($version);
1139 doprint "$version\n";
1140}
1141
1142sub start_monitor_and_boot {
1143 get_grub_index;
1144 get_version;
1145 install;
1146
1147 start_monitor;
1148 return monitor;
978} 1149}
979 1150
980sub check_buildlog { 1151sub check_buildlog {
@@ -1009,24 +1180,84 @@ sub check_buildlog {
1009 return 1; 1180 return 1;
1010} 1181}
1011 1182
1183sub apply_min_config {
1184 my $outconfig = "$output_config.new";
1185
1186 # Read the config file and remove anything that
1187 # is in the force_config hash (from minconfig and others)
1188 # then add the force config back.
1189
1190 doprint "Applying minimum configurations into $output_config.new\n";
1191
1192 open (OUT, ">$outconfig") or
1193 dodie "Can't create $outconfig";
1194
1195 if (-f $output_config) {
1196 open (IN, $output_config) or
1197 dodie "Failed to open $output_config";
1198 while (<IN>) {
1199 if (/^(# )?(CONFIG_[^\s=]*)/) {
1200 next if (defined($force_config{$2}));
1201 }
1202 print OUT;
1203 }
1204 close IN;
1205 }
1206 foreach my $config (keys %force_config) {
1207 print OUT "$force_config{$config}\n";
1208 }
1209 close OUT;
1210
1211 run_command "mv $outconfig $output_config";
1212}
1213
1012sub make_oldconfig { 1214sub make_oldconfig {
1013 my ($defconfig) = @_;
1014 1215
1015 if (!run_command "$defconfig $make oldnoconfig") { 1216 my @force_list = keys %force_config;
1217
1218 if ($#force_list >= 0) {
1219 apply_min_config;
1220 }
1221
1222 if (!run_command "$make oldnoconfig") {
1016 # Perhaps oldnoconfig doesn't exist in this version of the kernel 1223 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1017 # try a yes '' | oldconfig 1224 # try a yes '' | oldconfig
1018 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n"; 1225 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1019 run_command "yes '' | $defconfig $make oldconfig" or 1226 run_command "yes '' | $make oldconfig" or
1020 dodie "failed make config oldconfig"; 1227 dodie "failed make config oldconfig";
1021 } 1228 }
1022} 1229}
1023 1230
1231# read a config file and use this to force new configs.
1232sub load_force_config {
1233 my ($config) = @_;
1234
1235 open(IN, $config) or
1236 dodie "failed to read $config";
1237 while (<IN>) {
1238 chomp;
1239 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1240 $force_config{$1} = $_;
1241 } elsif (/^# (CONFIG_\S*) is not set/) {
1242 $force_config{$1} = $_;
1243 }
1244 }
1245 close IN;
1246}
1247
1024sub build { 1248sub build {
1025 my ($type) = @_; 1249 my ($type) = @_;
1026 my $defconfig = "";
1027 1250
1028 unlink $buildlog; 1251 unlink $buildlog;
1029 1252
1253 if (defined($pre_build)) {
1254 my $ret = run_command $pre_build;
1255 if (!$ret && defined($pre_build_die) &&
1256 $pre_build_die) {
1257 dodie "failed to pre_build\n";
1258 }
1259 }
1260
1030 if ($type =~ /^useconfig:(.*)/) { 1261 if ($type =~ /^useconfig:(.*)/) {
1031 run_command "cp $1 $output_config" or 1262 run_command "cp $1 $output_config" or
1032 dodie "could not copy $1 to .config"; 1263 dodie "could not copy $1 to .config";
@@ -1063,24 +1294,33 @@ sub build {
1063 close(OUT); 1294 close(OUT);
1064 1295
1065 if (defined($minconfig)) { 1296 if (defined($minconfig)) {
1066 $defconfig = "KCONFIG_ALLCONFIG=$minconfig"; 1297 load_force_config($minconfig);
1067 } 1298 }
1068 1299
1069 if ($type eq "oldnoconfig") { 1300 if ($type ne "oldnoconfig") {
1070 make_oldconfig $defconfig; 1301 run_command "$make $type" or
1071 } else {
1072 run_command "$defconfig $make $type" or
1073 dodie "failed make config"; 1302 dodie "failed make config";
1074 } 1303 }
1304 # Run old config regardless, to enforce min configurations
1305 make_oldconfig;
1075 1306
1076 $redirect = "$buildlog"; 1307 $redirect = "$buildlog";
1077 if (!run_command "$make $build_options") { 1308 my $build_ret = run_command "$make $build_options";
1078 undef $redirect; 1309 undef $redirect;
1310
1311 if (defined($post_build)) {
1312 my $ret = run_command $post_build;
1313 if (!$ret && defined($post_build_die) &&
1314 $post_build_die) {
1315 dodie "failed to post_build\n";
1316 }
1317 }
1318
1319 if (!$build_ret) {
1079 # bisect may need this to pass 1320 # bisect may need this to pass
1080 return 0 if ($in_bisect); 1321 return 0 if ($in_bisect);
1081 fail "failed build" and return 0; 1322 fail "failed build" and return 0;
1082 } 1323 }
1083 undef $redirect;
1084 1324
1085 return 1; 1325 return 1;
1086} 1326}
@@ -1102,9 +1342,15 @@ sub success {
1102 1342
1103 $successes++; 1343 $successes++;
1104 1344
1345 my $name = "";
1346
1347 if (defined($test_name)) {
1348 $name = " ($test_name)";
1349 }
1350
1105 doprint "\n\n*******************************************\n"; 1351 doprint "\n\n*******************************************\n";
1106 doprint "*******************************************\n"; 1352 doprint "*******************************************\n";
1107 doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n"; 1353 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
1108 doprint "*******************************************\n"; 1354 doprint "*******************************************\n";
1109 doprint "*******************************************\n"; 1355 doprint "*******************************************\n";
1110 1356
@@ -1117,14 +1363,6 @@ sub success {
1117 } 1363 }
1118} 1364}
1119 1365
1120sub get_version {
1121 # get the release name
1122 doprint "$make kernelrelease ... ";
1123 $version = `$make kernelrelease | tail -1`;
1124 chomp($version);
1125 doprint "$version\n";
1126}
1127
1128sub answer_bisect { 1366sub answer_bisect {
1129 for (;;) { 1367 for (;;) {
1130 doprint "Pass or fail? [p/f]"; 1368 doprint "Pass or fail? [p/f]";
@@ -1289,12 +1527,7 @@ sub run_bisect_test {
1289 dodie "Failed on build" if $failed; 1527 dodie "Failed on build" if $failed;
1290 1528
1291 # Now boot the box 1529 # Now boot the box
1292 get_grub_index; 1530 start_monitor_and_boot or $failed = 1;
1293 get_version;
1294 install;
1295
1296 start_monitor;
1297 monitor or $failed = 1;
1298 1531
1299 if ($type ne "boot") { 1532 if ($type ne "boot") {
1300 if ($failed && $bisect_skip) { 1533 if ($failed && $bisect_skip) {
@@ -1473,21 +1706,27 @@ my %null_config;
1473 1706
1474my %dependency; 1707my %dependency;
1475 1708
1476sub process_config_ignore { 1709sub assign_configs {
1477 my ($config) = @_; 1710 my ($hash, $config) = @_;
1478 1711
1479 open (IN, $config) 1712 open (IN, $config)
1480 or dodie "Failed to read $config"; 1713 or dodie "Failed to read $config";
1481 1714
1482 while (<IN>) { 1715 while (<IN>) {
1483 if (/^((CONFIG\S*)=.*)/) { 1716 if (/^((CONFIG\S*)=.*)/) {
1484 $config_ignore{$2} = $1; 1717 ${$hash}{$2} = $1;
1485 } 1718 }
1486 } 1719 }
1487 1720
1488 close(IN); 1721 close(IN);
1489} 1722}
1490 1723
1724sub process_config_ignore {
1725 my ($config) = @_;
1726
1727 assign_configs \%config_ignore, $config;
1728}
1729
1491sub read_current_config { 1730sub read_current_config {
1492 my ($config_ref) = @_; 1731 my ($config_ref) = @_;
1493 1732
@@ -1546,7 +1785,7 @@ sub create_config {
1546 close(OUT); 1785 close(OUT);
1547 1786
1548# exit; 1787# exit;
1549 make_oldconfig ""; 1788 make_oldconfig;
1550} 1789}
1551 1790
1552sub compare_configs { 1791sub compare_configs {
@@ -1718,6 +1957,10 @@ sub config_bisect {
1718 1957
1719 my $tmpconfig = "$tmpdir/use_config"; 1958 my $tmpconfig = "$tmpdir/use_config";
1720 1959
1960 if (defined($config_bisect_good)) {
1961 process_config_ignore $config_bisect_good;
1962 }
1963
1721 # Make the file with the bad config and the min config 1964 # Make the file with the bad config and the min config
1722 if (defined($minconfig)) { 1965 if (defined($minconfig)) {
1723 # read the min config for things to ignore 1966 # read the min config for things to ignore
@@ -1727,15 +1970,8 @@ sub config_bisect {
1727 unlink $tmpconfig; 1970 unlink $tmpconfig;
1728 } 1971 }
1729 1972
1730 # Add other configs
1731 if (defined($addconfig)) {
1732 run_command "cat $addconfig >> $tmpconfig" or
1733 dodie "failed to append $addconfig";
1734 }
1735
1736 my $defconfig = "";
1737 if (-f $tmpconfig) { 1973 if (-f $tmpconfig) {
1738 $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig"; 1974 load_force_config($tmpconfig);
1739 process_config_ignore $tmpconfig; 1975 process_config_ignore $tmpconfig;
1740 } 1976 }
1741 1977
@@ -1755,8 +1991,8 @@ sub config_bisect {
1755 } 1991 }
1756 close(IN); 1992 close(IN);
1757 1993
1758 # Now run oldconfig with the minconfig (and addconfigs) 1994 # Now run oldconfig with the minconfig
1759 make_oldconfig $defconfig; 1995 make_oldconfig;
1760 1996
1761 # check to see what we lost (or gained) 1997 # check to see what we lost (or gained)
1762 open (IN, $output_config) 1998 open (IN, $output_config)
@@ -1882,6 +2118,13 @@ sub patchcheck {
1882 @list = reverse @list; 2118 @list = reverse @list;
1883 2119
1884 my $save_clean = $noclean; 2120 my $save_clean = $noclean;
2121 my %ignored_warnings;
2122
2123 if (defined($ignore_warnings)) {
2124 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2125 $ignored_warnings{$sha1} = 1;
2126 }
2127 }
1885 2128
1886 $in_patchcheck = 1; 2129 $in_patchcheck = 1;
1887 foreach my $item (@list) { 2130 foreach my $item (@list) {
@@ -1908,18 +2151,16 @@ sub patchcheck {
1908 build "oldconfig" or return 0; 2151 build "oldconfig" or return 0;
1909 } 2152 }
1910 2153
1911 check_buildlog $sha1 or return 0;
1912 2154
1913 next if ($type eq "build"); 2155 if (!defined($ignored_warnings{$sha1})) {
2156 check_buildlog $sha1 or return 0;
2157 }
1914 2158
1915 get_grub_index; 2159 next if ($type eq "build");
1916 get_version;
1917 install;
1918 2160
1919 my $failed = 0; 2161 my $failed = 0;
1920 2162
1921 start_monitor; 2163 start_monitor_and_boot or $failed = 1;
1922 monitor or $failed = 1;
1923 2164
1924 if (!$failed && $type ne "boot"){ 2165 if (!$failed && $type ne "boot"){
1925 do_run_test or $failed = 1; 2166 do_run_test or $failed = 1;
@@ -1936,24 +2177,505 @@ sub patchcheck {
1936 return 1; 2177 return 1;
1937} 2178}
1938 2179
2180my %depends;
2181my $iflevel = 0;
2182my @ifdeps;
2183
2184# prevent recursion
2185my %read_kconfigs;
2186
2187# taken from streamline_config.pl
2188sub read_kconfig {
2189 my ($kconfig) = @_;
2190
2191 my $state = "NONE";
2192 my $config;
2193 my @kconfigs;
2194
2195 my $cont = 0;
2196 my $line;
2197
2198
2199 if (! -f $kconfig) {
2200 doprint "file $kconfig does not exist, skipping\n";
2201 return;
2202 }
2203
2204 open(KIN, "$kconfig")
2205 or die "Can't open $kconfig";
2206 while (<KIN>) {
2207 chomp;
2208
2209 # Make sure that lines ending with \ continue
2210 if ($cont) {
2211 $_ = $line . " " . $_;
2212 }
2213
2214 if (s/\\$//) {
2215 $cont = 1;
2216 $line = $_;
2217 next;
2218 }
2219
2220 $cont = 0;
2221
2222 # collect any Kconfig sources
2223 if (/^source\s*"(.*)"/) {
2224 $kconfigs[$#kconfigs+1] = $1;
2225 }
2226
2227 # configs found
2228 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2229 $state = "NEW";
2230 $config = $2;
2231
2232 for (my $i = 0; $i < $iflevel; $i++) {
2233 if ($i) {
2234 $depends{$config} .= " " . $ifdeps[$i];
2235 } else {
2236 $depends{$config} = $ifdeps[$i];
2237 }
2238 $state = "DEP";
2239 }
2240
2241 # collect the depends for the config
2242 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2243
2244 if (defined($depends{$1})) {
2245 $depends{$config} .= " " . $1;
2246 } else {
2247 $depends{$config} = $1;
2248 }
2249
2250 # Get the configs that select this config
2251 } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) {
2252 if (defined($depends{$1})) {
2253 $depends{$1} .= " " . $config;
2254 } else {
2255 $depends{$1} = $config;
2256 }
2257
2258 # Check for if statements
2259 } elsif (/^if\s+(.*\S)\s*$/) {
2260 my $deps = $1;
2261 # remove beginning and ending non text
2262 $deps =~ s/^[^a-zA-Z0-9_]*//;
2263 $deps =~ s/[^a-zA-Z0-9_]*$//;
2264
2265 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2266
2267 $ifdeps[$iflevel++] = join ':', @deps;
2268
2269 } elsif (/^endif/) {
2270
2271 $iflevel-- if ($iflevel);
2272
2273 # stop on "help"
2274 } elsif (/^\s*help\s*$/) {
2275 $state = "NONE";
2276 }
2277 }
2278 close(KIN);
2279
2280 # read in any configs that were found.
2281 foreach $kconfig (@kconfigs) {
2282 if (!defined($read_kconfigs{$kconfig})) {
2283 $read_kconfigs{$kconfig} = 1;
2284 read_kconfig("$builddir/$kconfig");
2285 }
2286 }
2287}
2288
2289sub read_depends {
2290 # find out which arch this is by the kconfig file
2291 open (IN, $output_config)
2292 or dodie "Failed to read $output_config";
2293 my $arch;
2294 while (<IN>) {
2295 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2296 $arch = $1;
2297 last;
2298 }
2299 }
2300 close IN;
2301
2302 if (!defined($arch)) {
2303 doprint "Could not find arch from config file\n";
2304 doprint "no dependencies used\n";
2305 return;
2306 }
2307
2308 # arch is really the subarch, we need to know
2309 # what directory to look at.
2310 if ($arch eq "i386" || $arch eq "x86_64") {
2311 $arch = "x86";
2312 } elsif ($arch =~ /^tile/) {
2313 $arch = "tile";
2314 }
2315
2316 my $kconfig = "$builddir/arch/$arch/Kconfig";
2317
2318 if (! -f $kconfig && $arch =~ /\d$/) {
2319 my $orig = $arch;
2320 # some subarchs have numbers, truncate them
2321 $arch =~ s/\d*$//;
2322 $kconfig = "$builddir/arch/$arch/Kconfig";
2323 if (! -f $kconfig) {
2324 doprint "No idea what arch dir $orig is for\n";
2325 doprint "no dependencies used\n";
2326 return;
2327 }
2328 }
2329
2330 read_kconfig($kconfig);
2331}
2332
2333sub read_config_list {
2334 my ($config) = @_;
2335
2336 open (IN, $config)
2337 or dodie "Failed to read $config";
2338
2339 while (<IN>) {
2340 if (/^((CONFIG\S*)=.*)/) {
2341 if (!defined($config_ignore{$2})) {
2342 $config_list{$2} = $1;
2343 }
2344 }
2345 }
2346
2347 close(IN);
2348}
2349
2350sub read_output_config {
2351 my ($config) = @_;
2352
2353 assign_configs \%config_ignore, $config;
2354}
2355
2356sub make_new_config {
2357 my @configs = @_;
2358
2359 open (OUT, ">$output_config")
2360 or dodie "Failed to write $output_config";
2361
2362 foreach my $config (@configs) {
2363 print OUT "$config\n";
2364 }
2365 close OUT;
2366}
2367
2368sub get_depends {
2369 my ($dep) = @_;
2370
2371 my $kconfig = $dep;
2372 $kconfig =~ s/CONFIG_//;
2373
2374 $dep = $depends{"$kconfig"};
2375
2376 # the dep string we have saves the dependencies as they
2377 # were found, including expressions like ! && ||. We
2378 # want to split this out into just an array of configs.
2379
2380 my $valid = "A-Za-z_0-9";
2381
2382 my @configs;
2383
2384 while ($dep =~ /[$valid]/) {
2385
2386 if ($dep =~ /^[^$valid]*([$valid]+)/) {
2387 my $conf = "CONFIG_" . $1;
2388
2389 $configs[$#configs + 1] = $conf;
2390
2391 $dep =~ s/^[^$valid]*[$valid]+//;
2392 } else {
2393 die "this should never happen";
2394 }
2395 }
2396
2397 return @configs;
2398}
2399
2400my %min_configs;
2401my %keep_configs;
2402my %save_configs;
2403my %processed_configs;
2404my %nochange_config;
2405
2406sub test_this_config {
2407 my ($config) = @_;
2408
2409 my $found;
2410
2411 # if we already processed this config, skip it
2412 if (defined($processed_configs{$config})) {
2413 return undef;
2414 }
2415 $processed_configs{$config} = 1;
2416
2417 # if this config failed during this round, skip it
2418 if (defined($nochange_config{$config})) {
2419 return undef;
2420 }
2421
2422 my $kconfig = $config;
2423 $kconfig =~ s/CONFIG_//;
2424
2425 # Test dependencies first
2426 if (defined($depends{"$kconfig"})) {
2427 my @parents = get_depends $config;
2428 foreach my $parent (@parents) {
2429 # if the parent is in the min config, check it first
2430 next if (!defined($min_configs{$parent}));
2431 $found = test_this_config($parent);
2432 if (defined($found)) {
2433 return $found;
2434 }
2435 }
2436 }
2437
2438 # Remove this config from the list of configs
2439 # do a make oldnoconfig and then read the resulting
2440 # .config to make sure it is missing the config that
2441 # we had before
2442 my %configs = %min_configs;
2443 delete $configs{$config};
2444 make_new_config ((values %configs), (values %keep_configs));
2445 make_oldconfig;
2446 undef %configs;
2447 assign_configs \%configs, $output_config;
2448
2449 return $config if (!defined($configs{$config}));
2450
2451 doprint "disabling config $config did not change .config\n";
2452
2453 $nochange_config{$config} = 1;
2454
2455 return undef;
2456}
2457
2458sub make_min_config {
2459 my ($i) = @_;
2460
2461 if (!defined($output_minconfig)) {
2462 fail "OUTPUT_MIN_CONFIG not defined" and return;
2463 }
2464
2465 # If output_minconfig exists, and the start_minconfig
2466 # came from min_config, than ask if we should use
2467 # that instead.
2468 if (-f $output_minconfig && !$start_minconfig_defined) {
2469 print "$output_minconfig exists\n";
2470 if (read_yn " Use it as minconfig?") {
2471 $start_minconfig = $output_minconfig;
2472 }
2473 }
2474
2475 if (!defined($start_minconfig)) {
2476 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2477 }
2478
2479 my $temp_config = "$tmpdir/temp_config";
2480
2481 # First things first. We build an allnoconfig to find
2482 # out what the defaults are that we can't touch.
2483 # Some are selections, but we really can't handle selections.
2484
2485 my $save_minconfig = $minconfig;
2486 undef $minconfig;
2487
2488 run_command "$make allnoconfig" or return 0;
2489
2490 read_depends;
2491
2492 process_config_ignore $output_config;
2493
2494 undef %save_configs;
2495 undef %min_configs;
2496
2497 if (defined($ignore_config)) {
2498 # make sure the file exists
2499 `touch $ignore_config`;
2500 assign_configs \%save_configs, $ignore_config;
2501 }
2502
2503 %keep_configs = %save_configs;
2504
2505 doprint "Load initial configs from $start_minconfig\n";
2506
2507 # Look at the current min configs, and save off all the
2508 # ones that were set via the allnoconfig
2509 assign_configs \%min_configs, $start_minconfig;
2510
2511 my @config_keys = keys %min_configs;
2512
2513 # Remove anything that was set by the make allnoconfig
2514 # we shouldn't need them as they get set for us anyway.
2515 foreach my $config (@config_keys) {
2516 # Remove anything in the ignore_config
2517 if (defined($keep_configs{$config})) {
2518 my $file = $ignore_config;
2519 $file =~ s,.*/(.*?)$,$1,;
2520 doprint "$config set by $file ... ignored\n";
2521 delete $min_configs{$config};
2522 next;
2523 }
2524 # But make sure the settings are the same. If a min config
2525 # sets a selection, we do not want to get rid of it if
2526 # it is not the same as what we have. Just move it into
2527 # the keep configs.
2528 if (defined($config_ignore{$config})) {
2529 if ($config_ignore{$config} ne $min_configs{$config}) {
2530 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2531 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2532 $keep_configs{$config} = $min_configs{$config};
2533 } else {
2534 doprint "$config set by allnoconfig ... ignored\n";
2535 }
2536 delete $min_configs{$config};
2537 }
2538 }
2539
2540 my $done = 0;
2541 my $take_two = 0;
2542
2543 while (!$done) {
2544
2545 my $config;
2546 my $found;
2547
2548 # Now disable each config one by one and do a make oldconfig
2549 # till we find a config that changes our list.
2550
2551 # Put configs that did not modify the config at the end.
2552 my @test_configs = keys %min_configs;
2553 my $reset = 1;
2554 for (my $i = 0; $i < $#test_configs; $i++) {
2555 if (!defined($nochange_config{$test_configs[0]})) {
2556 $reset = 0;
2557 last;
2558 }
2559 # This config didn't change the .config last time.
2560 # Place it at the end
2561 my $config = shift @test_configs;
2562 push @test_configs, $config;
2563 }
2564
2565 # if every test config has failed to modify the .config file
2566 # in the past, then reset and start over.
2567 if ($reset) {
2568 undef %nochange_config;
2569 }
2570
2571 undef %processed_configs;
2572
2573 foreach my $config (@test_configs) {
2574
2575 $found = test_this_config $config;
2576
2577 last if (defined($found));
2578
2579 # oh well, try another config
2580 }
2581
2582 if (!defined($found)) {
2583 # we could have failed due to the nochange_config hash
2584 # reset and try again
2585 if (!$take_two) {
2586 undef %nochange_config;
2587 $take_two = 1;
2588 next;
2589 }
2590 doprint "No more configs found that we can disable\n";
2591 $done = 1;
2592 last;
2593 }
2594 $take_two = 0;
2595
2596 $config = $found;
2597
2598 doprint "Test with $config disabled\n";
2599
2600 # set in_bisect to keep build and monitor from dieing
2601 $in_bisect = 1;
2602
2603 my $failed = 0;
2604 build "oldconfig";
2605 start_monitor_and_boot or $failed = 1;
2606 end_monitor;
2607
2608 $in_bisect = 0;
2609
2610 if ($failed) {
2611 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
2612 # this config is needed, add it to the ignore list.
2613 $keep_configs{$config} = $min_configs{$config};
2614 $save_configs{$config} = $min_configs{$config};
2615 delete $min_configs{$config};
2616
2617 # update new ignore configs
2618 if (defined($ignore_config)) {
2619 open (OUT, ">$temp_config")
2620 or die "Can't write to $temp_config";
2621 foreach my $config (keys %save_configs) {
2622 print OUT "$save_configs{$config}\n";
2623 }
2624 close OUT;
2625 run_command "mv $temp_config $ignore_config" or
2626 dodie "failed to copy update to $ignore_config";
2627 }
2628
2629 } else {
2630 # We booted without this config, remove it from the minconfigs.
2631 doprint "$config is not needed, disabling\n";
2632
2633 delete $min_configs{$config};
2634
2635 # Also disable anything that is not enabled in this config
2636 my %configs;
2637 assign_configs \%configs, $output_config;
2638 my @config_keys = keys %min_configs;
2639 foreach my $config (@config_keys) {
2640 if (!defined($configs{$config})) {
2641 doprint "$config is not set, disabling\n";
2642 delete $min_configs{$config};
2643 }
2644 }
2645
2646 # Save off all the current mandidory configs
2647 open (OUT, ">$temp_config")
2648 or die "Can't write to $temp_config";
2649 foreach my $config (keys %keep_configs) {
2650 print OUT "$keep_configs{$config}\n";
2651 }
2652 foreach my $config (keys %min_configs) {
2653 print OUT "$min_configs{$config}\n";
2654 }
2655 close OUT;
2656
2657 run_command "mv $temp_config $output_minconfig" or
2658 dodie "failed to copy update to $output_minconfig";
2659 }
2660
2661 doprint "Reboot and wait $sleep_time seconds\n";
2662 reboot;
2663 start_monitor;
2664 wait_for_monitor $sleep_time;
2665 end_monitor;
2666 }
2667
2668 success $i;
2669 return 1;
2670}
2671
1939$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n"; 2672$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
1940 2673
1941if ($#ARGV == 0) { 2674if ($#ARGV == 0) {
1942 $ktest_config = $ARGV[0]; 2675 $ktest_config = $ARGV[0];
1943 if (! -f $ktest_config) { 2676 if (! -f $ktest_config) {
1944 print "$ktest_config does not exist.\n"; 2677 print "$ktest_config does not exist.\n";
1945 my $ans; 2678 if (!read_yn "Create it?") {
1946 for (;;) {
1947 print "Create it? [Y/n] ";
1948 $ans = <STDIN>;
1949 chomp $ans;
1950 if ($ans =~ /^\s*$/) {
1951 $ans = "y";
1952 }
1953 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
1954 print "Please answer either 'y' or 'n'.\n";
1955 }
1956 if ($ans !~ /^y$/i) {
1957 exit 0; 2679 exit 0;
1958 } 2680 }
1959 } 2681 }
@@ -1977,6 +2699,10 @@ EOF
1977} 2699}
1978read_config $ktest_config; 2700read_config $ktest_config;
1979 2701
2702if (defined($opt{"LOG_FILE"})) {
2703 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2704}
2705
1980# Append any configs entered in manually to the config file. 2706# Append any configs entered in manually to the config file.
1981my @new_configs = keys %entered_configs; 2707my @new_configs = keys %entered_configs;
1982if ($#new_configs >= 0) { 2708if ($#new_configs >= 0) {
@@ -2045,70 +2771,13 @@ sub __set_test_option {
2045 return undef; 2771 return undef;
2046} 2772}
2047 2773
2048sub eval_option {
2049 my ($option, $i) = @_;
2050
2051 # Add space to evaluate the character before $
2052 $option = " $option";
2053 my $retval = "";
2054
2055 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
2056 my $start = $1;
2057 my $var = $2;
2058 my $end = $3;
2059
2060 # Append beginning of line
2061 $retval = "$retval$start";
2062
2063 # If the iteration option OPT[$i] exists, then use that.
2064 # otherwise see if the default OPT (without [$i]) exists.
2065
2066 my $o = "$var\[$i\]";
2067
2068 if (defined($opt{$o})) {
2069 $o = $opt{$o};
2070 $retval = "$retval$o";
2071 } elsif (defined($opt{$var})) {
2072 $o = $opt{$var};
2073 $retval = "$retval$o";
2074 } else {
2075 $retval = "$retval\$\{$var\}";
2076 }
2077
2078 $option = $end;
2079 }
2080
2081 $retval = "$retval$option";
2082
2083 $retval =~ s/^ //;
2084
2085 return $retval;
2086}
2087
2088sub set_test_option { 2774sub set_test_option {
2089 my ($name, $i) = @_; 2775 my ($name, $i) = @_;
2090 2776
2091 my $option = __set_test_option($name, $i); 2777 my $option = __set_test_option($name, $i);
2092 return $option if (!defined($option)); 2778 return $option if (!defined($option));
2093 2779
2094 my $prev = ""; 2780 return eval_option($option, $i);
2095
2096 # Since an option can evaluate to another option,
2097 # keep iterating until we do not evaluate any more
2098 # options.
2099 my $r = 0;
2100 while ($prev ne $option) {
2101 # Check for recursive evaluations.
2102 # 100 deep should be more than enough.
2103 if ($r++ > 100) {
2104 die "Over 100 evaluations accurred with $name\n" .
2105 "Check for recursive variables\n";
2106 }
2107 $prev = $option;
2108 $option = eval_option($option, $i);
2109 }
2110
2111 return $option;
2112} 2781}
2113 2782
2114# First we need to do is the builds 2783# First we need to do is the builds
@@ -2126,10 +2795,17 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2126 $test_type = set_test_option("TEST_TYPE", $i); 2795 $test_type = set_test_option("TEST_TYPE", $i);
2127 $build_type = set_test_option("BUILD_TYPE", $i); 2796 $build_type = set_test_option("BUILD_TYPE", $i);
2128 $build_options = set_test_option("BUILD_OPTIONS", $i); 2797 $build_options = set_test_option("BUILD_OPTIONS", $i);
2798 $pre_build = set_test_option("PRE_BUILD", $i);
2799 $post_build = set_test_option("POST_BUILD", $i);
2800 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
2801 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
2129 $power_cycle = set_test_option("POWER_CYCLE", $i); 2802 $power_cycle = set_test_option("POWER_CYCLE", $i);
2130 $reboot = set_test_option("REBOOT", $i); 2803 $reboot = set_test_option("REBOOT", $i);
2131 $noclean = set_test_option("BUILD_NOCLEAN", $i); 2804 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2132 $minconfig = set_test_option("MIN_CONFIG", $i); 2805 $minconfig = set_test_option("MIN_CONFIG", $i);
2806 $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
2807 $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
2808 $ignore_config = set_test_option("IGNORE_CONFIG", $i);
2133 $run_test = set_test_option("TEST", $i); 2809 $run_test = set_test_option("TEST", $i);
2134 $addconfig = set_test_option("ADD_CONFIG", $i); 2810 $addconfig = set_test_option("ADD_CONFIG", $i);
2135 $reboot_type = set_test_option("REBOOT_TYPE", $i); 2811 $reboot_type = set_test_option("REBOOT_TYPE", $i);
@@ -2145,12 +2821,16 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2145 $sleep_time = set_test_option("SLEEP_TIME", $i); 2821 $sleep_time = set_test_option("SLEEP_TIME", $i);
2146 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i); 2822 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
2147 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i); 2823 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
2824 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
2148 $bisect_manual = set_test_option("BISECT_MANUAL", $i); 2825 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
2149 $bisect_skip = set_test_option("BISECT_SKIP", $i); 2826 $bisect_skip = set_test_option("BISECT_SKIP", $i);
2827 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
2150 $store_failures = set_test_option("STORE_FAILURES", $i); 2828 $store_failures = set_test_option("STORE_FAILURES", $i);
2829 $test_name = set_test_option("TEST_NAME", $i);
2151 $timeout = set_test_option("TIMEOUT", $i); 2830 $timeout = set_test_option("TIMEOUT", $i);
2152 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i); 2831 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2153 $console = set_test_option("CONSOLE", $i); 2832 $console = set_test_option("CONSOLE", $i);
2833 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
2154 $success_line = set_test_option("SUCCESS_LINE", $i); 2834 $success_line = set_test_option("SUCCESS_LINE", $i);
2155 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i); 2835 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2156 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i); 2836 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
@@ -2161,6 +2841,13 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2161 $target_image = set_test_option("TARGET_IMAGE", $i); 2841 $target_image = set_test_option("TARGET_IMAGE", $i);
2162 $localversion = set_test_option("LOCALVERSION", $i); 2842 $localversion = set_test_option("LOCALVERSION", $i);
2163 2843
2844 $start_minconfig_defined = 1;
2845
2846 if (!defined($start_minconfig)) {
2847 $start_minconfig_defined = 0;
2848 $start_minconfig = $minconfig;
2849 }
2850
2164 chdir $builddir || die "can't change directory to $builddir"; 2851 chdir $builddir || die "can't change directory to $builddir";
2165 2852
2166 if (!-d $tmpdir) { 2853 if (!-d $tmpdir) {
@@ -2193,6 +2880,10 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2193 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"}; 2880 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
2194 } 2881 }
2195 2882
2883 if ($test_type eq "make_min_config") {
2884 $run_type = "";
2885 }
2886
2196 # mistake in config file? 2887 # mistake in config file?
2197 if (!defined($run_type)) { 2888 if (!defined($run_type)) {
2198 $run_type = "ERROR"; 2889 $run_type = "ERROR";
@@ -2204,11 +2895,12 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2204 unlink $dmesg; 2895 unlink $dmesg;
2205 unlink $buildlog; 2896 unlink $buildlog;
2206 2897
2207 if (!defined($minconfig)) { 2898 if (defined($addconfig)) {
2208 $minconfig = $addconfig; 2899 my $min = $minconfig;
2209 2900 if (!defined($minconfig)) {
2210 } elsif (defined($addconfig)) { 2901 $min = "";
2211 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or 2902 }
2903 run_command "cat $addconfig $min > $tmpdir/add_config" or
2212 dodie "Failed to create temp config"; 2904 dodie "Failed to create temp config";
2213 $minconfig = "$tmpdir/add_config"; 2905 $minconfig = "$tmpdir/add_config";
2214 } 2906 }
@@ -2228,6 +2920,9 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2228 } elsif ($test_type eq "patchcheck") { 2920 } elsif ($test_type eq "patchcheck") {
2229 patchcheck $i; 2921 patchcheck $i;
2230 next; 2922 next;
2923 } elsif ($test_type eq "make_min_config") {
2924 make_min_config $i;
2925 next;
2231 } 2926 }
2232 2927
2233 if ($build_type ne "nobuild") { 2928 if ($build_type ne "nobuild") {
@@ -2235,13 +2930,8 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2235 } 2930 }
2236 2931
2237 if ($test_type ne "build") { 2932 if ($test_type ne "build") {
2238 get_grub_index;
2239 get_version;
2240 install;
2241
2242 my $failed = 0; 2933 my $failed = 0;
2243 start_monitor; 2934 start_monitor_and_boot or $failed = 1;
2244 monitor or $failed = 1;;
2245 2935
2246 if (!$failed && $test_type ne "boot" && defined($run_test)) { 2936 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2247 do_run_test or $failed = 1; 2937 do_run_test or $failed = 1;
diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf
index 48cbcc80602a..b8bcd14b5a4d 100644
--- a/tools/testing/ktest/sample.conf
+++ b/tools/testing/ktest/sample.conf
@@ -293,6 +293,38 @@
293# or on some systems: 293# or on some systems:
294#POST_INSTALL = ssh user@target /sbin/dracut -f /boot/initramfs-test.img $KERNEL_VERSION 294#POST_INSTALL = ssh user@target /sbin/dracut -f /boot/initramfs-test.img $KERNEL_VERSION
295 295
296# If there is a script that you require to run before the build is done
297# you can specify it with PRE_BUILD.
298#
299# One example may be if you must add a temporary patch to the build to
300# fix a unrelated bug to perform a patchcheck test. This will apply the
301# patch before each build that is made. Use the POST_BUILD to do a git reset --hard
302# to remove the patch.
303#
304# (default undef)
305#PRE_BUILD = cd ${BUILD_DIR} && patch -p1 < /tmp/temp.patch
306
307# To specify if the test should fail if the PRE_BUILD fails,
308# PRE_BUILD_DIE needs to be set to 1. Otherwise the PRE_BUILD
309# result is ignored.
310# (default 0)
311# PRE_BUILD_DIE = 1
312
313# If there is a script that should run after the build is done
314# you can specify it with POST_BUILD.
315#
316# As the example in PRE_BUILD, POST_BUILD can be used to reset modifications
317# made by the PRE_BUILD.
318#
319# (default undef)
320#POST_BUILD = cd ${BUILD_DIR} && git reset --hard
321
322# To specify if the test should fail if the POST_BUILD fails,
323# POST_BUILD_DIE needs to be set to 1. Otherwise the POST_BUILD
324# result is ignored.
325# (default 0)
326#POST_BUILD_DIE = 1
327
296# Way to reboot the box to the test kernel. 328# Way to reboot the box to the test kernel.
297# Only valid options so far are "grub" and "script" 329# Only valid options so far are "grub" and "script"
298# (default grub) 330# (default grub)
@@ -360,8 +392,8 @@
360#ADD_CONFIG = /home/test/config-broken 392#ADD_CONFIG = /home/test/config-broken
361 393
362# The location on the host where to write temp files 394# The location on the host where to write temp files
363# (default /tmp/ktest) 395# (default /tmp/ktest/${MACHINE})
364#TMP_DIR = /tmp/ktest 396#TMP_DIR = /tmp/ktest/${MACHINE}
365 397
366# Optional log file to write the status (recommended) 398# Optional log file to write the status (recommended)
367# Note, this is a DEFAULT section only option. 399# Note, this is a DEFAULT section only option.
@@ -518,6 +550,16 @@
518# The variables SSH_USER and MACHINE are defined. 550# The variables SSH_USER and MACHINE are defined.
519#REBOOT = ssh $SSH_USER@$MACHINE reboot 551#REBOOT = ssh $SSH_USER@$MACHINE reboot
520 552
553# The way triple faults are detected is by testing the kernel
554# banner. If the kernel banner for the kernel we are testing is
555# found, and then later a kernel banner for another kernel version
556# is found, it is considered that we encountered a triple fault,
557# and there is no panic or callback, but simply a reboot.
558# To disable this (because it did a false positive) set the following
559# to 0.
560# (default 1)
561#DETECT_TRIPLE_FAULT = 0
562
521#### Per test run options #### 563#### Per test run options ####
522# The following options are only allowed in TEST_START sections. 564# The following options are only allowed in TEST_START sections.
523# They are ignored in the DEFAULTS sections. 565# They are ignored in the DEFAULTS sections.
@@ -535,6 +577,12 @@
535# all preceding tests until a new CHECKOUT is set. 577# all preceding tests until a new CHECKOUT is set.
536# 578#
537# 579#
580# TEST_NAME = name
581#
582# If you want the test to have a name that is displayed in
583# the test result banner at the end of the test, then use this
584# option. This is useful to search for the RESULT keyword and
585# not have to translate a test number to a test in the config.
538# 586#
539# For TEST_TYPE = patchcheck 587# For TEST_TYPE = patchcheck
540# 588#
@@ -556,7 +604,12 @@
556# build, boot, test. 604# build, boot, test.
557# 605#
558# Note, the build test will look for warnings, if a warning occurred 606# Note, the build test will look for warnings, if a warning occurred
559# in a file that a commit touches, the build will fail. 607# in a file that a commit touches, the build will fail, unless
608# IGNORE_WARNINGS is set for the given commit's sha1
609#
610# IGNORE_WARNINGS can be used to disable the failure of patchcheck
611# on a particuler commit (SHA1). You can add more than one commit
612# by adding a list of SHA1s that are space delimited.
560# 613#
561# If BUILD_NOCLEAN is set, then make mrproper will not be run on 614# If BUILD_NOCLEAN is set, then make mrproper will not be run on
562# any of the builds, just like all other TEST_TYPE tests. But 615# any of the builds, just like all other TEST_TYPE tests. But
@@ -571,6 +624,7 @@
571# PATCHCHECK_TYPE = boot 624# PATCHCHECK_TYPE = boot
572# PATCHCHECK_START = 747e94ae3d1b4c9bf5380e569f614eb9040b79e7 625# PATCHCHECK_START = 747e94ae3d1b4c9bf5380e569f614eb9040b79e7
573# PATCHCHECK_END = HEAD~2 626# PATCHCHECK_END = HEAD~2
627# IGNORE_WARNINGS = 42f9c6b69b54946ffc0515f57d01dc7f5c0e4712 0c17ca2c7187f431d8ffc79e81addc730f33d128
574# 628#
575# 629#
576# 630#
@@ -739,13 +793,18 @@
739# boot - bad builds but fails to boot 793# boot - bad builds but fails to boot
740# test - bad boots but fails a test 794# test - bad boots but fails a test
741# 795#
742# CONFIG_BISECT is the config that failed to boot 796# CONFIG_BISECT is the config that failed to boot
743# 797#
744# If BISECT_MANUAL is set, it will pause between iterations. 798# If BISECT_MANUAL is set, it will pause between iterations.
745# This is useful to use just ktest.pl just for the config bisect. 799# This is useful to use just ktest.pl just for the config bisect.
746# If you set it to build, it will run the bisect and you can 800# If you set it to build, it will run the bisect and you can
747# control what happens in between iterations. It will ask you if 801# control what happens in between iterations. It will ask you if
748# the test succeeded or not and continue the config bisect. 802# the test succeeded or not and continue the config bisect.
803#
804# CONFIG_BISECT_GOOD (optional)
805# If you have a good config to start with, then you
806# can specify it with CONFIG_BISECT_GOOD. Otherwise
807# the MIN_CONFIG is the base.
749# 808#
750# Example: 809# Example:
751# TEST_START 810# TEST_START
@@ -755,3 +814,68 @@
755# MIN_CONFIG = /home/test/config-min 814# MIN_CONFIG = /home/test/config-min
756# BISECT_MANUAL = 1 815# BISECT_MANUAL = 1
757# 816#
817#
818#
819# For TEST_TYPE = make_min_config
820#
821# After doing a make localyesconfig, your kernel configuration may
822# not be the most useful minimum configuration. Having a true minimum
823# config that you can use against other configs is very useful if
824# someone else has a config that breaks on your code. By only forcing
825# those configurations that are truly required to boot your machine
826# will give you less of a chance that one of your set configurations
827# will make the bug go away. This will give you a better chance to
828# be able to reproduce the reported bug matching the broken config.
829#
830# Note, this does take some time, and may require you to run the
831# test over night, or perhaps over the weekend. But it also allows
832# you to interrupt it, and gives you the current minimum config
833# that was found till that time.
834#
835# Note, this test automatically assumes a BUILD_TYPE of oldconfig
836# and its test type acts like boot.
837# TODO: add a test version that makes the config do more than just
838# boot, like having network access.
839#
840# To save time, the test does not just grab any option and test
841# it. The Kconfig files are examined to determine the dependencies
842# of the configs. If a config is chosen that depends on another
843# config, that config will be checked first. By checking the
844# parents first, we can eliminate whole groups of configs that
845# may have been enabled.
846#
847# For example, if a USB device config is chosen and depends on CONFIG_USB,
848# the CONFIG_USB will be tested before the device. If CONFIG_USB is
849# found not to be needed, it, as well as all configs that depend on
850# it, will be disabled and removed from the current min_config.
851#
852# OUTPUT_MIN_CONFIG is the path and filename of the file that will
853# be created from the MIN_CONFIG. If you interrupt the test, set
854# this file as your new min config, and use it to continue the test.
855# This file does not need to exist on start of test.
856# This file is not created until a config is found that can be removed.
857# If this file exists, you will be prompted if you want to use it
858# as the min_config (overriding MIN_CONFIG) if START_MIN_CONFIG
859# is not defined.
860# (required field)
861#
862# START_MIN_CONFIG is the config to use to start the test with.
863# you can set this as the same OUTPUT_MIN_CONFIG, but if you do
864# the OUTPUT_MIN_CONFIG file must exist.
865# (default MIN_CONFIG)
866#
867# IGNORE_CONFIG is used to specify a config file that has configs that
868# you already know must be set. Configs are written here that have
869# been tested and proved to be required. It is best to define this
870# file if you intend on interrupting the test and running it where
871# it left off. New configs that it finds will be written to this file
872# and will not be tested again in later runs.
873# (optional)
874#
875# Example:
876#
877# TEST_TYPE = make_min_config
878# OUTPUT_MIN_CONFIG = /path/to/config-new-min
879# START_MIN_CONFIG = /path/to/config-min
880# IGNORE_CONFIG = /path/to/config-tested
881#