Dominik Brodowski | 7fe2f63 | 2011-03-30 16:30:11 +0200 | [diff] [blame^] | 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 | |
| 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 | } |