Commit be5378f3baabb5667508c42c56b4281f967d6861

Authored by Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/cpupowerutils

* git://git.kernel.org/pub/scm/linux/kernel/git/brodo/cpupowerutils:
  cpupower: use man(1) when calling "cpupower help subcommand"
  cpupower: make NLS truly optional
  cpupower: fix Makefile typo
  cpupower: Make monitor command -c/--cpu aware
  cpupower: Better detect offlined CPUs
  cpupower: Do not show an empty Idle_Stats monitor if no idle driver is available
  cpupower: mperf monitor - Use TSC to calculate max frequency if possible
  cpupower: avoid using symlinks

Showing 21 changed files Side-by-side Diff

tools/power/cpupower/Makefile
... ... @@ -24,7 +24,7 @@
24 24  
25 25 # Set the following to `true' to make a unstripped, unoptimized
26 26 # binary. Leave this set to `false' for production use.
27   -DEBUG ?= false
  27 +DEBUG ?= true
28 28  
29 29 # make the build silent. Set this to something else to make it noisy again.
30 30 V ?= false
... ... @@ -35,7 +35,7 @@
35 35  
36 36 # Set the following to 'true' to build/install the
37 37 # cpufreq-bench benchmarking tool
38   -CPUFRQ_BENCH ?= true
  38 +CPUFREQ_BENCH ?= true
39 39  
40 40 # Prefix to the directories we're installing to
41 41 DESTDIR ?=
42 42  
... ... @@ -137,9 +137,10 @@
137 137 ifeq ($(strip $(NLS)),true)
138 138 INSTALL_NLS += install-gmo
139 139 COMPILE_NLS += create-gmo
  140 + CFLAGS += -DNLS
140 141 endif
141 142  
142   -ifeq ($(strip $(CPUFRQ_BENCH)),true)
  143 +ifeq ($(strip $(CPUFREQ_BENCH)),true)
143 144 INSTALL_BENCH += install-bench
144 145 COMPILE_BENCH += compile-bench
145 146 endif
tools/power/cpupower/debug/x86_64/Makefile
1 1 default: all
2 2  
3   -centrino-decode: centrino-decode.c
4   - $(CC) $(CFLAGS) -o centrino-decode centrino-decode.c
  3 +centrino-decode: ../i386/centrino-decode.c
  4 + $(CC) $(CFLAGS) -o $@ $<
5 5  
6   -powernow-k8-decode: powernow-k8-decode.c
7   - $(CC) $(CFLAGS) -o powernow-k8-decode powernow-k8-decode.c
  6 +powernow-k8-decode: ../i386/powernow-k8-decode.c
  7 + $(CC) $(CFLAGS) -o $@ $<
8 8  
9 9 all: centrino-decode powernow-k8-decode
10 10  
tools/power/cpupower/debug/x86_64/centrino-decode.c
1   -../i386/centrino-decode.c
tools/power/cpupower/debug/x86_64/powernow-k8-decode.c
1   -../i386/powernow-k8-decode.c
tools/power/cpupower/man/cpupower-frequency-info.1
1   -.TH "cpufreq-info" "1" "0.1" "Mattia Dongili" ""
  1 +.TH "cpupower-frequency-info" "1" "0.1" "Mattia Dongili" ""
2 2 .SH "NAME"
3 3 .LP
4   -cpufreq\-info \- Utility to retrieve cpufreq kernel information
  4 +cpupower frequency\-info \- Utility to retrieve cpufreq kernel information
5 5 .SH "SYNTAX"
6 6 .LP
7   -cpufreq\-info [\fIoptions\fP]
  7 +cpupower [ \-c cpulist ] frequency\-info [\fIoptions\fP]
8 8 .SH "DESCRIPTION"
9 9 .LP
10 10 A small tool which prints out cpufreq information helpful to developers and interested users.
tools/power/cpupower/man/cpupower-frequency-set.1
1   -.TH "cpufreq-set" "1" "0.1" "Mattia Dongili" ""
  1 +.TH "cpupower-freqency-set" "1" "0.1" "Mattia Dongili" ""
2 2 .SH "NAME"
3 3 .LP
4   -cpufreq\-set \- A small tool which allows to modify cpufreq settings.
  4 +cpupower frequency\-set \- A small tool which allows to modify cpufreq settings.
5 5 .SH "SYNTAX"
6 6 .LP
7   -cpufreq\-set [\fIoptions\fP]
  7 +cpupower [ \-c cpu ] frequency\-set [\fIoptions\fP]
8 8 .SH "DESCRIPTION"
9 9 .LP
10   -cpufreq\-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.
  10 +cpupower frequency\-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 11 .SH "OPTIONS"
12 12 .LP
13 13 .TP
tools/power/cpupower/man/cpupower.1
... ... @@ -3,7 +3,7 @@
3 3 cpupower \- Shows and sets processor power related values
4 4 .SH SYNOPSIS
5 5 .ft B
6   -.B cpupower [ \-c cpulist ] subcommand [ARGS]
  6 +.B cpupower [ \-c cpulist ] <command> [ARGS]
