cpuidle-info.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.de>
  3. * (C) 2010 Thomas Renninger <trenn@suse.de>
  4. *
  5. * Licensed under the terms of the GNU GPL License version 2.
  6. */
  7. #include <unistd.h>
  8. #include <stdio.h>
  9. #include <errno.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <getopt.h>
  13. #include <cpufreq.h>
  14. #include "helpers/helpers.h"
  15. #include "helpers/sysfs.h"
  16. #include "helpers/bitmask.h"
  17. #define LINE_LEN 10
  18. static void cpuidle_cpu_output(unsigned int cpu, int verbose)
  19. {
  20. int idlestates, idlestate;
  21. char *tmp;
  22. printf(_ ("Analyzing CPU %d:\n"), cpu);
  23. idlestates = sysfs_get_idlestate_count(cpu);
  24. if (idlestates == 0) {
  25. printf(_("CPU %u: No idle states\n"), cpu);
  26. return;
  27. } else if (idlestates <= 0) {
  28. printf(_("CPU %u: Can't read idle state info\n"), cpu);
  29. return;
  30. }
  31. tmp = sysfs_get_idlestate_name(cpu, idlestates - 1);
  32. if (!tmp) {
  33. printf(_("Could not determine max idle state %u\n"),
  34. idlestates - 1);
  35. return;
  36. }
  37. printf(_("Number of idle states: %d\n"), idlestates);
  38. printf(_("Available idle states:"));
  39. for (idlestate = 1; idlestate < idlestates; idlestate++) {
  40. tmp = sysfs_get_idlestate_name(cpu, idlestate);
  41. if (!tmp)
  42. continue;
  43. printf(" %s", tmp);
  44. free(tmp);
  45. }
  46. printf("\n");
  47. if (!verbose)
  48. return;
  49. for (idlestate = 1; idlestate < idlestates; idlestate++) {
  50. tmp = sysfs_get_idlestate_name(cpu, idlestate);
  51. if (!tmp)
  52. continue;
  53. printf("%s:\n", tmp);
  54. free(tmp);
  55. tmp = sysfs_get_idlestate_desc(cpu, idlestate);
  56. if (!tmp)
  57. continue;
  58. printf(_("Flags/Description: %s\n"), tmp);
  59. free(tmp);
  60. printf(_("Latency: %lu\n"),
  61. sysfs_get_idlestate_latency(cpu, idlestate));
  62. printf(_("Usage: %lu\n"),
  63. sysfs_get_idlestate_usage(cpu, idlestate));
  64. printf(_("Duration: %llu\n"),
  65. sysfs_get_idlestate_time(cpu, idlestate));
  66. }
  67. printf("\n");
  68. }
  69. static void cpuidle_general_output(void)
  70. {
  71. char *tmp;
  72. tmp = sysfs_get_cpuidle_driver();
  73. if (!tmp) {
  74. printf(_("Could not determine cpuidle driver\n"));
  75. return;
  76. }
  77. printf(_("CPUidle driver: %s\n"), tmp);
  78. free(tmp);
  79. tmp = sysfs_get_cpuidle_governor();
  80. if (!tmp) {
  81. printf(_("Could not determine cpuidle governor\n"));
  82. return;
  83. }
  84. printf(_("CPUidle governor: %s\n"), tmp);
  85. free(tmp);
  86. }
  87. static void proc_cpuidle_cpu_output(unsigned int cpu)
  88. {
  89. long max_allowed_cstate = 2000000000;
  90. int cstates, cstate;
  91. cstates = sysfs_get_idlestate_count(cpu);
  92. if (cstates == 0) {
  93. /*
  94. * Go on and print same useless info as you'd see with
  95. * cat /proc/acpi/processor/../power
  96. * printf(_("CPU %u: No C-states available\n"), cpu);
  97. * return;
  98. */
  99. } else if (cstates <= 0) {
  100. printf(_("CPU %u: Can't read C-state info\n"), cpu);
  101. return;
  102. }
  103. /* printf("Cstates: %d\n", cstates); */
  104. printf(_("active state: C0\n"));
  105. printf(_("max_cstate: C%u\n"), cstates-1);
  106. printf(_("maximum allowed latency: %lu usec\n"), max_allowed_cstate);
  107. printf(_("states:\t\n"));
  108. for (cstate = 1; cstate < cstates; cstate++) {
  109. printf(_(" C%d: "
  110. "type[C%d] "), cstate, cstate);
  111. printf(_("promotion[--] demotion[--] "));
  112. printf(_("latency[%03lu] "),
  113. sysfs_get_idlestate_latency(cpu, cstate));
  114. printf(_("usage[%08lu] "),
  115. sysfs_get_idlestate_usage(cpu, cstate));
  116. printf(_("duration[%020Lu] \n"),
  117. sysfs_get_idlestate_time(cpu, cstate));
  118. }
  119. }
  120. static struct option info_opts[] = {
  121. { .name = "silent", .has_arg = no_argument, .flag = NULL, .val = 's'},
  122. { .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'},
  123. { },
  124. };
  125. static inline void cpuidle_exit(int fail)
  126. {
  127. exit(EXIT_FAILURE);
  128. }
  129. int cmd_idle_info(int argc, char **argv)
  130. {
  131. extern char *optarg;
  132. extern int optind, opterr, optopt;
  133. int ret = 0, cont = 1, output_param = 0, verbose = 1;
  134. unsigned int cpu = 0;
  135. do {
  136. ret = getopt_long(argc, argv, "os", info_opts, NULL);
  137. if (ret == -1)
  138. break;
  139. switch (ret) {
  140. case '?':
  141. output_param = '?';
  142. cont = 0;
  143. break;
  144. case 's':
  145. verbose = 0;
  146. break;
  147. case -1:
  148. cont = 0;
  149. break;
  150. case 'o':
  151. if (output_param) {
  152. output_param = -1;
  153. cont = 0;
  154. break;
  155. }
  156. output_param = ret;
  157. break;
  158. }
  159. } while (cont);
  160. switch (output_param) {
  161. case -1:
  162. printf(_("You can't specify more than one "
  163. "output-specific argument\n"));
  164. cpuidle_exit(EXIT_FAILURE);
  165. case '?':
  166. printf(_("invalid or unknown argument\n"));
  167. cpuidle_exit(EXIT_FAILURE);
  168. }
  169. /* Default is: show output of CPU 0 only */
  170. if (bitmask_isallclear(cpus_chosen))
  171. bitmask_setbit(cpus_chosen, 0);
  172. if (output_param == 0)
  173. cpuidle_general_output();
  174. for (cpu = bitmask_first(cpus_chosen);
  175. cpu <= bitmask_last(cpus_chosen); cpu++) {
  176. if (!bitmask_isbitset(cpus_chosen, cpu) ||
  177. cpufreq_cpu_exists(cpu))
  178. continue;
  179. switch (output_param) {
  180. case 'o':
  181. proc_cpuidle_cpu_output(cpu);
  182. break;
  183. case 0:
  184. printf("\n");
  185. cpuidle_cpu_output(cpu, verbose);
  186. break;
  187. }
  188. }
  189. return EXIT_SUCCESS;
  190. }