blob: 7add04ccbad428cc24e4667d7a8cf78455f402be [file] [log] [blame]
Dominik Brodowski7fe2f632011-03-30 16:30:11 +02001/*
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
19void 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
32static 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
40static void print_wrong_arg_exit(void)
41{
42 printf(_("invalid or unknown argument\n"));
43 info_help();
44 exit(EXIT_FAILURE);
45}
46
47int 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
61 } params = {};
62 int ret = 0;
63
64 setlocale(LC_ALL, "");
65 textdomain (PACKAGE);
66
67 /* parameter parsing */
68 while ((ret = getopt_long(argc, argv, "msbh", set_opts, NULL)) != -1) {
69 switch (ret) {
70 case 'h':
71 info_help();
72 return 0;
73 case 'b':
74 if (params.perf_bias)
75 print_wrong_arg_exit();
76 params.perf_bias = 1;
77 break;
78 case 'm':
79 if (params.sched_mc)
80 print_wrong_arg_exit();
81 params.sched_mc = 1;
82 break;
83 case 's':
84 if (params.sched_smt)
85 print_wrong_arg_exit();
86 params.sched_smt = 1;
87 break;
88 default:
89 print_wrong_arg_exit();
90 }
91 };
92
93 if (!params.params)
94 params.params = 0x7;
95
96 /* Default is: show output of CPU 0 only */
97 if (bitmask_isallclear(cpus_chosen))
98 bitmask_setbit(cpus_chosen, 0);
99
100 if (params.sched_mc) {
101 ret = sysfs_get_sched("mc");
102 printf(_("System's multi core scheduler setting: "));
103 if (ret < 0)
104 /* if sysfs file is missing it's: errno == ENOENT */
105 printf(_("not supported\n"));
106 else
107 printf("%d\n", ret);
108 }
109 if (params.sched_smt) {
110 ret = sysfs_get_sched("smt");
111 printf(_("System's thread sibling scheduler setting: "));
112 if (ret < 0)
113 /* if sysfs file is missing it's: errno == ENOENT */
114 printf(_("not supported\n"));
115 else
116 printf("%d\n", ret);
117 }
118
119 /* Add more per cpu options here */
120 if (!params.perf_bias)
121 return ret;
122
123 if (params.perf_bias) {
124 if (!run_as_root) {
125 params.perf_bias = 0;
126 printf (_("Intel's performance bias setting needs root privileges\n"));
127 } else if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS)) {
128 printf(_("System does not support Intel's performance"
129 " bias setting\n"));
130 params.perf_bias = 0;
131 }
132 }
133
134 /* loop over CPUs */
135 for (cpu = bitmask_first(cpus_chosen);
136 cpu <= bitmask_last(cpus_chosen); cpu++) {
137
138 if (!bitmask_isbitset(cpus_chosen, cpu) ||
139 cpufreq_cpu_exists(cpu))
140 continue;
141
142 printf(_("analyzing CPU %d:\n"), cpu);
143
144 if (params.perf_bias) {
145 ret = msr_intel_get_perf_bias(cpu);
146 if (ret < 0) {
147 printf(_("Could not read perf-bias value\n"));
148 break;
149 } else
150 printf(_("perf-bias: %d\n"), ret);
151 }
152 }
153 return ret;
154}