7 7  
8 8 .B cpupower \-v|\-\-version
9 9  
10 10  
11 11  
12 12  
13 13  
... ... @@ -13,24 +13,24 @@
13 13 \fBcpupower \fP is a collection of tools to examine and tune power saving
14 14 related features of your processor.
15 15  
16   -The manpages of the subcommands (cpupower\-<subcommand>(1)) provide detailed
  16 +The manpages of the commands (cpupower\-<command>(1)) provide detailed
17 17 descriptions of supported features. Run \fBcpupower help\fP to get an overview
18   -of supported subcommands.
  18 +of supported commands.
19 19  
20 20 .SH Options
21 21 .PP
22 22 \-\-help, \-h
23 23 .RS 4
24   -Shows supported subcommands and general usage.
  24 +Shows supported commands and general usage.
25 25 .RE
26 26 .PP
27 27 \-\-cpu cpulist, \-c cpulist
28 28 .RS 4
29 29 Only show or set values for specific cores.
30   -This option is not supported by all subcommands, details can be found in the
31   -manpages of the subcommands.
  30 +This option is not supported by all commands, details can be found in the
  31 +manpages of the commands.
32 32  
33   -Some subcommands access all cores (typically the *\-set commands), some only
  33 +Some commands access all cores (typically the *\-set commands), some only
