aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrarit Bhargava <prarit@redhat.com>2017-07-31 07:56:06 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-07-31 08:17:30 -0400
commitd0e4a193c33adaa4f91128d5393aa3589c2f3e9e (patch)
tree3472fd34756f598658cf5b5e58865d01f699fca4
parent2158e7244d3560fa46bdd95e70bf41dd135181dc (diff)
tools/power/cpupower: allow running without cpu0
Linux-3.7 added CONFIG_BOOTPARAM_HOTPLUG_CPU0, allowing systems to offline cpu0. But when cpu0 is offline, cpupower monitor will not display all processor and Mperf information: [root@intel-skylake-dh-03 cpupower]# ./cpupower monitor WARNING: at least one cpu is offline |Idle_Stats CPU | POLL | C1-S | C1E- | C3-S | C6-S | C7s- | C8-S 4| 0.00| 0.00| 0.00| 0.00| 0.90| 0.00| 96.13 1| 0.00| 0.00| 5.49| 0.00| 0.01| 0.00| 92.26 5| 0.00| 0.00| 0.00| 0.00| 0.46| 0.00| 99.50 2| 45.42| 0.00| 0.00| 0.00| 22.94| 0.00| 28.84 6| 0.00| 37.54| 0.00| 0.00| 0.00| 0.00| 0.00 3| 0.00| 0.00| 0.00| 0.00| 0.30| 0.00| 91.99 7| 0.00| 0.00| 0.00| 0.00| 4.70| 0.00| 0.70 This patch replaces the hard-coded use of cpu0 in cpupower with the current cpu, allowing it to run without a cpu0. After the patch is applied, [root@intel-skylake-dh-03 cpupower]# ./cpupower monitor WARNING: at least one cpu is offline |Nehalem || Mperf || Idle_Stats CPU | C3 | C6 | PC3 | PC6 || C0 | Cx | Freq || POLL | C1-S | C1E- | C3-S | C6-S | C7s- | C8-S 4| 0.01| 1.27| 0.00| 0.00|| 0.04| 99.96| 3957|| 0.00| 0.00| 0.00| 0.00| 1.43| 0.00| 98.52 1| 0.00| 98.82| 0.00| 0.00|| 0.05| 99.95| 3361|| 0.00| 0.00| 0.01| 0.00| 0.03| 0.00| 99.88 5| 0.00| 98.82| 0.00| 0.00|| 0.09| 99.91| 3917|| 0.00| 0.00| 0.00| 0.00| 99.38| 0.00| 0.50 2| 0.33| 0.00| 0.00| 0.00|| 0.00|100.00| 3890|| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00|100.00 6| 0.33| 0.00| 0.00| 0.00|| 0.01| 99.99| 3903|| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 99.99 3| 0.01| 0.71| 0.00| 0.00|| 0.06| 99.94| 3678|| 0.00| 0.00| 0.00| 0.00| 0.80| 0.00| 99.13 7| 0.01| 0.71| 0.00| 0.00|| 0.03| 99.97| 3538|| 0.00| 0.69| 11.70| 0.00| 0.00| 0.00| 87.57 There are some minor cleanups included in this patch. Signed-off-by: Prarit Bhargava <prarit@redhat.com> Signed-off-by: Thomas Renninger <trenn@suse.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--tools/power/cpupower/utils/cpupower.c15
-rw-r--r--tools/power/cpupower/utils/helpers/cpuid.c4
-rw-r--r--tools/power/cpupower/utils/helpers/helpers.h5
-rw-r--r--tools/power/cpupower/utils/helpers/misc.c2
-rw-r--r--tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c4
-rw-r--r--tools/power/cpupower/utils/idle_monitor/mperf_monitor.c3
-rw-r--r--tools/power/cpupower/utils/idle_monitor/nhm_idle.c8
-rw-r--r--tools/power/cpupower/utils/idle_monitor/snb_idle.c4
8 files changed, 28 insertions, 17 deletions
diff --git a/tools/power/cpupower/utils/cpupower.c b/tools/power/cpupower/utils/cpupower.c
index 9ea914378985..2dccf4998599 100644
--- a/tools/power/cpupower/utils/cpupower.c
+++ b/tools/power/cpupower/utils/cpupower.c
@@ -12,6 +12,7 @@
12#include <string.h> 12#include <string.h>
13#include <unistd.h> 13#include <unistd.h>
14#include <errno.h> 14#include <errno.h>
15#include <sched.h>
15#include <sys/types.h> 16#include <sys/types.h>
16#include <sys/stat.h> 17#include <sys/stat.h>
17#include <sys/utsname.h> 18#include <sys/utsname.h>
@@ -31,6 +32,7 @@ static int cmd_help(int argc, const char **argv);
31 */ 32 */
32struct cpupower_cpu_info cpupower_cpu_info; 33struct cpupower_cpu_info cpupower_cpu_info;
33int run_as_root; 34int run_as_root;
35int base_cpu;
34/* Affected cpus chosen by -c/--cpu param */ 36/* Affected cpus chosen by -c/--cpu param */
35struct bitmask *cpus_chosen; 37struct bitmask *cpus_chosen;
36 38
@@ -174,6 +176,7 @@ int main(int argc, const char *argv[])
174 unsigned int i, ret; 176 unsigned int i, ret;
175 struct stat statbuf; 177 struct stat statbuf;
176 struct utsname uts; 178 struct utsname uts;
179 char pathname[32];
177 180
178 cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF)); 181 cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
179 182
@@ -198,17 +201,23 @@ int main(int argc, const char *argv[])
198 argv[0] = cmd = "help"; 201 argv[0] = cmd = "help";
199 } 202 }
200 203
201 get_cpu_info(0, &cpupower_cpu_info); 204 base_cpu = sched_getcpu();
205 if (base_cpu < 0) {
206 fprintf(stderr, _("No valid cpus found.\n"));
207 return EXIT_FAILURE;
208 }
209
210 get_cpu_info(&cpupower_cpu_info);
202 run_as_root = !geteuid(); 211 run_as_root = !geteuid();
203 if (run_as_root) { 212 if (run_as_root) {
204 ret = uname(&uts); 213 ret = uname(&uts);
214 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
205 if (!ret && !strcmp(uts.machine, "x86_64") && 215 if (!ret && !strcmp(uts.machine, "x86_64") &&
206 stat("/dev/cpu/0/msr", &statbuf) != 0) { 216 stat(pathname, &statbuf) != 0) {
207 if (system("modprobe msr") == -1) 217 if (system("modprobe msr") == -1)
208 fprintf(stderr, _("MSR access not available.\n")); 218 fprintf(stderr, _("MSR access not available.\n"));
209 } 219 }
210 } 220 }
211
212 221
213 for (i = 0; i < ARRAY_SIZE(commands); i++) { 222 for (i = 0; i < ARRAY_SIZE(commands); i++) {
214 struct cmd_struct *p = commands + i; 223 struct cmd_struct *p = commands + i;
diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c
index 39c2c7d067bb..32d37c9be791 100644
--- a/tools/power/cpupower/utils/helpers/cpuid.c
+++ b/tools/power/cpupower/utils/helpers/cpuid.c
@@ -42,7 +42,7 @@ cpuid_func(edx);
42 * 42 *
43 * TBD: Should there be a cpuid alternative for this if /proc is not mounted? 43 * TBD: Should there be a cpuid alternative for this if /proc is not mounted?
44 */ 44 */
45int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info) 45int get_cpu_info(struct cpupower_cpu_info *cpu_info)
46{ 46{
47 FILE *fp; 47 FILE *fp;
48 char value[64]; 48 char value[64];
@@ -70,7 +70,7 @@ int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info)
70 if (!strncmp(value, "processor\t: ", 12)) 70 if (!strncmp(value, "processor\t: ", 12))
71 sscanf(value, "processor\t: %u", &proc); 71 sscanf(value, "processor\t: %u", &proc);
72 72
73 if (proc != cpu) 73 if (proc != (unsigned int)base_cpu)
74 continue; 74 continue;
75 75
76 /* Get CPU vendor */ 76 /* Get CPU vendor */
diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h
index 799a18be60aa..41da392be448 100644
--- a/tools/power/cpupower/utils/helpers/helpers.h
+++ b/tools/power/cpupower/utils/helpers/helpers.h
@@ -34,6 +34,7 @@
34/* Internationalization ****************************/ 34/* Internationalization ****************************/
35 35
36extern int run_as_root; 36extern int run_as_root;
37extern int base_cpu;
37extern struct bitmask *cpus_chosen; 38extern struct bitmask *cpus_chosen;
38 39
39/* Global verbose (-d) stuff *********************************/ 40/* Global verbose (-d) stuff *********************************/
@@ -87,11 +88,11 @@ struct cpupower_cpu_info {
87 * 88 *
88 * Extract CPU vendor, family, model, stepping info from /proc/cpuinfo 89 * Extract CPU vendor, family, model, stepping info from /proc/cpuinfo
89 * 90 *
90 * Returns 0 on success or a negativ error code 91 * Returns 0 on success or a negative error code
91 * Only used on x86, below global's struct values are zero/unknown on 92 * Only used on x86, below global's struct values are zero/unknown on
92 * other archs 93 * other archs
93 */ 94 */
94extern int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info); 95extern int get_cpu_info(struct cpupower_cpu_info *cpu_info);
95extern struct cpupower_cpu_info cpupower_cpu_info; 96extern struct cpupower_cpu_info cpupower_cpu_info;
96/* cpuid and cpuinfo helpers **************************/ 97/* cpuid and cpuinfo helpers **************************/
97 98
diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c
index 601d719d4e60..a5e7ddf19dbd 100644
--- a/tools/power/cpupower/utils/helpers/misc.c
+++ b/tools/power/cpupower/utils/helpers/misc.c
@@ -13,7 +13,7 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
13 13
14 *support = *active = *states = 0; 14 *support = *active = *states = 0;
15 15
16 ret = get_cpu_info(0, &cpu_info); 16 ret = get_cpu_info(&cpu_info);
17 if (ret) 17 if (ret)
18 return ret; 18 return ret;
19 19
diff --git a/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c b/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c
index ebeaba6571a3..f794d6bbb7e9 100644
--- a/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c
+++ b/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c
@@ -123,7 +123,7 @@ static int hsw_ext_start(void)
123 previous_count[num][cpu] = val; 123 previous_count[num][cpu] = val;
124 } 124 }
125 } 125 }
126 hsw_ext_get_count(TSC, &tsc_at_measure_start, 0); 126 hsw_ext_get_count(TSC, &tsc_at_measure_start, base_cpu);
127 return 0; 127 return 0;
128} 128}
129 129
@@ -132,7 +132,7 @@ static int hsw_ext_stop(void)
132 unsigned long long val; 132 unsigned long long val;
133 int num, cpu; 133 int num, cpu;
134 134
135 hsw_ext_get_count(TSC, &tsc_at_measure_end, 0); 135 hsw_ext_get_count(TSC, &tsc_at_measure_end, base_cpu);
136 136
137 for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) { 137 for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) {
138 for (cpu = 0; cpu < cpu_count; cpu++) { 138 for (cpu = 0; cpu < cpu_count; cpu++) {
diff --git a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
index c83f1606970b..d7c2a6d13dea 100644
--- a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
+++ b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
@@ -80,7 +80,8 @@ static int *is_valid;
80static int mperf_get_tsc(unsigned long long *tsc) 80static int mperf_get_tsc(unsigned long long *tsc)
81{ 81{
82 int ret; 82 int ret;
83 ret = read_msr(0, MSR_TSC, tsc); 83
84 ret = read_msr(base_cpu, MSR_TSC, tsc);
84 if (ret) 85 if (ret)
85 dprint("Reading TSC MSR failed, returning %llu\n", *tsc); 86 dprint("Reading TSC MSR failed, returning %llu\n", *tsc);
86 return ret; 87 return ret;
diff --git a/tools/power/cpupower/utils/idle_monitor/nhm_idle.c b/tools/power/cpupower/utils/idle_monitor/nhm_idle.c
index d2a91dd0d563..abf8cb5f7349 100644
--- a/tools/power/cpupower/utils/idle_monitor/nhm_idle.c
+++ b/tools/power/cpupower/utils/idle_monitor/nhm_idle.c
@@ -129,7 +129,7 @@ static int nhm_start(void)
129 int num, cpu; 129 int num, cpu;
130 unsigned long long dbg, val; 130 unsigned long long dbg, val;
131 131
132 nhm_get_count(TSC, &tsc_at_measure_start, 0); 132 nhm_get_count(TSC, &tsc_at_measure_start, base_cpu);
133 133
134 for (num = 0; num < NHM_CSTATE_COUNT; num++) { 134 for (num = 0; num < NHM_CSTATE_COUNT; num++) {
135 for (cpu = 0; cpu < cpu_count; cpu++) { 135 for (cpu = 0; cpu < cpu_count; cpu++) {
@@ -137,7 +137,7 @@ static int nhm_start(void)
137 previous_count[num][cpu] = val; 137 previous_count[num][cpu] = val;
138 } 138 }
139 } 139 }
140 nhm_get_count(TSC, &dbg, 0); 140 nhm_get_count(TSC, &dbg, base_cpu);
141 dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start); 141 dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start);
142 return 0; 142 return 0;
143} 143}
@@ -148,7 +148,7 @@ static int nhm_stop(void)
148 unsigned long long dbg; 148 unsigned long long dbg;
149 int num, cpu; 149 int num, cpu;
150 150
151 nhm_get_count(TSC, &tsc_at_measure_end, 0); 151 nhm_get_count(TSC, &tsc_at_measure_end, base_cpu);
152 152
153 for (num = 0; num < NHM_CSTATE_COUNT; num++) { 153 for (num = 0; num < NHM_CSTATE_COUNT; num++) {
154 for (cpu = 0; cpu < cpu_count; cpu++) { 154 for (cpu = 0; cpu < cpu_count; cpu++) {
@@ -156,7 +156,7 @@ static int nhm_stop(void)
156 current_count[num][cpu] = val; 156 current_count[num][cpu] = val;
157 } 157 }
158 } 158 }
159 nhm_get_count(TSC, &dbg, 0); 159 nhm_get_count(TSC, &dbg, base_cpu);
160 dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end); 160 dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end);
161 161
162 return 0; 162 return 0;
diff --git a/tools/power/cpupower/utils/idle_monitor/snb_idle.c b/tools/power/cpupower/utils/idle_monitor/snb_idle.c
index efc8a69c9aba..a2b45219648d 100644
--- a/tools/power/cpupower/utils/idle_monitor/snb_idle.c
+++ b/tools/power/cpupower/utils/idle_monitor/snb_idle.c
@@ -120,7 +120,7 @@ static int snb_start(void)
120 previous_count[num][cpu] = val; 120 previous_count[num][cpu] = val;
121 } 121 }
122 } 122 }
123 snb_get_count(TSC, &tsc_at_measure_start, 0); 123 snb_get_count(TSC, &tsc_at_measure_start, base_cpu);
124 return 0; 124 return 0;
125} 125}
126 126
@@ -129,7 +129,7 @@ static int snb_stop(void)
129 unsigned long long val; 129 unsigned long long val;
130 int num, cpu; 130 int num, cpu;
131 131
132 snb_get_count(TSC, &tsc_at_measure_end, 0); 132 snb_get_count(TSC, &tsc_at_measure_end, base_cpu);
133 133
134 for (num = 0; num < SNB_CSTATE_COUNT; num++) { 134 for (num = 0; num < SNB_CSTATE_COUNT; num++) {
135 for (cpu = 0; cpu < cpu_count; cpu++) { 135 for (cpu = 0; cpu < cpu_count; cpu++) {