85253cb7600ef8c7850bcd7332a6639be20b9bf3
[linux-2.6.git] / tools / power / cpupower / utils / cpupower-info.c
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 }