File Index
Files and directories
Sign in
FILE

cpuidle-info.c

File preview with syntax highlighting.

linux-6.19.14/tools/power/cpupower/utils/cpuidle-info.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 *  (C) 2004-2009  Dominik Brodowski <linux@dominikbrodowski.de>
  4 *  (C) 2010       Thomas Renninger <trenn@suse.de>
  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
 23static 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
 76static 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
 99static 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
129static struct option info_opts[] = {
130	{"silent", no_argument, NULL, 's'},
131	{"proc", no_argument, NULL, 'o'},
132	{ },
133};
134
135static inline void cpuidle_exit(int fail)
136{
137	exit(EXIT_FAILURE);
138}
139
140int 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}
~/ Read-only file preview.