cpuidle-info.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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 <cpuidle.h>
  14. #include "helpers/sysfs.h"
  15. #include "helpers/helpers.h"
  16. #include "helpers/bitmask.h"
  17. #define LINE_LEN 10
  18. static void cpuidle_cpu_output(unsigned int cpu, int verbose)
  19. {
  20. unsigned int idlestates, idlestate;
  21. char *tmp;
  22. idlestates = cpuidle_state_count(cpu);
  23. if (idlestates == 0) {
  24. printf(_("CPU %u: No idle states\n"), cpu);
  25. return;
  26. }
  27. printf(_("Number of idle states: %d\n"), idlestates);
  28. printf(_("Available idle states:"));
  29. for (idlestate = 0; idlestate < idlestates; idlestate++) {
  30. tmp = cpuidle_state_name(cpu, idlestate);
  31. if (!tmp)
  32. continue;
  33. printf(" %s", tmp);
  34. free(tmp);
  35. }
  36. printf("\n");
  37. if (!verbose)
  38. return;
  39. for (idlestate = 0; idlestate < idlestates; idlestate++) {
  40. int disabled = cpuidle_is_state_disabled(cpu, idlestate);
  41. /* Disabled interface not supported on older kernels */
  42. if (disabled < 0)
  43. disabled = 0;
  44. tmp = cpuidle_state_name(cpu, idlestate);
  45. if (!tmp)
  46. continue;
  47. printf("%s%s:\n", tmp, (disabled) ? " (DISABLED) " : "");
  48. free(tmp);
  49. tmp = cpuidle_state_desc(cpu, idlestate);
  50. if (!tmp)
  51. continue;
  52. printf(_("Flags/Description: %s\n"), tmp);
  53. free(tmp);
  54. printf(_("Latency: %lu\n"),
  55. cpuidle_state_latency(cpu, idlestate));
  56. printf(_("Usage: %lu\n"),
  57. cpuidle_state_usage(cpu, idlestate));
  58. printf(_("Duration: %llu\n"),
  59. cpuidle_state_time(cpu, idlestate));
  60. }
  61. }
  62. static void cpuidle_general_output(void)
  63. {
  64. char *tmp;
  65. tmp = cpuidle_get_driver();
  66. if (!tmp) {
  67. printf(_("Could not determine cpuidle driver\n"));
  68. return;
  69. }
  70. printf(_("CPUidle driver: %s\n"), tmp);
  71. free(tmp);
  72. tmp = cpuidle_get_governor();
  73. if (!tmp) {
  74. printf(_("Could not determine cpuidle governor\n"));
  75. return;
  76. }
  77. printf(_("CPUidle governor: %s\n"), tmp);
  78. free(tmp);
  79. }
  80. static void proc_cpuidle_cpu_output(unsigned int cpu)
  81. {
  82. long max_allowed_cstate = 2000000000;
  83. unsigned int cstate, cstates;
  84. cstates = cpuidle_state_count(cpu);
  85. if (cstates == 0) {
  86. printf(_("CPU %u: No C-states info\n"), cpu);
  87. return;
  88. }
  89. printf(_("active state: C0\n"));
  90. printf(_("max_cstate: C%u\n"), cstates-1);
  91. printf(_("maximum allowed latency: %lu usec\n"), max_allowed_cstate);
  92. printf(_("states:\t\n"));
  93. for (cstate = 1; cstate < cstates; cstate++) {
  94. printf(_(" C%d: "
  95. "type[C%d] "), cstate, cstate);
  96. printf(_("promotion[--] demotion[--] "));
  97. printf(_("latency[%03lu] "),
  98. cpuidle_state_latency(cpu, cstate));
  99. printf(_("usage[%08lu] "),
  100. cpuidle_state_usage(cpu, cstate));
  101. printf(_("duration[%020Lu] \n"),
  102. cpuidle_state_time(cpu, cstate));
  103. }
  104. }
  105. static struct option info_opts[] = {
  106. {"silent", no_argument, NULL, 's'},
  107. {"proc", no_argument, NULL, 'o'},
  108. { },
  109. };
  110. static inline void cpuidle_exit(int fail)
  111. {
  112. exit(EXIT_FAILURE);
  113. }
  114. int cmd_idle_info(int argc, char **argv)
  115. {
  116. extern char *optarg;
  117. extern int optind, opterr, optopt;
  118. int ret = 0, cont = 1, output_param = 0, verbose = 1;
  119. unsigned int cpu = 0;
  120. do {
  121. ret = getopt_long(argc, argv, "os", info_opts, NULL);
  122. if (ret == -1)
  123. break;
  124. switch (ret) {
  125. case '?':
  126. output_param = '?';
  127. cont = 0;
  128. break;
  129. case 's':
  130. verbose = 0;
  131. break;
  132. case -1:
  133. cont = 0;
  134. break;
  135. case 'o':
  136. if (output_param) {
  137. output_param = -1;
  138. cont = 0;
  139. break;
  140. }
  141. output_param = ret;
  142. break;
  143. }
  144. } while (cont);
  145. switch (output_param) {
  146. case -1:
  147. printf(_("You can't specify more than one "
  148. "output-specific argument\n"));
  149. cpuidle_exit(EXIT_FAILURE);
  150. case '?':
  151. printf(_("invalid or unknown argument\n"));
  152. cpuidle_exit(EXIT_FAILURE);
  153. }
  154. /* Default is: show output of CPU 0 only */
  155. if (bitmask_isallclear(cpus_chosen))
  156. bitmask_setbit(cpus_chosen, 0);
  157. if (output_param == 0)
  158. cpuidle_general_output();
  159. for (cpu = bitmask_first(cpus_chosen);
  160. cpu <= bitmask_last(cpus_chosen); cpu++) {
  161. if (!bitmask_isbitset(cpus_chosen, cpu))
  162. continue;
  163. printf(_("analyzing CPU %d:\n"), cpu);
  164. if (sysfs_is_cpu_online(cpu) != 1) {
  165. printf(_(" *is offline\n"));
  166. printf("\n");
  167. continue;
  168. }
  169. switch (output_param) {
  170. case 'o':
  171. proc_cpuidle_cpu_output(cpu);
  172. break;
  173. case 0:
  174. printf("\n");
  175. cpuidle_cpu_output(cpu, verbose);
  176. break;
  177. }
  178. printf("\n");
  179. }
  180. return EXIT_SUCCESS;
  181. }