Path: blob/master/tools/power/cpupower/utils/cpuidle-info.c
26292 views
// SPDX-License-Identifier: GPL-2.0-only1/*2* (C) 2004-2009 Dominik Brodowski <[email protected]>3* (C) 2010 Thomas Renninger <[email protected]>4*/567#include <unistd.h>8#include <stdio.h>9#include <errno.h>10#include <stdlib.h>11#include <string.h>12#include <getopt.h>1314#include <cpuidle.h>1516#include "helpers/sysfs.h"17#include "helpers/helpers.h"18#include "helpers/bitmask.h"1920#define LINE_LEN 102122static void cpuidle_cpu_output(unsigned int cpu, int verbose)23{24unsigned int idlestates, idlestate;25char *tmp;2627idlestates = cpuidle_state_count(cpu);28if (idlestates == 0) {29printf(_("CPU %u: No idle states\n"), cpu);30return;31}3233printf(_("Number of idle states: %d\n"), idlestates);34printf(_("Available idle states:"));35for (idlestate = 0; idlestate < idlestates; idlestate++) {36tmp = cpuidle_state_name(cpu, idlestate);37if (!tmp)38continue;39printf(" %s", tmp);40free(tmp);41}42printf("\n");4344if (!verbose)45return;4647for (idlestate = 0; idlestate < idlestates; idlestate++) {48int disabled = cpuidle_is_state_disabled(cpu, idlestate);49/* Disabled interface not supported on older kernels */50if (disabled < 0)51disabled = 0;52tmp = cpuidle_state_name(cpu, idlestate);53if (!tmp)54continue;55printf("%s%s:\n", tmp, (disabled) ? " (DISABLED) " : "");56free(tmp);5758tmp = cpuidle_state_desc(cpu, idlestate);59if (!tmp)60continue;61printf(_("Flags/Description: %s\n"), tmp);62free(tmp);6364printf(_("Latency: %lu\n"),65cpuidle_state_latency(cpu, idlestate));66printf(_("Residency: %lu\n"),67cpuidle_state_residency(cpu, idlestate));68printf(_("Usage: %lu\n"),69cpuidle_state_usage(cpu, idlestate));70printf(_("Duration: %llu\n"),71cpuidle_state_time(cpu, idlestate));72}73}7475static void cpuidle_general_output(void)76{77char *tmp;7879tmp = cpuidle_get_driver();80if (!tmp) {81printf(_("Could not determine cpuidle driver\n"));82return;83}8485printf(_("CPUidle driver: %s\n"), tmp);86free(tmp);8788tmp = cpuidle_get_governor();89if (!tmp) {90printf(_("Could not determine cpuidle governor\n"));91return;92}9394printf(_("CPUidle governor: %s\n"), tmp);95free(tmp);96}9798static void proc_cpuidle_cpu_output(unsigned int cpu)99{100long max_allowed_cstate = 2000000000;101unsigned int cstate, cstates;102103cstates = cpuidle_state_count(cpu);104if (cstates == 0) {105printf(_("CPU %u: No C-states info\n"), cpu);106return;107}108109printf(_("active state: C0\n"));110printf(_("max_cstate: C%u\n"), cstates-1);111printf(_("maximum allowed latency: %lu usec\n"), max_allowed_cstate);112printf(_("states:\t\n"));113for (cstate = 1; cstate < cstates; cstate++) {114printf(_(" C%d: "115"type[C%d] "), cstate, cstate);116printf(_("promotion[--] demotion[--] "));117printf(_("latency[%03lu] "),118cpuidle_state_latency(cpu, cstate));119printf(_("residency[%05lu] "),120cpuidle_state_residency(cpu, cstate));121printf(_("usage[%08lu] "),122cpuidle_state_usage(cpu, cstate));123printf(_("duration[%020Lu] \n"),124cpuidle_state_time(cpu, cstate));125}126}127128static struct option info_opts[] = {129{"silent", no_argument, NULL, 's'},130{"proc", no_argument, NULL, 'o'},131{ },132};133134static inline void cpuidle_exit(int fail)135{136exit(EXIT_FAILURE);137}138139int cmd_idle_info(int argc, char **argv)140{141extern char *optarg;142extern int optind, opterr, optopt;143int ret = 0, cont = 1, output_param = 0, verbose = 1;144unsigned int cpu = 0;145146do {147ret = getopt_long(argc, argv, "os", info_opts, NULL);148if (ret == -1)149break;150switch (ret) {151case '?':152output_param = '?';153cont = 0;154break;155case 's':156verbose = 0;157break;158case -1:159cont = 0;160break;161case 'o':162if (output_param) {163output_param = -1;164cont = 0;165break;166}167output_param = ret;168break;169}170} while (cont);171172switch (output_param) {173case -1:174printf(_("You can't specify more than one "175"output-specific argument\n"));176cpuidle_exit(EXIT_FAILURE);177case '?':178printf(_("invalid or unknown argument\n"));179cpuidle_exit(EXIT_FAILURE);180}181182/* Default is: show output of base_cpu only */183if (bitmask_isallclear(cpus_chosen))184bitmask_setbit(cpus_chosen, base_cpu);185186if (output_param == 0)187cpuidle_general_output();188189for (cpu = bitmask_first(cpus_chosen);190cpu <= bitmask_last(cpus_chosen); cpu++) {191192if (!bitmask_isbitset(cpus_chosen, cpu))193continue;194195printf(_("analyzing CPU %d:\n"), cpu);196197if (sysfs_is_cpu_online(cpu) != 1) {198printf(_(" *is offline\n"));199printf("\n");200continue;201}202203switch (output_param) {204205case 'o':206proc_cpuidle_cpu_output(cpu);207break;208case 0:209printf("\n");210cpuidle_cpu_output(cpu, verbose);211break;212}213printf("\n");214}215return EXIT_SUCCESS;216}217218219