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