diff options
Diffstat (limited to 'tools/power/cpupower/utils/cpuidle-set.c')
| -rw-r--r-- | tools/power/cpupower/utils/cpuidle-set.c | 99 |
1 files changed, 84 insertions, 15 deletions
diff --git a/tools/power/cpupower/utils/cpuidle-set.c b/tools/power/cpupower/utils/cpuidle-set.c index c78141c5dfac..a551d1d4ac51 100644 --- a/tools/power/cpupower/utils/cpuidle-set.c +++ b/tools/power/cpupower/utils/cpuidle-set.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <unistd.h> #include <stdio.h> #include <errno.h> @@ -5,17 +6,19 @@ #include <limits.h> #include <string.h> #include <ctype.h> - #include <getopt.h> -#include "cpufreq.h" +#include <cpufreq.h> +#include <cpuidle.h> + #include "helpers/helpers.h" -#include "helpers/sysfs.h" static struct option info_opts[] = { - { .name = "disable", .has_arg = required_argument, .flag = NULL, .val = 'd'}, - { .name = "enable", .has_arg = required_argument, .flag = NULL, .val = 'e'}, - { }, + {"disable", required_argument, NULL, 'd'}, + {"enable", required_argument, NULL, 'e'}, + {"disable-by-latency", required_argument, NULL, 'D'}, + {"enable-all", no_argument, NULL, 'E'}, + { }, }; @@ -23,11 +26,13 @@ int cmd_idle_set(int argc, char **argv) { extern char *optarg; extern int optind, opterr, optopt; - int ret = 0, cont = 1, param = 0, idlestate = 0; - unsigned int cpu = 0; + int ret = 0, cont = 1, param = 0, disabled; + unsigned long long latency = 0, state_latency; + unsigned int cpu = 0, idlestate = 0, idlestates = 0; + char *endptr; do { - ret = getopt_long(argc, argv, "d:e:", info_opts, NULL); + ret = getopt_long(argc, argv, "d:e:ED:", info_opts, NULL); if (ret == -1) break; switch (ret) { @@ -36,22 +41,41 @@ int cmd_idle_set(int argc, char **argv) cont = 0; break; case 'd': + case 'e': if (param) { param = -1; cont = 0; break; } param = ret; - idlestate = atoi(optarg); + strtol(optarg, &endptr, 10); + if (*endptr != '\0') { + printf(_("Bad value: %s, Integer expected\n"), optarg); + exit(EXIT_FAILURE); + } else { + idlestate = atoi(optarg); + } break; - case 'e': + case 'D': + if (param) { + param = -1; + cont = 0; + break; + } + param = ret; + latency = strtoull(optarg, &endptr, 10); + if (*endptr != '\0') { + printf(_("Bad latency value: %s\n"), optarg); + exit(EXIT_FAILURE); + } + break; + case 'E': if (param) { param = -1; cont = 0; break; } param = ret; - idlestate = atoi(optarg); break; case -1: cont = 0; @@ -69,6 +93,8 @@ int cmd_idle_set(int argc, char **argv) exit(EXIT_FAILURE); } + get_cpustate(); + /* Default is: set all CPUs */ if (bitmask_isallclear(cpus_chosen)) bitmask_setall(cpus_chosen); @@ -79,10 +105,16 @@ int cmd_idle_set(int argc, char **argv) if (!bitmask_isbitset(cpus_chosen, cpu)) continue; - switch (param) { + if (cpupower_is_cpu_online(cpu) != 1) + continue; + idlestates = cpuidle_state_count(cpu); + if (idlestates <= 0) + continue; + + switch (param) { case 'd': - ret = sysfs_idlestate_disable(cpu, idlestate, 1); + ret = cpuidle_state_disable(cpu, idlestate, 1); if (ret == 0) printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu); else if (ret == -1) @@ -95,7 +127,7 @@ int cmd_idle_set(int argc, char **argv) idlestate, cpu); break; case 'e': - ret = sysfs_idlestate_disable(cpu, idlestate, 0); + ret = cpuidle_state_disable(cpu, idlestate, 0); if (ret == 0) printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu); else if (ret == -1) @@ -107,6 +139,41 @@ int cmd_idle_set(int argc, char **argv) printf(_("Idlestate %u not enabled on CPU %u\n"), idlestate, cpu); break; + case 'D': + for (idlestate = 0; idlestate < idlestates; idlestate++) { + disabled = cpuidle_is_state_disabled + (cpu, idlestate); + state_latency = cpuidle_state_latency + (cpu, idlestate); + if (disabled == 1) { + if (latency > state_latency){ + ret = cpuidle_state_disable + (cpu, idlestate, 0); + if (ret == 0) + printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu); + } + continue; + } + if (latency <= state_latency){ + ret = cpuidle_state_disable + (cpu, idlestate, 1); + if (ret == 0) + printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu); + } + } + break; + case 'E': + for (idlestate = 0; idlestate < idlestates; idlestate++) { + disabled = cpuidle_is_state_disabled + (cpu, idlestate); + if (disabled == 1) { + ret = cpuidle_state_disable + (cpu, idlestate, 0); + if (ret == 0) + printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu); + } + } + break; default: /* Not reachable with proper args checking */ printf(_("Invalid or unknown argument\n")); @@ -114,5 +181,7 @@ int cmd_idle_set(int argc, char **argv) break; } } + + print_offline_cpus(); return EXIT_SUCCESS; } |
