cpuidle-info.c 4.5 KB

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