cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cpuidle-info.c (4571B)


      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(_("Usage: %lu\n"),
     68		       cpuidle_state_usage(cpu, idlestate));
     69		printf(_("Duration: %llu\n"),
     70		       cpuidle_state_time(cpu, idlestate));
     71	}
     72}
     73
     74static void cpuidle_general_output(void)
     75{
     76	char *tmp;
     77
     78	tmp = cpuidle_get_driver();
     79	if (!tmp) {
     80		printf(_("Could not determine cpuidle driver\n"));
     81		return;
     82	}
     83
     84	printf(_("CPUidle driver: %s\n"), tmp);
     85	free(tmp);
     86
     87	tmp = cpuidle_get_governor();
     88	if (!tmp) {
     89		printf(_("Could not determine cpuidle governor\n"));
     90		return;
     91	}
     92
     93	printf(_("CPUidle governor: %s\n"), tmp);
     94	free(tmp);
     95}
     96
     97static void proc_cpuidle_cpu_output(unsigned int cpu)
     98{
     99	long max_allowed_cstate = 2000000000;
    100	unsigned int cstate, cstates;
    101
    102	cstates = cpuidle_state_count(cpu);
    103	if (cstates == 0) {
    104		printf(_("CPU %u: No C-states info\n"), cpu);
    105		return;
    106	}
    107
    108	printf(_("active state:            C0\n"));
    109	printf(_("max_cstate:              C%u\n"), cstates-1);
    110	printf(_("maximum allowed latency: %lu usec\n"), max_allowed_cstate);
    111	printf(_("states:\t\n"));
    112	for (cstate = 1; cstate < cstates; cstate++) {
    113		printf(_("    C%d:                  "
    114			 "type[C%d] "), cstate, cstate);
    115		printf(_("promotion[--] demotion[--] "));
    116		printf(_("latency[%03lu] "),
    117		       cpuidle_state_latency(cpu, cstate));
    118		printf(_("usage[%08lu] "),
    119		       cpuidle_state_usage(cpu, cstate));
    120		printf(_("duration[%020Lu] \n"),
    121		       cpuidle_state_time(cpu, cstate));
    122	}
    123}
    124
    125static struct option info_opts[] = {
    126	{"silent", no_argument, NULL, 's'},
    127	{"proc", no_argument, NULL, 'o'},
    128	{ },
    129};
    130
    131static inline void cpuidle_exit(int fail)
    132{
    133	exit(EXIT_FAILURE);
    134}
    135
    136int cmd_idle_info(int argc, char **argv)
    137{
    138	extern char *optarg;
    139	extern int optind, opterr, optopt;
    140	int ret = 0, cont = 1, output_param = 0, verbose = 1;
    141	unsigned int cpu = 0;
    142
    143	do {
    144		ret = getopt_long(argc, argv, "os", info_opts, NULL);
    145		if (ret == -1)
    146			break;
    147		switch (ret) {
    148		case '?':
    149			output_param = '?';
    150			cont = 0;
    151			break;
    152		case 's':
    153			verbose = 0;
    154			break;
    155		case -1:
    156			cont = 0;
    157			break;
    158		case 'o':
    159			if (output_param) {
    160				output_param = -1;
    161				cont = 0;
    162				break;
    163			}
    164			output_param = ret;
    165			break;
    166		}
    167	} while (cont);
    168
    169	switch (output_param) {
    170	case -1:
    171		printf(_("You can't specify more than one "
    172			 "output-specific argument\n"));
    173		cpuidle_exit(EXIT_FAILURE);
    174	case '?':
    175		printf(_("invalid or unknown argument\n"));
    176		cpuidle_exit(EXIT_FAILURE);
    177	}
    178
    179	/* Default is: show output of CPU 0 only */
    180	if (bitmask_isallclear(cpus_chosen))
    181		bitmask_setbit(cpus_chosen, 0);
    182
    183	if (output_param == 0)
    184		cpuidle_general_output();
    185
    186	for (cpu = bitmask_first(cpus_chosen);
    187	     cpu <= bitmask_last(cpus_chosen); cpu++) {
    188
    189		if (!bitmask_isbitset(cpus_chosen, cpu))
    190			continue;
    191
    192		printf(_("analyzing CPU %d:\n"), cpu);
    193
    194		if (sysfs_is_cpu_online(cpu) != 1) {
    195			printf(_(" *is offline\n"));
    196			printf("\n");
    197			continue;
    198		}
    199
    200		switch (output_param) {
    201
    202		case 'o':
    203			proc_cpuidle_cpu_output(cpu);
    204			break;
    205		case 0:
    206			printf("\n");
    207			cpuidle_cpu_output(cpu, verbose);
    208			break;
    209		}
    210		printf("\n");
    211	}
    212	return EXIT_SUCCESS;
    213}