34 34 the first core (typically the *\-info commands) by default.
35 35  
36 36 The syntax for <cpulist> is based on how the kernel exports CPU bitmasks via
tools/power/cpupower/utils/builtin.h
... ... @@ -8,12 +8,5 @@
8 8 extern int cmd_idle_info(int argc, const char **argv);
9 9 extern int cmd_monitor(int argc, const char **argv);
10 10  
11   -extern void set_help(void);
12   -extern void info_help(void);
13   -extern void freq_set_help(void);
14   -extern void freq_info_help(void);
15   -extern void idle_info_help(void);
16   -extern void monitor_help(void);
17   -
18 11 #endif
tools/power/cpupower/utils/cpufreq-info.c
... ... @@ -510,37 +510,6 @@
510 510 return 0;
511 511 }
512 512  
513   -void 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   -
544 513 static struct option info_opts[] = {
545 514 { .name = "debug", .has_arg = no_argument, .flag = NULL, .val = 'e'},
546 515 { .name = "boost", .has_arg = no_argument, .flag = NULL, .val = 'b'},
... ... @@ -556,7 +525,6 @@
556 525 { .name = "latency", .has_arg = no_argument, .flag = NULL, .val = 'y'},
557 526 { .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'},
558 527 { .name = "human", .has_arg = no_argument, .flag = NULL, .val = 'm'},
559   - { .name = "help", .has_arg = no_argument, .flag = NULL, .val = 'h'},
560 528 { },
561 529 };
562 530  
563 531  
... ... @@ -570,16 +538,12 @@
570 538 int output_param = 0;
571 539  
572 540 do {
573   - ret = getopt_long(argc, argv, "hoefwldpgrasmyb", info_opts, NULL);
  541 + ret = getopt_long(argc, argv, "oefwldpgrasmyb", info_opts, NULL);
574 542 switch (ret) {
575 543 case '?':
576 544 output_param = '?';
577 545 cont = 0;
578 546 break;
579   - case 'h':
580   - output_param = 'h';
581   - cont = 0;
582   - break;
583 547 case -1:
584 548 cont = 0;
585 549 break;
586 550  
... ... @@ -642,11 +606,7 @@
642 606 return -EINVAL;
643 607 case '?':
644 608 printf(_("invalid or unknown argument\n"));
645   - freq_info_help();
646 609 return -EINVAL;
647   - case 'h':
648   - freq_info_help();
649   - return EXIT_SUCCESS;
650 610 case 'o':
651 611 proc_cpufreq_output();
652 612 return EXIT_SUCCESS;
tools/power/cpupower/utils/cpufreq-set.c
... ... @@ -20,34 +20,11 @@
20 20  
21 21 #define NORM_FREQ_LEN 32
22 22  
23   -void 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   -
45 23 static struct option set_opts[] = {
46 24 { .name = "min", .has_arg = required_argument, .flag = NULL, .val = 'd'},
47 25 { .name = "max", .has_arg = required_argument, .flag = NULL, .val = 'u'},
48 26 { .name = "governor", .has_arg = required_argument, .flag = NULL, .val = 'g'},
49 27 { .name = "freq", .has_arg = required_argument, .flag = NULL, .val = 'f'},
50   - { .name = "help", .has_arg = no_argument, .flag = NULL, .val = 'h'},
51 28 { .name = "related", .has_arg = no_argument, .flag = NULL, .val='r'},
52 29 { },
53 30 };
... ... @@ -80,7 +57,6 @@
80 57 static void print_unknown_arg(void)
81 58 {
82 59 printf(_("invalid or unknown argument\n"));
83   - freq_set_help();
84 60 }
85 61  
86 62 static unsigned long string_to_frequency(const char *str)
87 63  
... ... @@ -231,14 +207,11 @@
231 207  
232 208 /* parameter parsing */
233 209 do {
234   - ret = getopt_long(argc, argv, "d:u:g:f:hr", set_opts, NULL);
  210 + ret = getopt_long(argc, argv, "d:u:g:f:r", set_opts, NULL);
235 211 switch (ret) {
236 212 case '?':
237 213 print_unknown_arg();
238 214 return -EINVAL;
239   - case 'h':
240   - freq_set_help();
241   - return 0;
242 215 case -1:
243 216 cont = 0;
244 217 break;
tools/power/cpupower/utils/cpuidle-info.c
... ... @@ -139,30 +139,14 @@
139 139 }
140 140 }
141 141  
142   -/* --freq / -f */
143   -
144   -void 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   -
156 142 static struct option info_opts[] = {
157 143 { .name = "silent", .has_arg = no_argument, .flag = NULL, .val = 's'},
158 144 { .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'},
159   - { .name = "help", .has_arg = no_argument, .flag = NULL, .val = 'h'},
160 145 { },
161 146 };
162 147  
163 148 static inline void cpuidle_exit(int fail)
164 149 {
165   - idle_info_help();
166 150 exit(EXIT_FAILURE);
167 151 }
168 152  
... ... @@ -174,7 +158,7 @@
174 158 unsigned int cpu = 0;
175 159  
176 160 do {
177   - ret = getopt_long(argc, argv, "hos", info_opts, NULL);
  161 + ret = getopt_long(argc, argv, "os", info_opts, NULL);
178 162 if (ret == -1)
179 163 break;
180 164 switch (ret) {
... ... @@ -182,10 +166,6 @@
182 166 output_param = '?';
183 167 cont = 0;
184 168 break;
185   - case 'h':
186   - output_param = 'h';
187   - cont = 0;
188   - break;
189 169 case 's':
190 170 verbose = 0;
191 171 break;
... ... @@ -211,8 +191,6 @@
211 191 case '?':
212 192 printf(_("invalid or unknown argument\n"));
213 193 cpuidle_exit(EXIT_FAILURE);
214   - case 'h':
215   - cpuidle_exit(EXIT_SUCCESS);
216 194 }
217 195  
218 196 /* Default is: show output of CPU 0 only */
tools/power/cpupower/utils/cpupower-info.c
... ... @@ -16,31 +16,16 @@
16 16 #include "helpers/helpers.h"
17 17 #include "helpers/sysfs.h"
18 18  
19   -void 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   -
32 19 static struct option set_opts[] = {
33 20 { .name = "perf-bias", .has_arg = optional_argument, .flag = NULL, .val = 'b'},
34 21 { .name = "sched-mc", .has_arg = optional_argument, .flag = NULL, .val = 'm'},
35 22 { .name = "sched-smt", .has_arg = optional_argument, .flag = NULL, .val = 's'},
36   - { .name = "help", .has_arg = no_argument, .flag = NULL, .val = 'h'},
37 23 { },
38 24 };
39 25  
40 26 static void print_wrong_arg_exit(void)
41 27 {
42 28 printf(_("invalid or unknown argument\n"));
43   - info_help();
44 29 exit(EXIT_FAILURE);
45 30 }
46 31  
47 32  
... ... @@ -64,11 +49,8 @@
64 49 textdomain(PACKAGE);
65 50  
66 51 /* parameter parsing */
67   - while ((ret = getopt_long(argc, argv, "msbh", set_opts, NULL)) != -1) {
  52 + while ((ret = getopt_long(argc, argv, "msb", set_opts, NULL)) != -1) {
68 53 switch (ret) {
69   - case 'h':
70   - info_help();
71   - return 0;
72 54 case 'b':
73 55 if (params.perf_bias)
74 56 print_wrong_arg_exit();
tools/power/cpupower/utils/cpupower-set.c
... ... @@ -17,30 +17,16 @@
17 17 #include "helpers/sysfs.h"
18 18 #include "helpers/bitmask.h"
19 19  
20   -void 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   -
32 20 static struct option set_opts[] = {
33 21 { .name = "perf-bias", .has_arg = optional_argument, .flag = NULL, .val = 'b'},
34 22 { .name = "sched-mc", .has_arg = optional_argument, .flag = NULL, .val = 'm'},
35 23 { .name = "sched-smt", .has_arg = optional_argument, .flag = NULL, .val = 's'},
36   - { .name = "help", .has_arg = no_argument, .flag = NULL, .val = 'h'},
37 24 { },
38 25 };
39 26  
40 27 static void print_wrong_arg_exit(void)
41 28 {
42 29 printf(_("invalid or unknown argument\n"));
43   - set_help();
44 30 exit(EXIT_FAILURE);
45 31 }
46 32  
47 33  
... ... @@ -66,12 +52,9 @@
66 52  
67 53 params.params = 0;
68 54 /* parameter parsing */
69   - while ((ret = getopt_long(argc, argv, "m:s:b:h",
  55 + while ((ret = getopt_long(argc, argv, "m:s:b:",
70 56 set_opts, NULL)) != -1) {
71 57 switch (ret) {
72   - case 'h':
73   - set_help();
74   - return 0;
75 58 case 'b':
76 59 if (params.perf_bias)
77 60 print_wrong_arg_exit();
... ... @@ -110,10 +93,8 @@
110 93 }
111 94 };
112 95  
113   - if (!params.params) {
114   - set_help();
115   - return -EINVAL;
116   - }
  96 + if (!params.params)
  97 + print_wrong_arg_exit();
117 98  
118 99 if (params.sched_mc) {
119 100 ret = sysfs_set_sched("mc", sched_mc);
tools/power/cpupower/utils/cpupower.c
... ... @@ -11,6 +11,7 @@
11 11 #include <stdlib.h>
12 12 #include <string.h>
13 13 #include <unistd.h>
  14 +#include <errno.h>
14 15  
15 16 #include "builtin.h"
16 17 #include "helpers/helpers.h"
17 18  
... ... @@ -19,13 +20,12 @@
19 20 struct cmd_struct {
20 21 const char *cmd;
21 22 int (*main)(int, const char **);
22   - void (*usage)(void);
23 23 int needs_root;
24 24 };
25 25  
26 26 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
27 27  
28   -int cmd_help(int argc, const char **argv);
  28 +static int cmd_help(int argc, const char **argv);
29 29  
30 30 /* Global cpu_info object available for all binaries
31 31 * Info only retrieved from CPU 0
32 32  
33 33  
34 34  
35 35  
36 36  
... ... @@ -44,55 +44,66 @@
44 44 static void print_help(void);
45 45  
46 46 static 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 }, */
  47 + { "frequency-info", cmd_freq_info, 0 },
  48 + { "frequency-set", cmd_freq_set, 1 },
  49 + { "idle-info", cmd_idle_info, 0 },
  50 + { "set", cmd_set, 1 },
  51 + { "info", cmd_info, 0 },
  52 + { "monitor", cmd_monitor, 0 },
  53 + { "help", cmd_help, 0 },
  54 + /* { "bench", cmd_bench, 1 }, */
55 55 };
56 56  
57   -int 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   -
78 57 static void print_help(void)
79 58 {
80 59 unsigned int i;
81 60  
82 61 #ifdef DEBUG
83   - printf(_("cpupower [ -d ][ -c cpulist ] subcommand [ARGS]\n"));
84   - printf(_(" -d, --debug May increase output (stderr) on some subcommands\n"));
  62 + printf(_("Usage:\tcpupower [-d|--debug] [-c|--cpu cpulist ] <command> [<args>]\n"));
85 63 #else
86   - printf(_("cpupower [ -c cpulist ] subcommand [ARGS]\n"));
  64 + printf(_("Usage:\tcpupower [-c|--cpu cpulist ] <command> [<args>]\n"));
87 65 #endif
88   - printf(_("cpupower --version\n"));
89   - printf(_("Supported subcommands are:\n"));
  66 + printf(_("Supported commands are:\n"));
90 67 for (i = 0; i < ARRAY_SIZE(commands); i++)
91 68 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"));
  69 + printf(_("\nNot all commands can make use of the -c cpulist option.\n"));
  70 + printf(_("\nUse 'cpupower help <command>' for getting help for above commands.\n"));
  71 +}
  72 +
  73 +static int print_man_page(const char *subpage)
  74 +{
  75 + int len;
  76 + char *page;
  77 +
  78 + len = 10; /* enough for "cpupower-" */
  79 + if (subpage != NULL)
  80 + len += strlen(subpage);
  81 +
  82 + page = malloc(len);
  83 + if (!page)
  84 + return -ENOMEM;
  85 +
  86 + sprintf(page, "cpupower");
  87 + if ((subpage != NULL) && strcmp(subpage, "help")) {
  88 + strcat(page, "-");
  89 + strcat(page, subpage);
  90 + }
  91 +
  92 + execlp("man", "man", page, NULL);
  93 +
  94 + /* should not be reached */
  95 + return -EINVAL;
  96 +}
  97 +
  98 +static int cmd_help(int argc, const char **argv)
  99 +{
  100 + if (argc > 1) {
  101 + print_man_page(argv[1]); /* exits within execlp() */
  102 + return EXIT_FAILURE;
  103 + }
  104 +
  105 + print_help();
  106 + return EXIT_SUCCESS;
96 107 }
97 108  
98 109 static void print_version(void)
tools/power/cpupower/utils/helpers/helpers.h
... ... @@ -16,11 +16,20 @@
16 16 #include "helpers/bitmask.h"
17 17  
18 18 /* Internationalization ****************************/
  19 +#ifdef NLS
  20 +
19 21 #define _(String) gettext(String)
20 22 #ifndef gettext_noop
21 23 #define gettext_noop(String) String
22 24 #endif
23 25 #define N_(String) gettext_noop(String)
  26 +
  27 +#else /* !NLS */
  28 +
  29 +#define _(String) String
  30 +#define N_(String) String
  31 +
  32 +#endif
24 33 /* Internationalization ****************************/
25 34  
26 35 extern int run_as_root;
... ... @@ -96,6 +105,9 @@
96 105 int pkg;
97 106 int core;
98 107 int cpu;
  108 +
  109 + /* flags */
  110 + unsigned int is_online:1;
99 111 } *core_info;
100 112 };
101 113  
tools/power/cpupower/utils/helpers/sysfs.c
... ... @@ -56,6 +56,56 @@
56 56 return (unsigned int) numwrite;
57 57 }
58 58  
  59 +/*
  60 + * Detect whether a CPU is online
  61 + *
  62 + * Returns:
  63 + * 1 -> if CPU is online
  64 + * 0 -> if CPU is offline
  65 + * negative errno values in error case
  66 + */
  67 +int sysfs_is_cpu_online(unsigned int cpu)
  68 +{
  69 + char path[SYSFS_PATH_MAX];
  70 + int fd;
  71 + ssize_t numread;
  72 + unsigned long long value;
  73 + char linebuf[MAX_LINE_LEN];
  74 + char *endp;
  75 + struct stat statbuf;
  76 +
  77 + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u", cpu);
  78 +
  79 + if (stat(path, &statbuf) != 0)
  80 + return 0;
  81 +
  82 + /*
  83 + * kernel without CONFIG_HOTPLUG_CPU
  84 + * -> cpuX directory exists, but not cpuX/online file
  85 + */
  86 + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/online", cpu);
  87 + if (stat(path, &statbuf) != 0)
  88 + return 1;
  89 +
  90 + fd = open(path, O_RDONLY);
  91 + if (fd == -1)
  92 + return -errno;
  93 +
  94 + numread = read(fd, linebuf, MAX_LINE_LEN - 1);
  95 + if (numread < 1) {
  96 + close(fd);
  97 + return -EIO;
  98 + }
  99 + linebuf[numread] = '\0';
  100 + close(fd);
  101 +
  102 + value = strtoull(linebuf, &endp, 0);
  103 + if (value > 1 || value < 0)
  104 + return -EINVAL;
  105 +
  106 + return value;
  107 +}
  108 +
59 109 /* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */
60 110  
61 111 /*
tools/power/cpupower/utils/helpers/sysfs.h
... ... @@ -7,6 +7,8 @@
7 7  
8 8 extern unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen);
9 9  
  10 +extern int sysfs_is_cpu_online(unsigned int cpu);
  11 +
10 12 extern unsigned long sysfs_get_idlestate_latency(unsigned int cpu,
11 13 unsigned int idlestate);
12 14 extern unsigned long sysfs_get_idlestate_usage(unsigned int cpu,
tools/power/cpupower/utils/helpers/topology.c
... ... @@ -41,6 +41,8 @@
41 41 unsigned int pkg;
42 42 unsigned int thread;
43 43 unsigned int cpu;
  44 + /* flags */
  45 + unsigned int is_online:1;
44 46 };
45 47  
46 48 static int __compare(const void *t1, const void *t2)
... ... @@ -78,6 +80,8 @@
78 80 return -ENOMEM;
79 81 cpu_top->pkgs = cpu_top->cores = 0;
80 82 for (cpu = 0; cpu < cpus; cpu++) {
  83 + cpu_top->core_info[cpu].cpu = cpu;
  84 + cpu_top->core_info[cpu].is_online = sysfs_is_cpu_online(cpu);
81 85 cpu_top->core_info[cpu].pkg =
82 86 sysfs_topology_read_file(cpu, "physical_package_id");
83 87 if ((int)cpu_top->core_info[cpu].pkg != -1 &&
... ... @@ -85,7 +89,6 @@
85 89 cpu_top->pkgs = cpu_top->core_info[cpu].pkg;
86 90 cpu_top->core_info[cpu].core =
87 91 sysfs_topology_read_file(cpu, "core_id");
88   - cpu_top->core_info[cpu].cpu = cpu;
89 92 }
90 93 cpu_top->pkgs++;
91 94  
tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c
... ... @@ -134,7 +134,7 @@
134 134 /* Assume idle state count is the same for all CPUs */
135 135 cpuidle_sysfs_monitor.hw_states_num = sysfs_get_idlestate_count(0);
136 136  
137   - if (cpuidle_sysfs_monitor.hw_states_num == 0)
  137 + if (cpuidle_sysfs_monitor.hw_states_num <= 0)
138 138 return NULL;
139 139  
140 140 for (num = 0; num < cpuidle_sysfs_monitor.hw_states_num; num++) {
tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
... ... @@ -43,6 +43,12 @@
43 43 /* ToDo: Document this in the manpage */
44 44 static char range_abbr[RANGE_MAX] = { 'T', 'C', 'P', 'M', };
45 45  
  46 +static void print_wrong_arg_exit(void)
  47 +{
  48 + printf(_("invalid or unknown argument\n"));
  49 + exit(EXIT_FAILURE);
  50 +}
  51 +
46 52 long long timespec_diff_us(struct timespec start, struct timespec end)
47 53 {
48 54 struct timespec temp;
... ... @@ -56,21 +62,6 @@
56 62 return (temp.tv_sec * 1000000) + (temp.tv_nsec / 1000);
57 63 }
58 64  
59   -void 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   -
74 65 void print_n_spaces(int n)
75 66 {
76 67 int x;
... ... @@ -149,6 +140,10 @@
149 140 unsigned long long result;
150 141 cstate_t s;
151 142  
  143 + /* Be careful CPUs may got resorted for pkg value do not just use cpu */
  144 + if (!bitmask_isbitset(cpus_chosen, cpu_top.core_info[cpu].cpu))
  145 + return;
  146 +
152 147 if (topology_depth > 2)
153 148 printf("%4d|", cpu_top.core_info[cpu].pkg);
154 149 if (topology_depth > 1)
... ... @@ -190,9 +185,13 @@
190 185 }
191 186 }
192 187 }
193   - /* cpu offline */
194   - if (cpu_top.core_info[cpu].pkg == -1 ||
195   - cpu_top.core_info[cpu].core == -1) {
  188 + /*
  189 + * The monitor could still provide useful data, for example
  190 + * AMD HW counters partly sit in PCI config space.
  191 + * It's up to the monitor plug-in to check .is_online, this one
  192 + * is just for additional info.
  193 + */
  194 + if (!cpu_top.core_info[cpu].is_online) {
196 195 printf(_(" *is offline\n"));
197 196 return;
198 197 } else
... ... @@ -238,7 +237,6 @@
238 237 if (hits == 0) {
239 238 printf(_("No matching monitor found in %s, "
240 239 "try -l option\n"), param);
241   - monitor_help();
242 240 exit(EXIT_FAILURE);
243 241 }
244 242 /* Override detected/registerd monitors array with requested one */
245 243  
246 244  
247 245  
248 246  
249 247  
... ... @@ -335,37 +333,27 @@
335 333 int opt;
336 334 progname = basename(argv[0]);
337 335  
338   - while ((opt = getopt(argc, argv, "+hli:m:")) != -1) {
  336 + while ((opt = getopt(argc, argv, "+li:m:")) != -1) {
339 337 switch (opt) {
340   - case 'h':
341   - monitor_help();
342   - exit(EXIT_SUCCESS);
343 338 case 'l':
344   - if (mode) {
345   - monitor_help();
346   - exit(EXIT_FAILURE);
347   - }
  339 + if (mode)
  340 + print_wrong_arg_exit();
348 341 mode = list;
349 342 break;
350 343 case 'i':
351 344 /* only allow -i with -m or no option */
352   - if (mode && mode != show) {
353   - monitor_help();
354   - exit(EXIT_FAILURE);
355   - }
  345 + if (mode && mode != show)
  346 + print_wrong_arg_exit();
356 347 interval = atoi(optarg);
357 348 break;
358 349 case 'm':
359   - if (mode) {
360   - monitor_help();
361   - exit(EXIT_FAILURE);
362   - }
  350 + if (mode)
  351 + print_wrong_arg_exit();
363 352 mode = show;
364 353 show_monitors_param = optarg;
365 354 break;
366 355 default:
367   - monitor_help();
368   - exit(EXIT_FAILURE);
  356 + print_wrong_arg_exit();
369 357 }
370 358 }
371 359 if (!mode)
... ... @@ -384,6 +372,10 @@
384 372 printf(_("Cannot read number of available processors\n"));
385 373 return EXIT_FAILURE;
386 374 }
  375 +
  376 + /* Default is: monitor all CPUs */
  377 + if (bitmask_isallclear(cpus_chosen))
  378 + bitmask_setall(cpus_chosen);
387 379  
388 380 dprint("System has up to %d CPU cores\n", cpu_count);
389 381  
tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
... ... @@ -22,12 +22,15 @@
22 22  
23 23 #define MSR_TSC 0x10
24 24  
  25 +#define MSR_AMD_HWCR 0xc0010015
  26 +
25 27 enum mperf_id { C0 = 0, Cx, AVG_FREQ, MPERF_CSTATE_COUNT };
26 28  
27 29 static int mperf_get_count_percent(unsigned int self_id, double *percent,
28 30 unsigned int cpu);
29 31 static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
30 32 unsigned int cpu);
  33 +static struct timespec time_start, time_end;
31 34  
32 35 static cstate_t mperf_cstates[MPERF_CSTATE_COUNT] = {
33 36 {
34 37  
35 38  
36 39  
... ... @@ -54,19 +57,33 @@
54 57 },
55 58 };
56 59  
  60 +enum MAX_FREQ_MODE { MAX_FREQ_SYSFS, MAX_FREQ_TSC_REF };
  61 +static int max_freq_mode;
  62 +/*
  63 + * The max frequency mperf is ticking at (in C0), either retrieved via:
  64 + * 1) calculated after measurements if we know TSC ticks at mperf/P0 frequency
  65 + * 2) cpufreq /sys/devices/.../cpu0/cpufreq/cpuinfo_max_freq at init time
  66 + * 1. Is preferred as it also works without cpufreq subsystem (e.g. on Xen)
  67 + */
  68 +static unsigned long max_frequency;
  69 +
57 70 static unsigned long long tsc_at_measure_start;
58 71 static unsigned long long tsc_at_measure_end;
59   -static unsigned long max_frequency;
60 72 static unsigned long long *mperf_previous_count;
61 73 static unsigned long long *aperf_previous_count;
62 74 static unsigned long long *mperf_current_count;
63 75 static unsigned long long *aperf_current_count;
  76 +
64 77 /* valid flag for all CPUs. If a MSR read failed it will be zero */
65 78 static int *is_valid;
66 79  
67 80 static int mperf_get_tsc(unsigned long long *tsc)
68 81 {
69   - return read_msr(0, MSR_TSC, tsc);
  82 + int ret;
  83 + ret = read_msr(0, MSR_TSC, tsc);
  84 + if (ret)
  85 + dprint("Reading TSC MSR failed, returning %llu\n", *tsc);
  86 + return ret;
70 87 }
71 88  
72 89 static int mperf_init_stats(unsigned int cpu)
73 90  
... ... @@ -97,36 +114,11 @@
97 114 return 0;
98 115 }
99 116  
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   - */
113   -static 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   -
126 117 static int mperf_get_count_percent(unsigned int id, double *percent,
127 118 unsigned int cpu)
128 119 {
129 120 unsigned long long aperf_diff, mperf_diff, tsc_diff;
  121 + unsigned long long timediff;
130 122  
131 123 if (!is_valid[cpu])
132 124 return -1;
133 125  
... ... @@ -136,11 +128,19 @@
136 128  
137 129 mperf_diff = mperf_current_count[cpu] - mperf_previous_count[cpu];
138 130 aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];
139   - tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
140 131  
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);
  132 + if (max_freq_mode == MAX_FREQ_TSC_REF) {
  133 + tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
  134 + *percent = 100.0 * mperf_diff / tsc_diff;
  135 + dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n",
  136 + mperf_cstates[id].name, mperf_diff, tsc_diff);
  137 + } else if (max_freq_mode == MAX_FREQ_SYSFS) {
  138 + timediff = timespec_diff_us(time_start, time_end);
  139 + *percent = 100.0 * mperf_diff / timediff;
  140 + dprint("%s: MAXFREQ - mperf_diff: %llu, time_diff: %llu\n",
  141 + mperf_cstates[id].name, mperf_diff, timediff);
  142 + } else
  143 + return -1;
144 144  
145 145 if (id == Cx)
146 146 *percent = 100.0 - *percent;
... ... @@ -154,7 +154,7 @@
154 154 static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
155 155 unsigned int cpu)
156 156 {
157   - unsigned long long aperf_diff, mperf_diff;
  157 + unsigned long long aperf_diff, mperf_diff, time_diff, tsc_diff;
158 158  
159 159 if (id != AVG_FREQ)
160 160 return 1;
161 161  
... ... @@ -165,11 +165,21 @@
165 165 mperf_diff = mperf_current_count[cpu] - mperf_previous_count[cpu];
166 166 aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];
167 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);
  168 + if (max_freq_mode == MAX_FREQ_TSC_REF) {
  169 + /* Calculate max_freq from TSC count */
  170 + tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
  171 + time_diff = timespec_diff_us(time_start, time_end);
  172 + max_frequency = tsc_diff / time_diff;
  173 + }
172 174  
  175 + *count = max_frequency * ((double)aperf_diff / mperf_diff);
  176 + dprint("%s: Average freq based on %s maximum frequency:\n",
  177 + mperf_cstates[id].name,
  178 + (max_freq_mode == MAX_FREQ_TSC_REF) ? "TSC calculated" : "sysfs read");
  179 + dprint("%max_frequency: %lu", max_frequency);
  180 + dprint("aperf_diff: %llu\n", aperf_diff);
  181 + dprint("mperf_diff: %llu\n", mperf_diff);
  182 + dprint("avg freq: %llu\n", *count);
173 183 return 0;
174 184 }
175 185  
... ... @@ -178,6 +188,7 @@
178 188 int cpu;
179 189 unsigned long long dbg;
180 190  
  191 + clock_gettime(CLOCK_REALTIME, &time_start);
181 192 mperf_get_tsc(&tsc_at_measure_start);
182 193  
183 194 for (cpu = 0; cpu < cpu_count; cpu++)
184 195  
185 196  
186 197  
187 198  
188 199  
189 200  
190 201  
... ... @@ -193,32 +204,104 @@
193 204 unsigned long long dbg;
194 205 int cpu;
195 206  
196   - mperf_get_tsc(&tsc_at_measure_end);
197   -
198 207 for (cpu = 0; cpu < cpu_count; cpu++)
199 208 mperf_measure_stats(cpu);
200 209  
  210 + mperf_get_tsc(&tsc_at_measure_end);
  211 + clock_gettime(CLOCK_REALTIME, &time_end);
  212 +
201 213 mperf_get_tsc(&dbg);
202 214 dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end);
203 215  
204 216 return 0;
205 217 }
206 218  
207   -struct cpuidle_monitor mperf_monitor;
208   -
209   -struct cpuidle_monitor *mperf_register(void)
  219 +/*
  220 + * Mperf register is defined to tick at P0 (maximum) frequency
  221 + *
  222 + * Instead of reading out P0 which can be tricky to read out from HW,
  223 + * we use TSC counter if it reliably ticks at P0/mperf frequency.
  224 + *
  225 + * Still try to fall back to:
  226 + * /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq
  227 + * on older Intel HW without invariant TSC feature.
  228 + * Or on AMD machines where TSC does not tick at P0 (do not exist yet, but
  229 + * it's still double checked (MSR_AMD_HWCR)).
  230 + *
  231 + * On these machines the user would still get useful mperf
  232 + * stats when acpi-cpufreq driver is loaded.
  233 + */
  234 +static int init_maxfreq_mode(void)
