blob: dc4de37621117f7dc6fe8d47669e761063c9eed0 [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#include "helpers/bitmask.h"
19
Dominik Brodowski7fe2f632011-03-30 16:30:11 +020020static struct option set_opts[] = {
Dominik Brodowskia1ce5ba2011-04-19 20:33:50 +020021 { .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'},
Dominik Brodowski7fe2f632011-03-30 16:30:11 +020024 { },
25};
26
27static void print_wrong_arg_exit(void)
28{
29 printf(_("invalid or unknown argument\n"));
Dominik Brodowski7fe2f632011-03-30 16:30:11 +020030 exit(EXIT_FAILURE);
31}
32
33int 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;
Dominik Brodowski7fe2f632011-03-30 16:30:11 +020046 } params;
47 int sched_mc = 0, sched_smt = 0, perf_bias = 0;
48 int ret = 0;
49
50 setlocale(LC_ALL, "");
Dominik Brodowskia1ce5ba2011-04-19 20:33:50 +020051 textdomain(PACKAGE);
Dominik Brodowski7fe2f632011-03-30 16:30:11 +020052
53 params.params = 0;
54 /* parameter parsing */
Dominik Brodowski498ca792011-08-06 18:11:43 +020055 while ((ret = getopt_long(argc, argv, "m:s:b:",
Dominik Brodowskia1ce5ba2011-04-19 20:33:50 +020056 set_opts, NULL)) != -1) {
Dominik Brodowski7fe2f632011-03-30 16:30:11 +020057 switch (ret) {
Dominik Brodowski7fe2f632011-03-30 16:30:11 +020058 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
Dominik Brodowski498ca792011-08-06 18:11:43 +020096 if (!params.params)
97 print_wrong_arg_exit();
Dominik Brodowski7fe2f632011-03-30 16:30:11 +020098
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 */
113 if (bitmask_isallclear(cpus_chosen))
114 bitmask_setall(cpus_chosen);
115
116 /* loop over CPUs */
117 for (cpu = bitmask_first(cpus_chosen);
118 cpu <= bitmask_last(cpus_chosen); cpu++) {
Dominik Brodowskia1ce5ba2011-04-19 20:33:50 +0200119
Dominik Brodowski7fe2f632011-03-30 16:30:11 +0200120 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}