Skip to content

Commit 748f0d7

Browse files
brsrinivshuahkh
authored andcommitted
cpupower: Provide online and offline CPU information
When a user tries to modify cpuidle or cpufreq properties on offline CPUs, the tool returns success (exit status 0) but also does not provide any warning message regarding offline cpus that may have been specified but left unchanged. In case of all or a few CPUs being offline, it can be difficult to keep track of which CPUs didn't get the new frequency or idle state set. Silent failures are difficult to keep track of when there are a huge number of CPUs on which the action is performed. This patch adds helper functions to find both online and offline CPUs and print them out accordingly. We use these helper functions in cpuidle-set and cpufreq-set to print an additional message if the user attempts to modify offline cpus. Reported-by: Pavithra R. Prakash <[email protected]> Signed-off-by: Brahadambal Srinivasan <[email protected]> Signed-off-by: Shuah Khan <[email protected]>
1 parent 3650b22 commit 748f0d7

File tree

5 files changed

+92
-1
lines changed

5 files changed

+92
-1
lines changed

tools/power/cpupower/utils/cpufreq-set.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ int cmd_freq_set(int argc, char **argv)
315315
}
316316
}
317317

318+
get_cpustate();
318319

319320
/* loop over CPUs */
320321
for (cpu = bitmask_first(cpus_chosen);
@@ -332,5 +333,7 @@ int cmd_freq_set(int argc, char **argv)
332333
}
333334
}
334335

336+
print_offline_cpus();
337+
335338
return 0;
336339
}

tools/power/cpupower/utils/cpuidle-set.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ int cmd_idle_set(int argc, char **argv)
9595
exit(EXIT_FAILURE);
9696
}
9797

98+
get_cpustate();
99+
98100
/* Default is: set all CPUs */
99101
if (bitmask_isallclear(cpus_chosen))
100102
bitmask_setall(cpus_chosen);
@@ -181,5 +183,7 @@ int cmd_idle_set(int argc, char **argv)
181183
break;
182184
}
183185
}
186+
187+
print_offline_cpus();
184188
return EXIT_SUCCESS;
185189
}

tools/power/cpupower/utils/cpupower.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ int run_as_root;
3434
int base_cpu;
3535
/* Affected cpus chosen by -c/--cpu param */
3636
struct bitmask *cpus_chosen;
37+
struct bitmask *online_cpus;
38+
struct bitmask *offline_cpus;
3739

3840
#ifdef DEBUG
3941
int be_verbose;
@@ -178,6 +180,8 @@ int main(int argc, const char *argv[])
178180
char pathname[32];
179181

180182
cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
183+
online_cpus = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
184+
offline_cpus = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
181185

182186
argc--;
183187
argv += 1;
@@ -230,6 +234,10 @@ int main(int argc, const char *argv[])
230234
ret = p->main(argc, argv);
231235
if (cpus_chosen)
232236
bitmask_free(cpus_chosen);
237+
if (online_cpus)
238+
bitmask_free(online_cpus);
239+
if (offline_cpus)
240+
bitmask_free(offline_cpus);
233241
return ret;
234242
}
235243
print_help();

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ struct cpupower_cpu_info {
9494
*/
9595
extern int get_cpu_info(struct cpupower_cpu_info *cpu_info);
9696
extern struct cpupower_cpu_info cpupower_cpu_info;
97+
98+
9799
/* cpuid and cpuinfo helpers **************************/
98100

99101
/* X86 ONLY ****************************************/
@@ -171,4 +173,14 @@ static inline unsigned int cpuid_ecx(unsigned int op) { return 0; };
171173
static inline unsigned int cpuid_edx(unsigned int op) { return 0; };
172174
#endif /* defined(__i386__) || defined(__x86_64__) */
173175

176+
/*
177+
* CPU State related functions
178+
*/
179+
extern struct bitmask *online_cpus;
180+
extern struct bitmask *offline_cpus;
181+
182+
void get_cpustate(void);
183+
void print_online_cpus(void);
184+
void print_offline_cpus(void);
185+
174186
#endif /* __CPUPOWERUTILS_HELPERS__ */

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

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
// SPDX-License-Identifier: GPL-2.0
2-
#if defined(__i386__) || defined(__x86_64__)
2+
3+
#include <stdio.h>
4+
#include <stdlib.h>
35

46
#include "helpers/helpers.h"
57

8+
#if defined(__i386__) || defined(__x86_64__)
9+
610
#define MSR_AMD_HWCR 0xc0010015
711

812
int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
@@ -41,3 +45,63 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
4145
return 0;
4246
}
4347
#endif /* #if defined(__i386__) || defined(__x86_64__) */
48+
49+
/* get_cpustate
50+
*
51+
* Gather the information of all online CPUs into bitmask struct
52+
*/
53+
void get_cpustate(void)
54+
{
55+
unsigned int cpu = 0;
56+
57+
bitmask_clearall(online_cpus);
58+
bitmask_clearall(offline_cpus);
59+
60+
for (cpu = bitmask_first(cpus_chosen);
61+
cpu <= bitmask_last(cpus_chosen); cpu++) {
62+
63+
if (cpupower_is_cpu_online(cpu) == 1)
64+
bitmask_setbit(online_cpus, cpu);
65+
else
66+
bitmask_setbit(offline_cpus, cpu);
67+
68+
continue;
69+
}
70+
}
71+
72+
/* print_online_cpus
73+
*
74+
* Print the CPU numbers of all CPUs that are online currently
75+
*/
76+
void print_online_cpus(void)
77+
{
78+
int str_len = 0;
79+
char *online_cpus_str = NULL;
80+
81+
str_len = online_cpus->size * 5;
82+
online_cpus_str = (void *)malloc(sizeof(char) * str_len);
83+
84+
if (!bitmask_isallclear(online_cpus)) {
85+
bitmask_displaylist(online_cpus_str, str_len, online_cpus);
86+
printf(_("Following CPUs are online:\n%s\n"), online_cpus_str);
87+
}
88+
}
89+
90+
/* print_offline_cpus
91+
*
92+
* Print the CPU numbers of all CPUs that are offline currently
93+
*/
94+
void print_offline_cpus(void)
95+
{
96+
int str_len = 0;
97+
char *offline_cpus_str = NULL;
98+
99+
str_len = offline_cpus->size * 5;
100+
offline_cpus_str = (void *)malloc(sizeof(char) * str_len);
101+
102+
if (!bitmask_isallclear(offline_cpus)) {
103+
bitmask_displaylist(offline_cpus_str, str_len, offline_cpus);
104+
printf(_("Following CPUs are offline:\n%s\n"), offline_cpus_str);
105+
printf(_("cpupower set operation was not performed on them\n"));
106+
}
107+
}

0 commit comments

Comments
 (0)