1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
11 #include <rte_cycles.h>
18 test_power_cpufreq(void)
20 printf("Power management library not supported, skipping test\n");
27 printf("Power management library not supported, skipping test\n");
32 #include <rte_power.h>
34 #define TEST_POWER_LCORE_ID 2U
35 #define TEST_POWER_LCORE_INVALID ((unsigned)RTE_MAX_LCORE)
36 #define TEST_POWER_FREQS_NUM_MAX ((unsigned)RTE_MAX_LCORE_FREQS)
38 /* macros used for rounding frequency to nearest 100000 */
39 #define TEST_FREQ_ROUNDING_DELTA 50000
40 #define TEST_ROUND_FREQ_TO_N_100000 100000
42 #define TEST_POWER_SYSFILE_CUR_FREQ \
43 "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_cur_freq"
45 static uint32_t total_freq_num;
46 static uint32_t freqs[TEST_POWER_FREQS_NUM_MAX];
49 check_cur_freq(unsigned lcore_id, uint32_t idx)
51 #define TEST_POWER_CONVERT_TO_DECIMAL 10
54 char fullpath[PATH_MAX];
60 if (snprintf(fullpath, sizeof(fullpath),
61 TEST_POWER_SYSFILE_CUR_FREQ, lcore_id) < 0) {
64 f = fopen(fullpath, "r");
68 for (i = 0; i < MAX_LOOP; i++) {
70 if (fgets(buf, sizeof(buf), f) == NULL)
73 cur_freq = strtoul(buf, NULL, TEST_POWER_CONVERT_TO_DECIMAL);
75 /* convert the frequency to nearest 100000 value
76 * Ex: if cur_freq=1396789 then freq_conv=1400000
77 * Ex: if cur_freq=800030 then freq_conv=800000
79 unsigned int freq_conv = 0;
80 freq_conv = (cur_freq + TEST_FREQ_ROUNDING_DELTA)
81 / TEST_ROUND_FREQ_TO_N_100000;
82 freq_conv = freq_conv * TEST_ROUND_FREQ_TO_N_100000;
84 ret = (freqs[idx] == freq_conv ? 0 : -1);
89 if (fseek(f, 0, SEEK_SET) < 0) {
90 printf("Fail to set file position indicator to 0\n");
94 /* wait for the value to be updated */
104 /* Check rte_power_freqs() */
106 check_power_freqs(void)
111 memset(freqs, 0, sizeof(freqs));
113 /* test with an invalid lcore id */
114 ret = rte_power_freqs(TEST_POWER_LCORE_INVALID, freqs,
115 TEST_POWER_FREQS_NUM_MAX);
117 printf("Unexpectedly get available freqs successfully on "
118 "lcore %u\n", TEST_POWER_LCORE_INVALID);
122 /* test with NULL buffer to save available freqs */
123 ret = rte_power_freqs(TEST_POWER_LCORE_ID, NULL,
124 TEST_POWER_FREQS_NUM_MAX);
126 printf("Unexpectedly get available freqs successfully with "
127 "NULL buffer on lcore %u\n", TEST_POWER_LCORE_ID);
131 /* test of getting zero number of freqs */
132 ret = rte_power_freqs(TEST_POWER_LCORE_ID, freqs, 0);
134 printf("Unexpectedly get available freqs successfully with "
135 "zero buffer size on lcore %u\n", TEST_POWER_LCORE_ID);
139 /* test with all valid input parameters */
140 ret = rte_power_freqs(TEST_POWER_LCORE_ID, freqs,
141 TEST_POWER_FREQS_NUM_MAX);
142 if (ret == 0 || ret > TEST_POWER_FREQS_NUM_MAX) {
143 printf("Fail to get available freqs on lcore %u\n",
144 TEST_POWER_LCORE_ID);
148 /* Save the total number of available freqs */
149 total_freq_num = ret;
154 /* Check rte_power_get_freq() */
156 check_power_get_freq(void)
161 /* test with an invalid lcore id */
162 count = rte_power_get_freq(TEST_POWER_LCORE_INVALID);
163 if (count < TEST_POWER_FREQS_NUM_MAX) {
164 printf("Unexpectedly get freq index successfully on "
165 "lcore %u\n", TEST_POWER_LCORE_INVALID);
169 count = rte_power_get_freq(TEST_POWER_LCORE_ID);
170 if (count >= TEST_POWER_FREQS_NUM_MAX) {
171 printf("Fail to get the freq index on lcore %u\n",
172 TEST_POWER_LCORE_ID);
176 /* Check the current frequency */
177 ret = check_cur_freq(TEST_POWER_LCORE_ID, count);
184 /* Check rte_power_set_freq() */
186 check_power_set_freq(void)
190 /* test with an invalid lcore id */
191 ret = rte_power_set_freq(TEST_POWER_LCORE_INVALID, 0);
193 printf("Unexpectedly set freq index successfully on "
194 "lcore %u\n", TEST_POWER_LCORE_INVALID);
198 /* test with an invalid freq index */
199 ret = rte_power_set_freq(TEST_POWER_LCORE_ID,
200 TEST_POWER_FREQS_NUM_MAX);
202 printf("Unexpectedly set an invalid freq index (%u)"
203 "successfully on lcore %u\n", TEST_POWER_FREQS_NUM_MAX,
204 TEST_POWER_LCORE_ID);
209 * test with an invalid freq index which is right one bigger than
210 * total number of freqs
212 ret = rte_power_set_freq(TEST_POWER_LCORE_ID, total_freq_num);
214 printf("Unexpectedly set an invalid freq index (%u)"
215 "successfully on lcore %u\n", total_freq_num,
216 TEST_POWER_LCORE_ID);
219 ret = rte_power_set_freq(TEST_POWER_LCORE_ID, total_freq_num - 1);
221 printf("Fail to set freq index on lcore %u\n",
222 TEST_POWER_LCORE_ID);
226 /* Check the current frequency */
227 ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1);
234 /* Check rte_power_freq_down() */
236 check_power_freq_down(void)
240 /* test with an invalid lcore id */
241 ret = rte_power_freq_down(TEST_POWER_LCORE_INVALID);
243 printf("Unexpectedly scale down successfully the freq on "
244 "lcore %u\n", TEST_POWER_LCORE_INVALID);
248 /* Scale down to min and then scale down one step */
249 ret = rte_power_freq_min(TEST_POWER_LCORE_ID);
251 printf("Fail to scale down the freq to min on lcore %u\n",
252 TEST_POWER_LCORE_ID);
255 ret = rte_power_freq_down(TEST_POWER_LCORE_ID);
257 printf("Fail to scale down the freq on lcore %u\n",
258 TEST_POWER_LCORE_ID);
262 /* Check the current frequency */
263 ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1);
267 /* Scale up to max and then scale down one step */
268 ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
270 printf("Fail to scale up the freq to max on lcore %u\n",
271 TEST_POWER_LCORE_ID);
274 ret = rte_power_freq_down(TEST_POWER_LCORE_ID);
276 printf("Fail to scale down the freq on lcore %u\n",
277 TEST_POWER_LCORE_ID);
281 /* Check the current frequency */
282 ret = check_cur_freq(TEST_POWER_LCORE_ID, 1);
289 /* Check rte_power_freq_up() */
291 check_power_freq_up(void)
295 /* test with an invalid lcore id */
296 ret = rte_power_freq_up(TEST_POWER_LCORE_INVALID);
298 printf("Unexpectedly scale up successfully the freq on %u\n",
299 TEST_POWER_LCORE_INVALID);
303 /* Scale down to min and then scale up one step */
304 ret = rte_power_freq_min(TEST_POWER_LCORE_ID);
306 printf("Fail to scale down the freq to min on lcore %u\n",
307 TEST_POWER_LCORE_ID);
310 ret = rte_power_freq_up(TEST_POWER_LCORE_ID);
312 printf("Fail to scale up the freq on lcore %u\n",
313 TEST_POWER_LCORE_ID);
317 /* Check the current frequency */
318 ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 2);
322 /* Scale up to max and then scale up one step */
323 ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
325 printf("Fail to scale up the freq to max on lcore %u\n",
326 TEST_POWER_LCORE_ID);
329 ret = rte_power_freq_up(TEST_POWER_LCORE_ID);
331 printf("Fail to scale up the freq on lcore %u\n",
332 TEST_POWER_LCORE_ID);
336 /* Check the current frequency */
337 ret = check_cur_freq(TEST_POWER_LCORE_ID, 0);
344 /* Check rte_power_freq_max() */
346 check_power_freq_max(void)
350 /* test with an invalid lcore id */
351 ret = rte_power_freq_max(TEST_POWER_LCORE_INVALID);
353 printf("Unexpectedly scale up successfully the freq to max on "
354 "lcore %u\n", TEST_POWER_LCORE_INVALID);
357 ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
359 printf("Fail to scale up the freq to max on lcore %u\n",
360 TEST_POWER_LCORE_ID);
364 /* Check the current frequency */
365 ret = check_cur_freq(TEST_POWER_LCORE_ID, 0);
372 /* Check rte_power_freq_min() */
374 check_power_freq_min(void)
378 /* test with an invalid lcore id */
379 ret = rte_power_freq_min(TEST_POWER_LCORE_INVALID);
381 printf("Unexpectedly scale down successfully the freq to min "
382 "on lcore %u\n", TEST_POWER_LCORE_INVALID);
385 ret = rte_power_freq_min(TEST_POWER_LCORE_ID);
387 printf("Fail to scale down the freq to min on lcore %u\n",
388 TEST_POWER_LCORE_ID);
392 /* Check the current frequency */
393 ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1);
400 /* Check rte_power_turbo() */
402 check_power_turbo(void)
406 if (rte_power_turbo_status(TEST_POWER_LCORE_ID) == 0) {
407 printf("Turbo not available on lcore %u, skipping test\n",
408 TEST_POWER_LCORE_ID);
412 /* test with an invalid lcore id */
413 ret = rte_power_freq_enable_turbo(TEST_POWER_LCORE_INVALID);
415 printf("Unexpectedly enable turbo successfully on lcore %u\n",
416 TEST_POWER_LCORE_INVALID);
419 ret = rte_power_freq_enable_turbo(TEST_POWER_LCORE_ID);
421 printf("Fail to enable turbo on lcore %u\n",
422 TEST_POWER_LCORE_ID);
426 /* Check the current frequency */
427 ret = check_cur_freq(TEST_POWER_LCORE_ID, 0);
431 /* test with an invalid lcore id */
432 ret = rte_power_freq_disable_turbo(TEST_POWER_LCORE_INVALID);
434 printf("Unexpectedly disable turbo successfully on lcore %u\n",
435 TEST_POWER_LCORE_INVALID);
438 ret = rte_power_freq_disable_turbo(TEST_POWER_LCORE_ID);
440 printf("Fail to disable turbo on lcore %u\n",
441 TEST_POWER_LCORE_ID);
445 /* Check the current frequency */
446 ret = check_cur_freq(TEST_POWER_LCORE_ID, 1);
454 test_power_cpufreq(void)
457 enum power_management_env env;
459 /* Test initialisation of a valid lcore */
460 ret = rte_power_init(TEST_POWER_LCORE_ID);
462 printf("Cannot initialise power management for lcore %u, this "
463 "may occur if environment is not configured "
464 "correctly(APCI cpufreq) or operating in another valid "
465 "Power management environment\n",
466 TEST_POWER_LCORE_ID);
467 rte_power_unset_env();
471 /* Test environment configuration */
472 env = rte_power_get_env();
473 if ((env != PM_ENV_ACPI_CPUFREQ) && (env != PM_ENV_PSTATE_CPUFREQ)) {
474 printf("Unexpectedly got an environment other than ACPI/PSTATE\n");
478 /* verify that function pointers are not NULL */
479 if (rte_power_freqs == NULL) {
480 printf("rte_power_freqs should not be NULL, environment has not been "
484 if (rte_power_get_freq == NULL) {
485 printf("rte_power_get_freq should not be NULL, environment has not "
486 "been initialised\n");
489 if (rte_power_set_freq == NULL) {
490 printf("rte_power_set_freq should not be NULL, environment has not "
491 "been initialised\n");
494 if (rte_power_freq_up == NULL) {
495 printf("rte_power_freq_up should not be NULL, environment has not "
496 "been initialised\n");
499 if (rte_power_freq_down == NULL) {
500 printf("rte_power_freq_down should not be NULL, environment has not "
501 "been initialised\n");
504 if (rte_power_freq_max == NULL) {
505 printf("rte_power_freq_max should not be NULL, environment has not "
506 "been initialised\n");
509 if (rte_power_freq_min == NULL) {
510 printf("rte_power_freq_min should not be NULL, environment has not "
511 "been initialised\n");
514 if (rte_power_turbo_status == NULL) {
515 printf("rte_power_turbo_status should not be NULL, environment has not "
516 "been initialised\n");
519 if (rte_power_freq_enable_turbo == NULL) {
520 printf("rte_power_freq_enable_turbo should not be NULL, environment has not "
521 "been initialised\n");
524 if (rte_power_freq_disable_turbo == NULL) {
525 printf("rte_power_freq_disable_turbo should not be NULL, environment has not "
526 "been initialised\n");
530 ret = rte_power_exit(TEST_POWER_LCORE_ID);
532 printf("Cannot exit power management for lcore %u\n",
533 TEST_POWER_LCORE_ID);
534 rte_power_unset_env();
538 /* test of init power management for an invalid lcore */
539 ret = rte_power_init(TEST_POWER_LCORE_INVALID);
541 printf("Unexpectedly initialise power management successfully "
542 "for lcore %u\n", TEST_POWER_LCORE_INVALID);
543 rte_power_unset_env();
547 /* Test initialisation of a valid lcore */
548 ret = rte_power_init(TEST_POWER_LCORE_ID);
550 printf("Cannot initialise power management for lcore %u, this "
551 "may occur if environment is not configured "
552 "correctly(APCI cpufreq) or operating in another valid "
553 "Power management environment\n", TEST_POWER_LCORE_ID);
554 rte_power_unset_env();
559 * test of initialising power management for the lcore which has
562 ret = rte_power_init(TEST_POWER_LCORE_ID);
564 printf("Unexpectedly init successfully power twice on "
565 "lcore %u\n", TEST_POWER_LCORE_ID);
569 ret = check_power_freqs();
573 if (total_freq_num < 2) {
574 rte_power_exit(TEST_POWER_LCORE_ID);
575 printf("Frequency can not be changed due to CPU itself\n");
576 rte_power_unset_env();
580 ret = check_power_get_freq();
584 ret = check_power_set_freq();
588 ret = check_power_freq_down();
592 ret = check_power_freq_up();
596 ret = check_power_freq_max();
600 ret = check_power_freq_min();
604 ret = check_power_turbo();
608 ret = rte_power_exit(TEST_POWER_LCORE_ID);
610 printf("Cannot exit power management for lcore %u\n",
611 TEST_POWER_LCORE_ID);
612 rte_power_unset_env();
617 * test of exiting power management for the lcore which has been exited
619 ret = rte_power_exit(TEST_POWER_LCORE_ID);
621 printf("Unexpectedly exit successfully power management twice "
622 "on lcore %u\n", TEST_POWER_LCORE_ID);
623 rte_power_unset_env();
627 /* test of exit power management for an invalid lcore */
628 ret = rte_power_exit(TEST_POWER_LCORE_INVALID);
630 printf("Unpectedly exit power management successfully for "
631 "lcore %u\n", TEST_POWER_LCORE_INVALID);
632 rte_power_unset_env();
635 rte_power_unset_env();
639 rte_power_exit(TEST_POWER_LCORE_ID);
640 rte_power_unset_env();
645 test_power_caps(void)
647 struct rte_power_core_capabilities caps;
650 ret = rte_power_init(TEST_POWER_LCORE_ID);
652 printf("Cannot initialise power management for lcore %u, this "
653 "may occur if environment is not configured "
654 "correctly(APCI cpufreq) or operating in another valid "
655 "Power management environment\n", TEST_POWER_LCORE_ID);
656 rte_power_unset_env();
660 ret = rte_power_get_capabilities(TEST_POWER_LCORE_ID, &caps);
662 printf("POWER: Error getting capabilities\n");
666 printf("POWER: Capabilities %"PRIx64"\n", caps.capabilities);
668 rte_power_unset_env();
674 REGISTER_TEST_COMMAND(power_cpufreq_autotest, test_power_cpufreq);
675 REGISTER_TEST_COMMAND(power_caps_autotest, test_power_caps);