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