Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cpupower-set.c
Go to the documentation of this file.
1 /*
2  * (C) 2011 Thomas Renninger <[email protected]>, 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 #include "helpers/bitmask.h"
19 
20 static struct option set_opts[] = {
21  { .name = "perf-bias", .has_arg = optional_argument, .flag = NULL, .val = 'b'},
22  { .name = "sched-mc", .has_arg = optional_argument, .flag = NULL, .val = 'm'},
23  { .name = "sched-smt", .has_arg = optional_argument, .flag = NULL, .val = 's'},
24  { },
25 };
26 
27 static void print_wrong_arg_exit(void)
28 {
29  printf(_("invalid or unknown argument\n"));
30  exit(EXIT_FAILURE);
31 }
32 
33 int cmd_set(int argc, char **argv)
34 {
35  extern char *optarg;
36  extern int optind, opterr, optopt;
37  unsigned int cpu;
38 
39  union {
40  struct {
41  int sched_mc:1;
42  int sched_smt:1;
43  int perf_bias:1;
44  };
45  int params;
46  } params;
47  int sched_mc = 0, sched_smt = 0, perf_bias = 0;
48  int ret = 0;
49 
50  setlocale(LC_ALL, "");
51  textdomain(PACKAGE);
52 
53  params.params = 0;
54  /* parameter parsing */
55  while ((ret = getopt_long(argc, argv, "m:s:b:",
56  set_opts, NULL)) != -1) {
57  switch (ret) {
58  case 'b':
59  if (params.perf_bias)
60  print_wrong_arg_exit();
61  perf_bias = atoi(optarg);
62  if (perf_bias < 0 || perf_bias > 15) {
63  printf(_("--perf-bias param out "
64  "of range [0-%d]\n"), 15);
65  print_wrong_arg_exit();
66  }
67  params.perf_bias = 1;
68  break;
69  case 'm':
70  if (params.sched_mc)
71  print_wrong_arg_exit();
72  sched_mc = atoi(optarg);
73  if (sched_mc < 0 || sched_mc > 2) {
74  printf(_("--sched-mc param out "
75  "of range [0-%d]\n"), 2);
76  print_wrong_arg_exit();
77  }
78  params.sched_mc = 1;
79  break;
80  case 's':
81  if (params.sched_smt)
82  print_wrong_arg_exit();
83  sched_smt = atoi(optarg);
84  if (sched_smt < 0 || sched_smt > 2) {
85  printf(_("--sched-smt param out "
86  "of range [0-%d]\n"), 2);
87  print_wrong_arg_exit();
88  }
89  params.sched_smt = 1;
90  break;
91  default:
92  print_wrong_arg_exit();
93  }
94  };
95 
96  if (!params.params)
97  print_wrong_arg_exit();
98 
99  if (params.sched_mc) {
100  ret = sysfs_set_sched("mc", sched_mc);
101  if (ret)
102  fprintf(stderr, _("Error setting sched-mc %s\n"),
103  (ret == -ENODEV) ? "not supported" : "");
104  }
105  if (params.sched_smt) {
106  ret = sysfs_set_sched("smt", sched_smt);
107  if (ret)
108  fprintf(stderr, _("Error setting sched-smt %s\n"),
109  (ret == -ENODEV) ? "not supported" : "");
110  }
111 
112  /* Default is: set all CPUs */
115 
116  /* loop over CPUs */
117  for (cpu = bitmask_first(cpus_chosen);
118  cpu <= bitmask_last(cpus_chosen); cpu++) {
119 
120  if (!bitmask_isbitset(cpus_chosen, cpu) ||
121  cpufreq_cpu_exists(cpu))
122  continue;
123 
124  if (params.perf_bias) {
125  ret = msr_intel_set_perf_bias(cpu, perf_bias);
126  if (ret) {
127  fprintf(stderr, _("Error setting perf-bias "
128  "value on CPU %d\n"), cpu);
129  break;
130  }
131  }
132  }
133  return ret;
134 }