xref: /linux/tools/power/cpupower/utils/cpupower-info.c (revision d20bbfab01802e195a50435940f7e4aa747c217c)
1 /*
2  *  (C) 2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3  *
4  *  Licensed under the terms of the GNU GPL License version 2.
5  */
6 
7 
8 #include <unistd.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <string.h>
13 #include <getopt.h>
14 
15 #include <cpufreq.h>
16 #include "helpers/helpers.h"
17 #include "helpers/sysfs.h"
18 
19 void info_help(void)
20 {
21 	printf(_("Usage: cpupower info [ -b ] [ -m ] [ -s ]\n"));
22 	printf(_("Options:\n"));
23 	printf(_("  -b, --perf-bias    Gets CPU's power vs performance policy on some\n"
24 	       "                           Intel models [0-15], see manpage for details\n"));
25 	printf(_("  -m, --sched-mc     Gets the kernel's multi core scheduler policy.\n"));
26 	printf(_("  -s, --sched-smt    Gets the kernel's thread sibling scheduler policy.\n"));
27 	printf(_("  -h, --help               Prints out this screen\n"));
28 	printf(_("\nPassing no option will show all info, by default only on core 0\n"));
29 	printf("\n");
30 }
31 
32 static struct option set_opts[] = {
33 	{ .name = "perf-bias",	.has_arg = optional_argument,	.flag = NULL,	.val = 'b'},
34 	{ .name = "sched-mc",	.has_arg = optional_argument,	.flag = NULL,	.val = 'm'},
35 	{ .name = "sched-smt",	.has_arg = optional_argument,	.flag = NULL,	.val = 's'},
36 	{ .name = "help",	.has_arg = no_argument,		.flag = NULL,	.val = 'h'},
37 	{ },
38 };
39 
40 static void print_wrong_arg_exit(void)
41 {
42 	printf(_("invalid or unknown argument\n"));
43 	info_help();
44 	exit(EXIT_FAILURE);
45 }
46 
47 int cmd_info(int argc, char **argv)
48 {
49 	extern char *optarg;
50 	extern int optind, opterr, optopt;
51 	unsigned int cpu;
52 
53 	union {
54 		struct {
55 			int sched_mc:1;
56 			int sched_smt:1;
57 			int perf_bias:1;
58 		};
59 		int params;
60 	} params = {};
61 	int ret = 0;
62 
63 	setlocale(LC_ALL, "");
64 	textdomain(PACKAGE);
65 
66 	/* parameter parsing */
67 	while ((ret = getopt_long(argc, argv, "msbh", set_opts, NULL)) != -1) {
68 		switch (ret) {
69 		case 'h':
70 			info_help();
71 			return 0;
72 		case 'b':
73 			if (params.perf_bias)
74 				print_wrong_arg_exit();
75 			params.perf_bias = 1;
76 			break;
77 		case 'm':
78 			if (params.sched_mc)
79 				print_wrong_arg_exit();
80 			params.sched_mc = 1;
81 			break;
82 		case 's':
83 			if (params.sched_smt)
84 				print_wrong_arg_exit();
85 			params.sched_smt = 1;
86 			break;
87 		default:
88 			print_wrong_arg_exit();
89 		}
90 	};
91 
92 	if (!params.params)
93 		params.params = 0x7;
94 
95 	/* Default is: show output of CPU 0 only */
96 	if (bitmask_isallclear(cpus_chosen))
97 		bitmask_setbit(cpus_chosen, 0);
98 
99 	if (params.sched_mc) {
100 		ret = sysfs_get_sched("mc");
101 		printf(_("System's multi core scheduler setting: "));
102 		if (ret < 0)
103 			/* if sysfs file is missing it's: errno == ENOENT */
104 			printf(_("not supported\n"));
105 		else
106 			printf("%d\n", ret);
107 	}
108 	if (params.sched_smt) {
109 		ret = sysfs_get_sched("smt");
110 		printf(_("System's thread sibling scheduler setting: "));
111 		if (ret < 0)
112 			/* if sysfs file is missing it's: errno == ENOENT */
113 			printf(_("not supported\n"));
114 		else
115 			printf("%d\n", ret);
116 	}
117 
118 	/* Add more per cpu options here */
119 	if (!params.perf_bias)
120 		return ret;
121 
122 	if (params.perf_bias) {
123 		if (!run_as_root) {
124 			params.perf_bias = 0;
125 			printf(_("Intel's performance bias setting needs root privileges\n"));
126 		} else if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS)) {
127 			printf(_("System does not support Intel's performance"
128 				 " bias setting\n"));
129 			params.perf_bias = 0;
130 		}
131 	}
132 
133 	/* loop over CPUs */
134 	for (cpu = bitmask_first(cpus_chosen);
135 	     cpu <= bitmask_last(cpus_chosen); cpu++) {
136 
137 		if (!bitmask_isbitset(cpus_chosen, cpu) ||
138 		    cpufreq_cpu_exists(cpu))
139 			continue;
140 
141 		printf(_("analyzing CPU %d:\n"), cpu);
142 
143 		if (params.perf_bias) {
144 			ret = msr_intel_get_perf_bias(cpu);
145 			if (ret < 0) {
146 				printf(_("Could not read perf-bias value\n"));
147 				break;
148 			} else
149 				printf(_("perf-bias: %d\n"), ret);
150 		}
151 	}
152 	return ret;
153 }
154