aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorThomas Renninger <trenn@suse.de>2012-11-27 07:17:48 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2012-11-27 17:07:20 -0500
commitc8cfc3c6bf404b0f110631d5bba234982e6ad24f (patch)
treedd6e71768799b81cca6e78fb0a26a45526a5af85 /tools
parentea1021ffa65a81da3d393fcbd7509d6e40d4d325 (diff)
cpupower: Provide -c param for cpupower monitor to schedule process on all cores
If an MSR based monitor is run in parallel this is not needed. This is the default case on all/most Intel machines. But when only sysfs info is read via cpupower monitor -m Idle_Stats (typically the case for non root users) or when other monitors are PCI based (AMD), Idle_Stats, read from sysfs can be totally bogus: cpupower monitor -m Idle_Stats PKG |CORE|CPU | POLL | C1-N | C3-N | C6-N 0| 0| 0| 0.00| 0.00| 0.24| 99.81 0| 0| 32| 0.00| 0.00| 0.00| 100.7 ... 0| 17| 20| 0.00| 0.00| 0.00| 173.1 0| 17| 52| 0.00| 0.00| 0.07| 173.0 0| 18| 68| 0.00| 0.00| 0.00| 0.00 0| 18| 76| 0.00| 0.00| 0.00| 0.00 ... With the -c option all cores are woken up and the kernel did update cpuidle statistics before reading out sysfs. This causes some overhead. Therefore avoid if possible, use if needed: cpupower monitor -c -m Idle_Stats PKG |CORE|CPU | POLL | C1-N | C3-N | C6-N 0| 0| 0| 0.00| 0.00| 0.00| 100.2 0| 0| 32| 0.00| 0.00| 0.00| 100.2 ... 0| 8| 8| 0.00| 0.00| 0.00| 99.82 0| 8| 40| 0.00| 0.00| 0.00| 99.81 0| 9| 24| 0.00| 0.00| 0.00| 100.3 0| 9| 56| 0.00| 0.00| 0.00| 100.2 0| 16| 4| 0.00| 0.00| 0.00| 99.75 0| 16| 36| 0.00| 0.00| 0.00| 99.38 ... Signed-off-by: Thomas Renninger <trenn@suse.de> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/power/cpupower/man/cpupower-monitor.115
-rw-r--r--tools/power/cpupower/utils/helpers/helpers.h1
-rw-r--r--tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c18
-rw-r--r--tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h17
4 files changed, 48 insertions, 3 deletions
diff --git a/tools/power/cpupower/man/cpupower-monitor.1 b/tools/power/cpupower/man/cpupower-monitor.1
index 1141c2073719..e01c35d13b6e 100644
--- a/tools/power/cpupower/man/cpupower-monitor.1
+++ b/tools/power/cpupower/man/cpupower-monitor.1
@@ -7,11 +7,11 @@ cpupower\-monitor \- Report processor frequency and idle statistics
7.RB "\-l" 7.RB "\-l"
8 8
9.B cpupower monitor 9.B cpupower monitor
10.RB [ "\-m <mon1>," [ "<mon2>,..." ] ] 10.RB [ -c ] [ "\-m <mon1>," [ "<mon2>,..." ] ]
11.RB [ "\-i seconds" ] 11.RB [ "\-i seconds" ]
12.br 12.br
13.B cpupower monitor 13.B cpupower monitor
14.RB [ "\-m <mon1>," [ "<mon2>,..." ] ] 14.RB [ -c ][ "\-m <mon1>," [ "<mon2>,..." ] ]
15.RB command 15.RB command
16.br 16.br
17.SH DESCRIPTION 17.SH DESCRIPTION
@@ -64,6 +64,17 @@ Only display specific monitors. Use the monitor string(s) provided by \-l option
64Measure intervall. 64Measure intervall.
65.RE 65.RE
66.PP 66.PP
67\-c
68.RS 4
69Schedule the process on every core before starting and ending measuring.
70This could be needed for the Idle_Stats monitor when no other MSR based
71monitor (has to be run on the core that is measured) is run in parallel.
72This is to wake up the processors from deeper sleep states and let the
73kernel re
74-account its cpuidle (C-state) information before reading the
75cpuidle timings from sysfs.
76.RE
77.PP
67command 78command
68.RS 4 79.RS 4
69Measure idle and frequency characteristics of an arbitrary command/workload. 80Measure idle and frequency characteristics of an arbitrary command/workload.
diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h
index f84985f630e2..aa9e95486a2d 100644
--- a/tools/power/cpupower/utils/helpers/helpers.h
+++ b/tools/power/cpupower/utils/helpers/helpers.h
@@ -114,6 +114,7 @@ struct cpupower_topology {
114 114
115extern int get_cpu_topology(struct cpupower_topology *cpu_top); 115extern int get_cpu_topology(struct cpupower_topology *cpu_top);
116extern void cpu_topology_release(struct cpupower_topology cpu_top); 116extern void cpu_topology_release(struct cpupower_topology cpu_top);
117
117/* CPU topology/hierarchy parsing ******************/ 118/* CPU topology/hierarchy parsing ******************/
118 119
119/* X86 ONLY ****************************************/ 120/* X86 ONLY ****************************************/
diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
index 7a657f3da23b..c4bae9203a69 100644
--- a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
+++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
@@ -39,6 +39,7 @@ static int mode;
39static int interval = 1; 39static int interval = 1;
40static char *show_monitors_param; 40static char *show_monitors_param;
41static struct cpupower_topology cpu_top; 41static struct cpupower_topology cpu_top;
42static unsigned int wake_cpus;
42 43
43/* ToDo: Document this in the manpage */ 44/* ToDo: Document this in the manpage */
44static char range_abbr[RANGE_MAX] = { 'T', 'C', 'P', 'M', }; 45static char range_abbr[RANGE_MAX] = { 'T', 'C', 'P', 'M', };
@@ -314,16 +315,28 @@ int fork_it(char **argv)
314int do_interval_measure(int i) 315int do_interval_measure(int i)
315{ 316{
316 unsigned int num; 317 unsigned int num;
318 int cpu;
319
320 if (wake_cpus)
321 for (cpu = 0; cpu < cpu_count; cpu++)
322 bind_cpu(cpu);
317 323
318 for (num = 0; num < avail_monitors; num++) { 324 for (num = 0; num < avail_monitors; num++) {
319 dprint("HW C-state residency monitor: %s - States: %d\n", 325 dprint("HW C-state residency monitor: %s - States: %d\n",
320 monitors[num]->name, monitors[num]->hw_states_num); 326 monitors[num]->name, monitors[num]->hw_states_num);
321 monitors[num]->start(); 327 monitors[num]->start();
322 } 328 }
329
323 sleep(i); 330 sleep(i);
331
332 if (wake_cpus)
333 for (cpu = 0; cpu < cpu_count; cpu++)
334 bind_cpu(cpu);
335
324 for (num = 0; num < avail_monitors; num++) 336 for (num = 0; num < avail_monitors; num++)
325 monitors[num]->stop(); 337 monitors[num]->stop();
326 338
339
327 return 0; 340 return 0;
328} 341}
329 342
@@ -332,7 +345,7 @@ static void cmdline(int argc, char *argv[])
332 int opt; 345 int opt;
333 progname = basename(argv[0]); 346 progname = basename(argv[0]);
334 347
335 while ((opt = getopt(argc, argv, "+li:m:")) != -1) { 348 while ((opt = getopt(argc, argv, "+lci:m:")) != -1) {
336 switch (opt) { 349 switch (opt) {
337 case 'l': 350 case 'l':
338 if (mode) 351 if (mode)
@@ -351,6 +364,9 @@ static void cmdline(int argc, char *argv[])
351 mode = show; 364 mode = show;
352 show_monitors_param = optarg; 365 show_monitors_param = optarg;
353 break; 366 break;
367 case 'c':
368 wake_cpus = 1;
369 break;
354 default: 370 default:
355 print_wrong_arg_exit(); 371 print_wrong_arg_exit();
356 } 372 }
diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h
index 9312ee1f2dbc..9e43f3371fbc 100644
--- a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h
+++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h
@@ -65,4 +65,21 @@ extern long long timespec_diff_us(struct timespec start, struct timespec end);
65 "could be inaccurate\n"), mes, ov); \ 65 "could be inaccurate\n"), mes, ov); \
66} 66}
67 67
68
69/* Taken over from x86info project sources -> return 0 on success */
70#include <sched.h>
71#include <sys/types.h>
72#include <unistd.h>
73static inline int bind_cpu(int cpu)
74{
75 cpu_set_t set;
76
77 if (sched_getaffinity(getpid(), sizeof(set), &set) == 0) {
78 CPU_ZERO(&set);
79 CPU_SET(cpu, &set);
80 return sched_setaffinity(getpid(), sizeof(set), &set);
81 }
82 return 1;
83}
84
68#endif /* __CPUIDLE_INFO_HW__ */ 85#endif /* __CPUIDLE_INFO_HW__ */