linux/tools/power/cpupower/utils/cpuidle-set.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#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                        if (param) {
  45                                param = -1;
  46                                cont = 0;
  47                                break;
  48                        }
  49                        param = ret;
  50                        idlestate = atoi(optarg);
  51                        break;
  52                case 'e':
  53                        if (param) {
  54                                param = -1;
  55                                cont = 0;
  56                                break;
  57                        }
  58                        param = ret;
  59                        idlestate = atoi(optarg);
  60                        break;
  61                case 'D':
  62                        if (param) {
  63                                param = -1;
  64                                cont = 0;
  65                                break;
  66                        }
  67                        param = ret;
  68                        latency = strtoull(optarg, &endptr, 10);
  69                        if (*endptr != '\0') {
  70                                printf(_("Bad latency value: %s\n"), optarg);
  71                                exit(EXIT_FAILURE);
  72                        }
  73                        break;
  74                case 'E':
  75                        if (param) {
  76                                param = -1;
  77                                cont = 0;
  78                                break;
  79                        }
  80                        param = ret;
  81                        break;
  82                case -1:
  83                        cont = 0;
  84                        break;
  85                }
  86        } while (cont);
  87
  88        switch (param) {
  89        case -1:
  90                printf(_("You can't specify more than one "
  91                         "output-specific argument\n"));
  92                exit(EXIT_FAILURE);
  93        case '?':
  94                printf(_("invalid or unknown argument\n"));
  95                exit(EXIT_FAILURE);
  96        }
  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                        else
 126                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                        else
 139                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_disabled
 145                                        (cpu, idlestate);
 146                                state_latency = cpuidle_state_latency
 147                                        (cpu, idlestate);
 148                                if (disabled == 1) {
 149                                        if (latency > state_latency){
 150                                                ret = cpuidle_state_disable
 151                                                        (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_disable
 159                                                (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_disabled
 168                                        (cpu, idlestate);
 169                                if (disabled == 1) {
 170                                        ret = cpuidle_state_disable
 171                                                (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        return EXIT_SUCCESS;
 185}
 186