Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/power/cpupower/utils/cpuidle-info.c
26292 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* (C) 2004-2009 Dominik Brodowski <[email protected]>
4
* (C) 2010 Thomas Renninger <[email protected]>
5
*/
6
7
8
#include <unistd.h>
9
#include <stdio.h>
10
#include <errno.h>
11
#include <stdlib.h>
12
#include <string.h>
13
#include <getopt.h>
14
15
#include <cpuidle.h>
16
17
#include "helpers/sysfs.h"
18
#include "helpers/helpers.h"
19
#include "helpers/bitmask.h"
20
21
#define LINE_LEN 10
22
23
static void cpuidle_cpu_output(unsigned int cpu, int verbose)
24
{
25
unsigned int idlestates, idlestate;
26
char *tmp;
27
28
idlestates = cpuidle_state_count(cpu);
29
if (idlestates == 0) {
30
printf(_("CPU %u: No idle states\n"), cpu);
31
return;
32
}
33
34
printf(_("Number of idle states: %d\n"), idlestates);
35
printf(_("Available idle states:"));
36
for (idlestate = 0; idlestate < idlestates; idlestate++) {
37
tmp = cpuidle_state_name(cpu, idlestate);
38
if (!tmp)
39
continue;
40
printf(" %s", tmp);
41
free(tmp);
42
}
43
printf("\n");
44
45
if (!verbose)
46
return;
47
48
for (idlestate = 0; idlestate < idlestates; idlestate++) {
49
int disabled = cpuidle_is_state_disabled(cpu, idlestate);
50
/* Disabled interface not supported on older kernels */
51
if (disabled < 0)
52
disabled = 0;
53
tmp = cpuidle_state_name(cpu, idlestate);
54
if (!tmp)
55
continue;
56
printf("%s%s:\n", tmp, (disabled) ? " (DISABLED) " : "");
57
free(tmp);
58
59
tmp = cpuidle_state_desc(cpu, idlestate);
60
if (!tmp)
61
continue;
62
printf(_("Flags/Description: %s\n"), tmp);
63
free(tmp);
64
65
printf(_("Latency: %lu\n"),
66
cpuidle_state_latency(cpu, idlestate));
67
printf(_("Residency: %lu\n"),
68
cpuidle_state_residency(cpu, idlestate));
69
printf(_("Usage: %lu\n"),
70
cpuidle_state_usage(cpu, idlestate));
71
printf(_("Duration: %llu\n"),
72
cpuidle_state_time(cpu, idlestate));
73
}
74
}
75
76
static void cpuidle_general_output(void)
77
{
78
char *tmp;
79
80
tmp = cpuidle_get_driver();
81
if (!tmp) {
82
printf(_("Could not determine cpuidle driver\n"));
83
return;
84
}
85
86
printf(_("CPUidle driver: %s\n"), tmp);
87
free(tmp);
88
89
tmp = cpuidle_get_governor();
90
if (!tmp) {
91
printf(_("Could not determine cpuidle governor\n"));
92
return;
93
}
94
95
printf(_("CPUidle governor: %s\n"), tmp);
96
free(tmp);
97
}
98
99
static void proc_cpuidle_cpu_output(unsigned int cpu)
100
{
101
long max_allowed_cstate = 2000000000;
102
unsigned int cstate, cstates;
103
104
cstates = cpuidle_state_count(cpu);
105
if (cstates == 0) {
106
printf(_("CPU %u: No C-states info\n"), cpu);
107
return;
108
}
109
110
printf(_("active state: C0\n"));
111
printf(_("max_cstate: C%u\n"), cstates-1);
112
printf(_("maximum allowed latency: %lu usec\n"), max_allowed_cstate);
113
printf(_("states:\t\n"));
114
for (cstate = 1; cstate < cstates; cstate++) {
115
printf(_(" C%d: "
116
"type[C%d] "), cstate, cstate);
117
printf(_("promotion[--] demotion[--] "));
118
printf(_("latency[%03lu] "),
119
cpuidle_state_latency(cpu, cstate));
120
printf(_("residency[%05lu] "),
121
cpuidle_state_residency(cpu, cstate));
122
printf(_("usage[%08lu] "),
123
cpuidle_state_usage(cpu, cstate));
124
printf(_("duration[%020Lu] \n"),
125
cpuidle_state_time(cpu, cstate));
126
}
127
}
128
129
static struct option info_opts[] = {
130
{"silent", no_argument, NULL, 's'},
131
{"proc", no_argument, NULL, 'o'},
132
{ },
133
};
134
135
static inline void cpuidle_exit(int fail)
136
{
137
exit(EXIT_FAILURE);
138
}
139
140
int cmd_idle_info(int argc, char **argv)
141
{
142
extern char *optarg;
143
extern int optind, opterr, optopt;
144
int ret = 0, cont = 1, output_param = 0, verbose = 1;
145
unsigned int cpu = 0;
146
147
do {
148
ret = getopt_long(argc, argv, "os", info_opts, NULL);
149
if (ret == -1)
150
break;
151
switch (ret) {
152
case '?':
153
output_param = '?';
154
cont = 0;
155
break;
156
case 's':
157
verbose = 0;
158
break;
159
case -1:
160
cont = 0;
161
break;
162
case 'o':
163
if (output_param) {
164
output_param = -1;
165
cont = 0;
166
break;
167
}
168
output_param = ret;
169
break;
170
}
171
} while (cont);
172
173
switch (output_param) {
174
case -1:
175
printf(_("You can't specify more than one "
176
"output-specific argument\n"));
177
cpuidle_exit(EXIT_FAILURE);
178
case '?':
179
printf(_("invalid or unknown argument\n"));
180
cpuidle_exit(EXIT_FAILURE);
181
}
182
183
/* Default is: show output of base_cpu only */
184
if (bitmask_isallclear(cpus_chosen))
185
bitmask_setbit(cpus_chosen, base_cpu);
186
187
if (output_param == 0)
188
cpuidle_general_output();
189
190
for (cpu = bitmask_first(cpus_chosen);
191
cpu <= bitmask_last(cpus_chosen); cpu++) {
192
193
if (!bitmask_isbitset(cpus_chosen, cpu))
194
continue;
195
196
printf(_("analyzing CPU %d:\n"), cpu);
197
198
if (sysfs_is_cpu_online(cpu) != 1) {
199
printf(_(" *is offline\n"));
200
printf("\n");
201
continue;
202
}
203
204
switch (output_param) {
205
206
case 'o':
207
proc_cpuidle_cpu_output(cpu);
208
break;
209
case 0:
210
printf("\n");
211
cpuidle_cpu_output(cpu, verbose);
212
break;
213
}
214
printf("\n");
215
}
216
return EXIT_SUCCESS;
217
}
218
219