1 #include <unistd.h>
2 #include <stdio.h>
3 #include <errno.h>
4 #include <stdlib.h>
5 #include <limits.h>
6 #include <string.h>
7 #include <ctype.h>
8
9 #include <getopt.h>
10
11 #include "cpufreq.h"
12 #include "helpers/helpers.h"
13 #include "helpers/sysfs.h"
14
15 static struct option info_opts[] = {
16 { .name = "disable",
17 .has_arg = required_argument, .flag = NULL, .val = 'd'},
18 { .name = "enable",
19 .has_arg = required_argument, .flag = NULL, .val = 'e'},
20 { .name = "disable-by-latency",
21 .has_arg = required_argument, .flag = NULL, .val = 'D'},
22 { .name = "enable-all",
23 .has_arg = no_argument, .flag = NULL, .val = 'E'},
24 { },
25 };
26
27
cmd_idle_set(int argc,char ** argv)28 int cmd_idle_set(int argc, char **argv)
29 {
30 extern char *optarg;
31 extern int optind, opterr, optopt;
32 int ret = 0, cont = 1, param = 0, disabled;
33 unsigned long long latency = 0, state_latency;
34 unsigned int cpu = 0, idlestate = 0, idlestates = 0;
35 char *endptr;
36
37 do {
38 ret = getopt_long(argc, argv, "d:e:ED:", info_opts, NULL);
39 if (ret == -1)
40 break;
41 switch (ret) {
42 case '?':
43 param = '?';
44 cont = 0;
45 break;
46 case 'd':
47 if (param) {
48 param = -1;
49 cont = 0;
50 break;
51 }
52 param = ret;
53 idlestate = atoi(optarg);
54 break;
55 case 'e':
56 if (param) {
57 param = -1;
58 cont = 0;
59 break;
60 }
61 param = ret;
62 idlestate = atoi(optarg);
63 break;
64 case 'D':
65 if (param) {
66 param = -1;
67 cont = 0;
68 break;
69 }
70 param = ret;
71 latency = strtoull(optarg, &endptr, 10);
72 if (*endptr != '\0') {
73 printf(_("Bad latency value: %s\n"), optarg);
74 exit(EXIT_FAILURE);
75 }
76 break;
77 case 'E':
78 if (param) {
79 param = -1;
80 cont = 0;
81 break;
82 }
83 param = ret;
84 break;
85 case -1:
86 cont = 0;
87 break;
88 }
89 } while (cont);
90
91 switch (param) {
92 case -1:
93 printf(_("You can't specify more than one "
94 "output-specific argument\n"));
95 exit(EXIT_FAILURE);
96 case '?':
97 printf(_("invalid or unknown argument\n"));
98 exit(EXIT_FAILURE);
99 }
100
101 /* Default is: set all CPUs */
102 if (bitmask_isallclear(cpus_chosen))
103 bitmask_setall(cpus_chosen);
104
105 for (cpu = bitmask_first(cpus_chosen);
106 cpu <= bitmask_last(cpus_chosen); cpu++) {
107
108 if (!bitmask_isbitset(cpus_chosen, cpu))
109 continue;
110
111 if (sysfs_is_cpu_online(cpu) != 1)
112 continue;
113
114 idlestates = sysfs_get_idlestate_count(cpu);
115 if (idlestates <= 0)
116 continue;
117
118 switch (param) {
119 case 'd':
120 ret = sysfs_idlestate_disable(cpu, idlestate, 1);
121 if (ret == 0)
122 printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu);
123 else if (ret == -1)
124 printf(_("Idlestate %u not available on CPU %u\n"),
125 idlestate, cpu);
126 else if (ret == -2)
127 printf(_("Idlestate disabling not supported by kernel\n"));
128 else
129 printf(_("Idlestate %u not disabled on CPU %u\n"),
130 idlestate, cpu);
131 break;
132 case 'e':
133 ret = sysfs_idlestate_disable(cpu, idlestate, 0);
134 if (ret == 0)
135 printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu);
136 else if (ret == -1)
137 printf(_("Idlestate %u not available on CPU %u\n"),
138 idlestate, cpu);
139 else if (ret == -2)
140 printf(_("Idlestate enabling not supported by kernel\n"));
141 else
142 printf(_("Idlestate %u not enabled on CPU %u\n"),
143 idlestate, cpu);
144 break;
145 case 'D':
146 for (idlestate = 0; idlestate < idlestates; idlestate++) {
147 disabled = sysfs_is_idlestate_disabled
148 (cpu, idlestate);
149 state_latency = sysfs_get_idlestate_latency
150 (cpu, idlestate);
151 printf("CPU: %u - idlestate %u - state_latency: %llu - latency: %llu\n",
152 cpu, idlestate, state_latency, latency);
153 if (disabled == 1 || latency > state_latency)
154 continue;
155 ret = sysfs_idlestate_disable
156 (cpu, idlestate, 1);
157 if (ret == 0)
158 printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu);
159 }
160 break;
161 case 'E':
162 for (idlestate = 0; idlestate < idlestates; idlestate++) {
163 disabled = sysfs_is_idlestate_disabled
164 (cpu, idlestate);
165 if (disabled == 1) {
166 ret = sysfs_idlestate_disable
167 (cpu, idlestate, 0);
168 if (ret == 0)
169 printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu);
170 }
171 }
172 break;
173 default:
174 /* Not reachable with proper args checking */
175 printf(_("Invalid or unknown argument\n"));
176 exit(EXIT_FAILURE);
177 break;
178 }
179 }
180 return EXIT_SUCCESS;
181 }
182