cpuidle-set.c 4.1 KB

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