Skip to content

Commit d0e4a19

Browse files
praritrafaeljw
authored andcommitted
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 <[email protected]> Signed-off-by: Thomas Renninger <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 2158e72 commit d0e4a19

File tree

8 files changed

+28
-17
lines changed

8 files changed

+28
-17
lines changed

tools/power/cpupower/utils/cpupower.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <string.h>
1313
#include <unistd.h>
1414
#include <errno.h>
15+
#include <sched.h>
1516
#include <sys/types.h>
1617
#include <sys/stat.h>
1718
#include <sys/utsname.h>
@@ -31,6 +32,7 @@ static int cmd_help(int argc, const char **argv);
3132
*/
3233
struct cpupower_cpu_info cpupower_cpu_info;
3334
int run_as_root;
35+
int base_cpu;
3436
/* Affected cpus chosen by -c/--cpu param */
3537
struct bitmask *cpus_chosen;
3638

@@ -174,6 +176,7 @@ int main(int argc, const char *argv[])
174176
unsigned int i, ret;
175177
struct stat statbuf;
176178
struct utsname uts;
179+
char pathname[32];
177180

178181
cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
179182

@@ -198,17 +201,23 @@ int main(int argc, const char *argv[])
198201
argv[0] = cmd = "help";
199202
}
200203

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);
202211
run_as_root = !geteuid();
203212
if (run_as_root) {
204213
ret = uname(&uts);
214+
sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
205215
if (!ret && !strcmp(uts.machine, "x86_64") &&
206-
stat("/dev/cpu/0/msr", &statbuf) != 0) {
216+
stat(pathname, &statbuf) != 0) {
207217
if (system("modprobe msr") == -1)
208218
fprintf(stderr, _("MSR access not available.\n"));
209219
}
210220
}
211-
212221

213222
for (i = 0; i < ARRAY_SIZE(commands); i++) {
214223
struct cmd_struct *p = commands + i;

tools/power/cpupower/utils/helpers/cpuid.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ cpuid_func(edx);
4242
*
4343
* TBD: Should there be a cpuid alternative for this if /proc is not mounted?
4444
*/
45-
int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info)
45+
int get_cpu_info(struct cpupower_cpu_info *cpu_info)
4646
{
4747
FILE *fp;
4848
char value[64];
@@ -70,7 +70,7 @@ int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info)
7070
if (!strncmp(value, "processor\t: ", 12))
7171
sscanf(value, "processor\t: %u", &proc);
7272

73-
if (proc != cpu)
73+
if (proc != (unsigned int)base_cpu)
7474
continue;
7575

7676
/* Get CPU vendor */

tools/power/cpupower/utils/helpers/helpers.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
/* Internationalization ****************************/
3535

3636
extern int run_as_root;
37+
extern int base_cpu;
3738
extern struct bitmask *cpus_chosen;
3839

3940
/* Global verbose (-d) stuff *********************************/
@@ -87,11 +88,11 @@ struct cpupower_cpu_info {
8788
*
8889
* Extract CPU vendor, family, model, stepping info from /proc/cpuinfo
8990
*
90-
* Returns 0 on success or a negativ error code
91+
* Returns 0 on success or a negative error code
9192
* Only used on x86, below global's struct values are zero/unknown on
9293
* other archs
9394
*/
94-
extern int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info);
95+
extern int get_cpu_info(struct cpupower_cpu_info *cpu_info);
9596
extern struct cpupower_cpu_info cpupower_cpu_info;
9697
/* cpuid and cpuinfo helpers **************************/
9798

tools/power/cpupower/utils/helpers/misc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
1313

1414
*support = *active = *states = 0;
1515

16-
ret = get_cpu_info(0, &cpu_info);
16+
ret = get_cpu_info(&cpu_info);
1717
if (ret)
1818
return ret;
1919

tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ static int hsw_ext_start(void)
123123
previous_count[num][cpu] = val;
124124
}
125125
}
126-
hsw_ext_get_count(TSC, &tsc_at_measure_start, 0);
126+
hsw_ext_get_count(TSC, &tsc_at_measure_start, base_cpu);
127127
return 0;
128128
}
129129

@@ -132,7 +132,7 @@ static int hsw_ext_stop(void)
132132
unsigned long long val;
133133
int num, cpu;
134134

135-
hsw_ext_get_count(TSC, &tsc_at_measure_end, 0);
135+
hsw_ext_get_count(TSC, &tsc_at_measure_end, base_cpu);
136136

137137
for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) {
138138
for (cpu = 0; cpu < cpu_count; cpu++) {

tools/power/cpupower/utils/idle_monitor/mperf_monitor.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ static int *is_valid;
8080
static int mperf_get_tsc(unsigned long long *tsc)
8181
{
8282
int ret;
83-
ret = read_msr(0, MSR_TSC, tsc);
83+
84+
ret = read_msr(base_cpu, MSR_TSC, tsc);
8485
if (ret)
8586
dprint("Reading TSC MSR failed, returning %llu\n", *tsc);
8687
return ret;

tools/power/cpupower/utils/idle_monitor/nhm_idle.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,15 @@ static int nhm_start(void)
129129
int num, cpu;
130130
unsigned long long dbg, val;
131131

132-
nhm_get_count(TSC, &tsc_at_measure_start, 0);
132+
nhm_get_count(TSC, &tsc_at_measure_start, base_cpu);
133133

134134
for (num = 0; num < NHM_CSTATE_COUNT; num++) {
135135
for (cpu = 0; cpu < cpu_count; cpu++) {
136136
is_valid[cpu] = !nhm_get_count(num, &val, cpu);
137137
previous_count[num][cpu] = val;
138138
}
139139
}
140-
nhm_get_count(TSC, &dbg, 0);
140+
nhm_get_count(TSC, &dbg, base_cpu);
141141
dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start);
142142
return 0;
143143
}
@@ -148,15 +148,15 @@ static int nhm_stop(void)
148148
unsigned long long dbg;
149149
int num, cpu;
150150

151-
nhm_get_count(TSC, &tsc_at_measure_end, 0);
151+
nhm_get_count(TSC, &tsc_at_measure_end, base_cpu);
152152

153153
for (num = 0; num < NHM_CSTATE_COUNT; num++) {
154154
for (cpu = 0; cpu < cpu_count; cpu++) {
155155
is_valid[cpu] = !nhm_get_count(num, &val, cpu);
156156
current_count[num][cpu] = val;
157157
}
158158
}
159-
nhm_get_count(TSC, &dbg, 0);
159+
nhm_get_count(TSC, &dbg, base_cpu);
160160
dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end);
161161

162162
return 0;

tools/power/cpupower/utils/idle_monitor/snb_idle.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ static int snb_start(void)
120120
previous_count[num][cpu] = val;
121121
}
122122
}
123-
snb_get_count(TSC, &tsc_at_measure_start, 0);
123+
snb_get_count(TSC, &tsc_at_measure_start, base_cpu);
124124
return 0;
125125
}
126126

@@ -129,7 +129,7 @@ static int snb_stop(void)
129129
unsigned long long val;
130130
int num, cpu;
131131

132-
snb_get_count(TSC, &tsc_at_measure_end, 0);
132+
snb_get_count(TSC, &tsc_at_measure_end, base_cpu);
133133

134134
for (num = 0; num < SNB_CSTATE_COUNT; num++) {
135135
for (cpu = 0; cpu < cpu_count; cpu++) {

0 commit comments

Comments
 (0)