cpufreq-info.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. /*
  2. * (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.de>
  3. *
  4. * Licensed under the terms of the GNU GPL License version 2.
  5. */
  6. #include <unistd.h>
  7. #include <stdio.h>
  8. #include <errno.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <getopt.h>
  12. #include "cpufreq.h"
  13. #include "helpers/helpers.h"
  14. #include "helpers/bitmask.h"
  15. #define LINE_LEN 10
  16. static unsigned int count_cpus(void)
  17. {
  18. FILE *fp;
  19. char value[LINE_LEN];
  20. unsigned int ret = 0;
  21. unsigned int cpunr = 0;
  22. fp = fopen("/proc/stat", "r");
  23. if (!fp) {
  24. printf(_("Couldn't count the number of CPUs (%s: %s), assuming 1\n"), "/proc/stat", strerror(errno));
  25. return 1;
  26. }
  27. while (!feof(fp)) {
  28. if (!fgets(value, LINE_LEN, fp))
  29. continue;
  30. value[LINE_LEN - 1] = '\0';
  31. if (strlen(value) < (LINE_LEN - 2))
  32. continue;
  33. if (strstr(value, "cpu "))
  34. continue;
  35. if (sscanf(value, "cpu%d ", &cpunr) != 1)
  36. continue;
  37. if (cpunr > ret)
  38. ret = cpunr;
  39. }
  40. fclose(fp);
  41. /* cpu count starts from 0, on error return 1 (UP) */
  42. return ret + 1;
  43. }
  44. static void proc_cpufreq_output(void)
  45. {
  46. unsigned int cpu, nr_cpus;
  47. struct cpufreq_policy *policy;
  48. unsigned int min_pctg = 0;
  49. unsigned int max_pctg = 0;
  50. unsigned long min, max;
  51. printf(_(" minimum CPU frequency - maximum CPU frequency - governor\n"));
  52. nr_cpus = count_cpus();
  53. for (cpu = 0; cpu < nr_cpus; cpu++) {
  54. policy = cpufreq_get_policy(cpu);
  55. if (!policy)
  56. continue;
  57. if (cpufreq_get_hardware_limits(cpu, &min, &max)) {
  58. max = 0;
  59. } else {
  60. min_pctg = (policy->min * 100) / max;
  61. max_pctg = (policy->max * 100) / max;
  62. }
  63. printf("CPU%3d %9lu kHz (%3d %%) - %9lu kHz (%3d %%) - %s\n",
  64. cpu , policy->min, max ? min_pctg : 0, policy->max,
  65. max ? max_pctg : 0, policy->governor);
  66. cpufreq_put_policy(policy);
  67. }
  68. }
  69. static int no_rounding;
  70. static void print_speed(unsigned long speed)
  71. {
  72. unsigned long tmp;
  73. if (no_rounding) {
  74. if (speed > 1000000)
  75. printf("%u.%06u GHz", ((unsigned int) speed/1000000),
  76. ((unsigned int) speed%1000000));
  77. else if (speed > 100000)
  78. printf("%u MHz", (unsigned int) speed);
  79. else if (speed > 1000)
  80. printf("%u.%03u MHz", ((unsigned int) speed/1000),
  81. (unsigned int) (speed%1000));
  82. else
  83. printf("%lu kHz", speed);
  84. } else {
  85. if (speed > 1000000) {
  86. tmp = speed%10000;
  87. if (tmp >= 5000)
  88. speed += 10000;
  89. printf("%u.%02u GHz", ((unsigned int) speed/1000000),
  90. ((unsigned int) (speed%1000000)/10000));
  91. } else if (speed > 100000) {
  92. tmp = speed%1000;
  93. if (tmp >= 500)
  94. speed += 1000;
  95. printf("%u MHz", ((unsigned int) speed/1000));
  96. } else if (speed > 1000) {
  97. tmp = speed%100;
  98. if (tmp >= 50)
  99. speed += 100;
  100. printf("%u.%01u MHz", ((unsigned int) speed/1000),
  101. ((unsigned int) (speed%1000)/100));
  102. }
  103. }
  104. return;
  105. }
  106. static void print_duration(unsigned long duration)
  107. {
  108. unsigned long tmp;
  109. if (no_rounding) {
  110. if (duration > 1000000)
  111. printf("%u.%06u ms", ((unsigned int) duration/1000000),
  112. ((unsigned int) duration%1000000));
  113. else if (duration > 100000)
  114. printf("%u us", ((unsigned int) duration/1000));
  115. else if (duration > 1000)
  116. printf("%u.%03u us", ((unsigned int) duration/1000),
  117. ((unsigned int) duration%1000));
  118. else
  119. printf("%lu ns", duration);
  120. } else {
  121. if (duration > 1000000) {
  122. tmp = duration%10000;
  123. if (tmp >= 5000)
  124. duration += 10000;
  125. printf("%u.%02u ms", ((unsigned int) duration/1000000),
  126. ((unsigned int) (duration%1000000)/10000));
  127. } else if (duration > 100000) {
  128. tmp = duration%1000;
  129. if (tmp >= 500)
  130. duration += 1000;
  131. printf("%u us", ((unsigned int) duration / 1000));
  132. } else if (duration > 1000) {
  133. tmp = duration%100;
  134. if (tmp >= 50)
  135. duration += 100;
  136. printf("%u.%01u us", ((unsigned int) duration/1000),
  137. ((unsigned int) (duration%1000)/100));
  138. } else
  139. printf("%lu ns", duration);
  140. }
  141. return;
  142. }
  143. /* --boost / -b */
  144. static int get_boost_mode(unsigned int cpu)
  145. {
  146. int support, active, b_states = 0, ret, pstate_no, i;
  147. /* ToDo: Make this more global */
  148. unsigned long pstates[MAX_HW_PSTATES] = {0,};
  149. if (cpupower_cpu_info.vendor != X86_VENDOR_AMD &&
  150. cpupower_cpu_info.vendor != X86_VENDOR_INTEL)
  151. return 0;
  152. ret = cpufreq_has_boost_support(cpu, &support, &active, &b_states);
  153. if (ret) {
  154. printf(_("Error while evaluating Boost Capabilities"
  155. " on CPU %d -- are you root?\n"), cpu);
  156. return ret;
  157. }
  158. /* P state changes via MSR are identified via cpuid 80000007
  159. on Intel and AMD, but we assume boost capable machines can do that
  160. if (cpuid_eax(0x80000000) >= 0x80000007
  161. && (cpuid_edx(0x80000007) & (1 << 7)))
  162. */
  163. printf(_(" boost state support:\n"));
  164. printf(_(" Supported: %s\n"), support ? _("yes") : _("no"));
  165. printf(_(" Active: %s\n"), active ? _("yes") : _("no"));
  166. if (cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
  167. cpupower_cpu_info.family >= 0x10) {
  168. ret = decode_pstates(cpu, cpupower_cpu_info.family, b_states,
  169. pstates, &pstate_no);
  170. if (ret)
  171. return ret;
  172. printf(_(" Boost States: %d\n"), b_states);
  173. printf(_(" Total States: %d\n"), pstate_no);
  174. for (i = 0; i < pstate_no; i++) {
  175. if (i < b_states)
  176. printf(_(" Pstate-Pb%d: %luMHz (boost state)"
  177. "\n"), i, pstates[i]);
  178. else
  179. printf(_(" Pstate-P%d: %luMHz\n"),
  180. i - b_states, pstates[i]);
  181. }
  182. } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_HAS_TURBO_RATIO) {
  183. double bclk;
  184. unsigned long long intel_turbo_ratio = 0;
  185. unsigned int ratio;
  186. /* Any way to autodetect this ? */
  187. if (cpupower_cpu_info.caps & CPUPOWER_CAP_IS_SNB)
  188. bclk = 100.00;
  189. else
  190. bclk = 133.33;
  191. intel_turbo_ratio = msr_intel_get_turbo_ratio(cpu);
  192. dprint (" Ratio: 0x%llx - bclk: %f\n",
  193. intel_turbo_ratio, bclk);
  194. ratio = (intel_turbo_ratio >> 24) & 0xFF;
  195. if (ratio)
  196. printf(_(" %.0f MHz max turbo 4 active cores\n"),
  197. ratio * bclk);
  198. ratio = (intel_turbo_ratio >> 16) & 0xFF;
  199. if (ratio)
  200. printf(_(" %.0f MHz max turbo 3 active cores\n"),
  201. ratio * bclk);
  202. ratio = (intel_turbo_ratio >> 8) & 0xFF;
  203. if (ratio)
  204. printf(_(" %.0f MHz max turbo 2 active cores\n"),
  205. ratio * bclk);
  206. ratio = (intel_turbo_ratio >> 0) & 0xFF;
  207. if (ratio)
  208. printf(_(" %.0f MHz max turbo 1 active cores\n"),
  209. ratio * bclk);
  210. }
  211. return 0;
  212. }
  213. static void debug_output_one(unsigned int cpu)
  214. {
  215. char *driver;
  216. struct cpufreq_affected_cpus *cpus;
  217. struct cpufreq_available_frequencies *freqs;
  218. unsigned long min, max, freq_kernel, freq_hardware;
  219. unsigned long total_trans, latency;
  220. unsigned long long total_time;
  221. struct cpufreq_policy *policy;
  222. struct cpufreq_available_governors *governors;
  223. struct cpufreq_stats *stats;
  224. if (cpufreq_cpu_exists(cpu))
  225. return;
  226. freq_kernel = cpufreq_get_freq_kernel(cpu);
  227. freq_hardware = cpufreq_get_freq_hardware(cpu);
  228. driver = cpufreq_get_driver(cpu);
  229. if (!driver) {
  230. printf(_(" no or unknown cpufreq driver is active on this CPU\n"));
  231. } else {
  232. printf(_(" driver: %s\n"), driver);
  233. cpufreq_put_driver(driver);
  234. }
  235. cpus = cpufreq_get_related_cpus(cpu);
  236. if (cpus) {
  237. printf(_(" CPUs which run at the same hardware frequency: "));
  238. while (cpus->next) {
  239. printf("%d ", cpus->cpu);
  240. cpus = cpus->next;
  241. }
  242. printf("%d\n", cpus->cpu);
  243. cpufreq_put_related_cpus(cpus);
  244. }
  245. cpus = cpufreq_get_affected_cpus(cpu);
  246. if (cpus) {
  247. printf(_(" CPUs which need to have their frequency coordinated by software: "));
  248. while (cpus->next) {
  249. printf("%d ", cpus->cpu);
  250. cpus = cpus->next;
  251. }
  252. printf("%d\n", cpus->cpu);
  253. cpufreq_put_affected_cpus(cpus);
  254. }
  255. latency = cpufreq_get_transition_latency(cpu);
  256. if (latency) {
  257. printf(_(" maximum transition latency: "));
  258. print_duration(latency);
  259. printf(".\n");
  260. }
  261. if (!(cpufreq_get_hardware_limits(cpu, &min, &max))) {
  262. printf(_(" hardware limits: "));
  263. print_speed(min);
  264. printf(" - ");
  265. print_speed(max);
  266. printf("\n");
  267. }
  268. freqs = cpufreq_get_available_frequencies(cpu);
  269. if (freqs) {
  270. printf(_(" available frequency steps: "));
  271. while (freqs->next) {
  272. print_speed(freqs->frequency);
  273. printf(", ");
  274. freqs = freqs->next;
  275. }
  276. print_speed(freqs->frequency);
  277. printf("\n");
  278. cpufreq_put_available_frequencies(freqs);
  279. }
  280. governors = cpufreq_get_available_governors(cpu);
  281. if (governors) {
  282. printf(_(" available cpufreq governors: "));
  283. while (governors->next) {
  284. printf("%s, ", governors->governor);
  285. governors = governors->next;
  286. }
  287. printf("%s\n", governors->governor);
  288. cpufreq_put_available_governors(governors);
  289. }
  290. policy = cpufreq_get_policy(cpu);
  291. if (policy) {
  292. printf(_(" current policy: frequency should be within "));
  293. print_speed(policy->min);
  294. printf(_(" and "));
  295. print_speed(policy->max);
  296. printf(".\n ");
  297. printf(_("The governor \"%s\" may"
  298. " decide which speed to use\n within this range.\n"),
  299. policy->governor);
  300. cpufreq_put_policy(policy);
  301. }
  302. if (freq_kernel || freq_hardware) {
  303. printf(_(" current CPU frequency is "));
  304. if (freq_hardware) {
  305. print_speed(freq_hardware);
  306. printf(_(" (asserted by call to hardware)"));
  307. } else
  308. print_speed(freq_kernel);
  309. printf(".\n");
  310. }
  311. stats = cpufreq_get_stats(cpu, &total_time);
  312. if (stats) {
  313. printf(_(" cpufreq stats: "));
  314. while (stats) {
  315. print_speed(stats->frequency);
  316. printf(":%.2f%%", (100.0 * stats->time_in_state) / total_time);
  317. stats = stats->next;
  318. if (stats)
  319. printf(", ");
  320. }
  321. cpufreq_put_stats(stats);
  322. total_trans = cpufreq_get_transitions(cpu);
  323. if (total_trans)
  324. printf(" (%lu)\n", total_trans);
  325. else
  326. printf("\n");
  327. }
  328. get_boost_mode(cpu);
  329. }
  330. /* --freq / -f */
  331. static int get_freq_kernel(unsigned int cpu, unsigned int human)
  332. {
  333. unsigned long freq = cpufreq_get_freq_kernel(cpu);
  334. if (!freq)
  335. return -EINVAL;
  336. if (human) {
  337. print_speed(freq);
  338. printf("\n");
  339. } else
  340. printf("%lu\n", freq);
  341. return 0;
  342. }
  343. /* --hwfreq / -w */
  344. static int get_freq_hardware(unsigned int cpu, unsigned int human)
  345. {
  346. unsigned long freq = cpufreq_get_freq_hardware(cpu);
  347. if (!freq)
  348. return -EINVAL;
  349. if (human) {
  350. print_speed(freq);
  351. printf("\n");
  352. } else
  353. printf("%lu\n", freq);
  354. return 0;
  355. }
  356. /* --hwlimits / -l */
  357. static int get_hardware_limits(unsigned int cpu)
  358. {
  359. unsigned long min, max;
  360. if (cpufreq_get_hardware_limits(cpu, &min, &max))
  361. return -EINVAL;
  362. printf("%lu %lu\n", min, max);
  363. return 0;
  364. }
  365. /* --driver / -d */
  366. static int get_driver(unsigned int cpu)
  367. {
  368. char *driver = cpufreq_get_driver(cpu);
  369. if (!driver)
  370. return -EINVAL;
  371. printf("%s\n", driver);
  372. cpufreq_put_driver(driver);
  373. return 0;
  374. }
  375. /* --policy / -p */
  376. static int get_policy(unsigned int cpu)
  377. {
  378. struct cpufreq_policy *policy = cpufreq_get_policy(cpu);
  379. if (!policy)
  380. return -EINVAL;
  381. printf("%lu %lu %s\n", policy->min, policy->max, policy->governor);
  382. cpufreq_put_policy(policy);
  383. return 0;
  384. }
  385. /* --governors / -g */
  386. static int get_available_governors(unsigned int cpu)
  387. {
  388. struct cpufreq_available_governors *governors =
  389. cpufreq_get_available_governors(cpu);
  390. if (!governors)
  391. return -EINVAL;
  392. while (governors->next) {
  393. printf("%s ", governors->governor);
  394. governors = governors->next;
  395. }
  396. printf("%s\n", governors->governor);
  397. cpufreq_put_available_governors(governors);
  398. return 0;
  399. }
  400. /* --affected-cpus / -a */
  401. static int get_affected_cpus(unsigned int cpu)
  402. {
  403. struct cpufreq_affected_cpus *cpus = cpufreq_get_affected_cpus(cpu);
  404. if (!cpus)
  405. return -EINVAL;
  406. while (cpus->next) {
  407. printf("%d ", cpus->cpu);
  408. cpus = cpus->next;
  409. }
  410. printf("%d\n", cpus->cpu);
  411. cpufreq_put_affected_cpus(cpus);
  412. return 0;
  413. }
  414. /* --related-cpus / -r */
  415. static int get_related_cpus(unsigned int cpu)
  416. {
  417. struct cpufreq_affected_cpus *cpus = cpufreq_get_related_cpus(cpu);
  418. if (!cpus)
  419. return -EINVAL;
  420. while (cpus->next) {
  421. printf("%d ", cpus->cpu);
  422. cpus = cpus->next;
  423. }
  424. printf("%d\n", cpus->cpu);
  425. cpufreq_put_related_cpus(cpus);
  426. return 0;
  427. }
  428. /* --stats / -s */
  429. static int get_freq_stats(unsigned int cpu, unsigned int human)
  430. {
  431. unsigned long total_trans = cpufreq_get_transitions(cpu);
  432. unsigned long long total_time;
  433. struct cpufreq_stats *stats = cpufreq_get_stats(cpu, &total_time);
  434. while (stats) {
  435. if (human) {
  436. print_speed(stats->frequency);
  437. printf(":%.2f%%",
  438. (100.0 * stats->time_in_state) / total_time);
  439. } else
  440. printf("%lu:%llu",
  441. stats->frequency, stats->time_in_state);
  442. stats = stats->next;
  443. if (stats)
  444. printf(", ");
  445. }
  446. cpufreq_put_stats(stats);
  447. if (total_trans)
  448. printf(" (%lu)\n", total_trans);
  449. return 0;
  450. }
  451. /* --latency / -y */
  452. static int get_latency(unsigned int cpu, unsigned int human)
  453. {
  454. unsigned long latency = cpufreq_get_transition_latency(cpu);
  455. if (!latency)
  456. return -EINVAL;
  457. if (human) {
  458. print_duration(latency);
  459. printf("\n");
  460. } else
  461. printf("%lu\n", latency);
  462. return 0;
  463. }
  464. static struct option info_opts[] = {
  465. { .name = "debug", .has_arg = no_argument, .flag = NULL, .val = 'e'},
  466. { .name = "boost", .has_arg = no_argument, .flag = NULL, .val = 'b'},
  467. { .name = "freq", .has_arg = no_argument, .flag = NULL, .val = 'f'},
  468. { .name = "hwfreq", .has_arg = no_argument, .flag = NULL, .val = 'w'},
  469. { .name = "hwlimits", .has_arg = no_argument, .flag = NULL, .val = 'l'},
  470. { .name = "driver", .has_arg = no_argument, .flag = NULL, .val = 'd'},
  471. { .name = "policy", .has_arg = no_argument, .flag = NULL, .val = 'p'},
  472. { .name = "governors", .has_arg = no_argument, .flag = NULL, .val = 'g'},
  473. { .name = "related-cpus", .has_arg = no_argument, .flag = NULL, .val = 'r'},
  474. { .name = "affected-cpus",.has_arg = no_argument, .flag = NULL, .val = 'a'},
  475. { .name = "stats", .has_arg = no_argument, .flag = NULL, .val = 's'},
  476. { .name = "latency", .has_arg = no_argument, .flag = NULL, .val = 'y'},
  477. { .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'},
  478. { .name = "human", .has_arg = no_argument, .flag = NULL, .val = 'm'},
  479. { .name = "no-rounding", .has_arg = no_argument, .flag = NULL, .val = 'n'},
  480. { },
  481. };
  482. int cmd_freq_info(int argc, char **argv)
  483. {
  484. extern char *optarg;
  485. extern int optind, opterr, optopt;
  486. int ret = 0, cont = 1;
  487. unsigned int cpu = 0;
  488. unsigned int human = 0;
  489. int output_param = 0;
  490. do {
  491. ret = getopt_long(argc, argv, "oefwldpgrasmybn", info_opts,
  492. NULL);
  493. switch (ret) {
  494. case '?':
  495. output_param = '?';
  496. cont = 0;
  497. break;
  498. case -1:
  499. cont = 0;
  500. break;
  501. case 'b':
  502. case 'o':
  503. case 'a':
  504. case 'r':
  505. case 'g':
  506. case 'p':
  507. case 'd':
  508. case 'l':
  509. case 'w':
  510. case 'f':
  511. case 'e':
  512. case 's':
  513. case 'y':
  514. if (output_param) {
  515. output_param = -1;
  516. cont = 0;
  517. break;
  518. }
  519. output_param = ret;
  520. break;
  521. case 'm':
  522. if (human) {
  523. output_param = -1;
  524. cont = 0;
  525. break;
  526. }
  527. human = 1;
  528. break;
  529. case 'n':
  530. no_rounding = 1;
  531. break;
  532. default:
  533. fprintf(stderr, "invalid or unknown argument\n");
  534. return EXIT_FAILURE;
  535. }
  536. } while (cont);
  537. switch (output_param) {
  538. case 'o':
  539. if (!bitmask_isallclear(cpus_chosen)) {
  540. printf(_("The argument passed to this tool can't be "
  541. "combined with passing a --cpu argument\n"));
  542. return -EINVAL;
  543. }
  544. break;
  545. case 0:
  546. output_param = 'e';
  547. }
  548. ret = 0;
  549. /* Default is: show output of CPU 0 only */
  550. if (bitmask_isallclear(cpus_chosen))
  551. bitmask_setbit(cpus_chosen, 0);
  552. switch (output_param) {
  553. case -1:
  554. printf(_("You can't specify more than one --cpu parameter and/or\n"
  555. "more than one output-specific argument\n"));
  556. return -EINVAL;
  557. case '?':
  558. printf(_("invalid or unknown argument\n"));
  559. return -EINVAL;
  560. case 'o':
  561. proc_cpufreq_output();
  562. return EXIT_SUCCESS;
  563. }
  564. for (cpu = bitmask_first(cpus_chosen);
  565. cpu <= bitmask_last(cpus_chosen); cpu++) {
  566. if (!bitmask_isbitset(cpus_chosen, cpu))
  567. continue;
  568. if (cpufreq_cpu_exists(cpu)) {
  569. printf(_("couldn't analyze CPU %d as it doesn't seem to be present\n"), cpu);
  570. continue;
  571. }
  572. printf(_("analyzing CPU %d:\n"), cpu);
  573. switch (output_param) {
  574. case 'b':
  575. get_boost_mode(cpu);
  576. break;
  577. case 'e':
  578. debug_output_one(cpu);
  579. break;
  580. case 'a':
  581. ret = get_affected_cpus(cpu);
  582. break;
  583. case 'r':
  584. ret = get_related_cpus(cpu);
  585. break;
  586. case 'g':
  587. ret = get_available_governors(cpu);
  588. break;
  589. case 'p':
  590. ret = get_policy(cpu);
  591. break;
  592. case 'd':
  593. ret = get_driver(cpu);
  594. break;
  595. case 'l':
  596. ret = get_hardware_limits(cpu);
  597. break;
  598. case 'w':
  599. ret = get_freq_hardware(cpu, human);
  600. break;
  601. case 'f':
  602. ret = get_freq_kernel(cpu, human);
  603. break;
  604. case 's':
  605. ret = get_freq_stats(cpu, human);
  606. break;
  607. case 'y':
  608. ret = get_latency(cpu, human);
  609. break;
  610. }
  611. if (ret)
  612. return ret;
  613. }
  614. return ret;
  615. }