210 235 {
  236 + int ret;
  237 + unsigned long long hwcr;
211 238 unsigned long min;
212 239  
213   - if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF))
214   - return NULL;
  240 + if (!cpupower_cpu_info.caps & CPUPOWER_CAP_INV_TSC)
  241 + goto use_sysfs;
215 242  
216   - /* Assume min/max all the same on all cores */
  243 + if (cpupower_cpu_info.vendor == X86_VENDOR_AMD) {
  244 + /* MSR_AMD_HWCR tells us whether TSC runs at P0/mperf
  245 + * freq.
  246 + * A test whether hwcr is accessable/available would be:
  247 + * (cpupower_cpu_info.family > 0x10 ||
  248 + * cpupower_cpu_info.family == 0x10 &&
  249 + * cpupower_cpu_info.model >= 0x2))
  250 + * This should be the case for all aperf/mperf
  251 + * capable AMD machines and is therefore safe to test here.
  252 + * Compare with Linus kernel git commit: acf01734b1747b1ec4
  253 + */
  254 + ret = read_msr(0, MSR_AMD_HWCR, &hwcr);
  255 + /*
  256 + * If the MSR read failed, assume a Xen system that did
  257 + * not explicitly provide access to it and assume TSC works
  258 + */
  259 + if (ret != 0) {
  260 + dprint("TSC read 0x%x failed - assume TSC working\n",
  261 + MSR_AMD_HWCR);
  262 + return 0;
  263 + } else if (1 & (hwcr >> 24)) {
  264 + max_freq_mode = MAX_FREQ_TSC_REF;
  265 + return 0;
  266 + } else { /* Use sysfs max frequency if available */ }
  267 + } else if (cpupower_cpu_info.vendor == X86_VENDOR_INTEL) {
  268 + /*
  269 + * On Intel we assume mperf (in C0) is ticking at same
  270 + * rate than TSC
  271 + */
  272 + max_freq_mode = MAX_FREQ_TSC_REF;
  273 + return 0;
  274 + }
  275 +use_sysfs:
217 276 if (cpufreq_get_hardware_limits(0, &min, &max_frequency)) {
218 277 dprint("Cannot retrieve max freq from cpufreq kernel "
219 278 "subsystem\n");
220   - return NULL;
  279 + return -1;
221 280 }
  281 + max_freq_mode = MAX_FREQ_SYSFS;
  282 + return 0;
  283 +}
  284 +
  285 +/*
  286 + * This monitor provides:
  287 + *
  288 + * 1) Average frequency a CPU resided in
  289 + * This always works if the CPU has aperf/mperf capabilities
  290 + *
  291 + * 2) C0 and Cx (any sleep state) time a CPU resided in
  292 + * Works if mperf timer stops ticking in sleep states which
  293 + * seem to be the case on all current HW.
  294 + * Both is directly retrieved from HW registers and is independent
  295 + * from kernel statistics.
  296 + */
  297 +struct cpuidle_monitor mperf_monitor;
  298 +struct cpuidle_monitor *mperf_register(void)
  299 +{
  300 + if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF))
  301 + return NULL;
  302 +
  303 + if (init_maxfreq_mode())
  304 + return NULL;
222 305  
223 306 /* Free this at program termination */
224 307 is_valid = calloc(cpu_count, sizeof(int));