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_CPUINFO_FREQ \
43 "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_cur_freq"
44 #define TEST_POWER_SYSFILE_SCALING_FREQ \
45 "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq"
47 static uint32_t total_freq_num;
48 static uint32_t freqs[TEST_POWER_FREQS_NUM_MAX];
51 check_cur_freq(unsigned int lcore_id, uint32_t idx, bool turbo)
53 #define TEST_POWER_CONVERT_TO_DECIMAL 10
56 char fullpath[PATH_MAX];
62 if (snprintf(fullpath, sizeof(fullpath),
63 TEST_POWER_SYSFILE_SCALING_FREQ, lcore_id) < 0) {
66 f = fopen(fullpath, "r");
68 if (snprintf(fullpath, sizeof(fullpath),
69 TEST_POWER_SYSFILE_CPUINFO_FREQ, lcore_id) < 0) {
72 f = fopen(fullpath, "r");
77 for (i = 0; i < MAX_LOOP; i++) {
79 if (fgets(buf, sizeof(buf), f) == NULL)
82 cur_freq = strtoul(buf, NULL, TEST_POWER_CONVERT_TO_DECIMAL);
84 /* convert the frequency to nearest 100000 value
85 * Ex: if cur_freq=1396789 then freq_conv=1400000
86 * Ex: if cur_freq=800030 then freq_conv=800000
88 unsigned int freq_conv = 0;
89 freq_conv = (cur_freq + TEST_FREQ_ROUNDING_DELTA)
90 / TEST_ROUND_FREQ_TO_N_100000;
91 freq_conv = freq_conv * TEST_ROUND_FREQ_TO_N_100000;
94 ret = (freqs[idx] <= freq_conv ? 0 : -1);
96 ret = (freqs[idx] == freq_conv ? 0 : -1);
101 if (fseek(f, 0, SEEK_SET) < 0) {
102 printf("Fail to set file position indicator to 0\n");
106 /* wait for the value to be updated */
116 /* Check rte_power_freqs() */
118 check_power_freqs(void)
123 memset(freqs, 0, sizeof(freqs));
125 /* test with an invalid lcore id */
126 ret = rte_power_freqs(TEST_POWER_LCORE_INVALID, freqs,
127 TEST_POWER_FREQS_NUM_MAX);
129 printf("Unexpectedly get available freqs successfully on "
130 "lcore %u\n", TEST_POWER_LCORE_INVALID);
134 /* test with NULL buffer to save available freqs */
135 ret = rte_power_freqs(TEST_POWER_LCORE_ID, NULL,
136 TEST_POWER_FREQS_NUM_MAX);
138 printf("Unexpectedly get available freqs successfully with "
139 "NULL buffer on lcore %u\n", TEST_POWER_LCORE_ID);
143 /* test of getting zero number of freqs */
144 ret = rte_power_freqs(TEST_POWER_LCORE_ID, freqs, 0);
146 printf("Unexpectedly get available freqs successfully with "
147 "zero buffer size on lcore %u\n", TEST_POWER_LCORE_ID);
151 /* test with all valid input parameters */
152 ret = rte_power_freqs(TEST_POWER_LCORE_ID, freqs,
153 TEST_POWER_FREQS_NUM_MAX);
154 if (ret == 0 || ret > TEST_POWER_FREQS_NUM_MAX) {
155 printf("Fail to get available freqs on lcore %u\n",
156 TEST_POWER_LCORE_ID);
160 /* Save the total number of available freqs */
161 total_freq_num = ret;
166 /* Check rte_power_get_freq() */
168 check_power_get_freq(void)
173 /* test with an invalid lcore id */
174 count = rte_power_get_freq(TEST_POWER_LCORE_INVALID);
175 if (count < TEST_POWER_FREQS_NUM_MAX) {
176 printf("Unexpectedly get freq index successfully on "
177 "lcore %u\n", TEST_POWER_LCORE_INVALID);
181 count = rte_power_get_freq(TEST_POWER_LCORE_ID);
182 if (count >= TEST_POWER_FREQS_NUM_MAX) {
183 printf("Fail to get the freq index on lcore %u\n",
184 TEST_POWER_LCORE_ID);
188 /* Check the current frequency */
189 ret = check_cur_freq(TEST_POWER_LCORE_ID, count, false);
196 /* Check rte_power_set_freq() */
198 check_power_set_freq(void)
202 /* test with an invalid lcore id */
203 ret = rte_power_set_freq(TEST_POWER_LCORE_INVALID, 0);
205 printf("Unexpectedly set freq index successfully on "
206 "lcore %u\n", TEST_POWER_LCORE_INVALID);
210 /* test with an invalid freq index */
211 ret = rte_power_set_freq(TEST_POWER_LCORE_ID,
212 TEST_POWER_FREQS_NUM_MAX);
214 printf("Unexpectedly set an invalid freq index (%u)"
215 "successfully on lcore %u\n", TEST_POWER_FREQS_NUM_MAX,
216 TEST_POWER_LCORE_ID);
221 * test with an invalid freq index which is right one bigger than
222 * total number of freqs
224 ret = rte_power_set_freq(TEST_POWER_LCORE_ID, total_freq_num);
226 printf("Unexpectedly set an invalid freq index (%u)"
227 "successfully on lcore %u\n", total_freq_num,
228 TEST_POWER_LCORE_ID);
231 ret = rte_power_set_freq(TEST_POWER_LCORE_ID, total_freq_num - 1);
233 printf("Fail to set freq index on lcore %u\n",
234 TEST_POWER_LCORE_ID);
238 /* Check the current frequency */
239 ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1, false);
246 /* Check rte_power_freq_down() */
248 check_power_freq_down(void)
252 rte_power_freq_enable_turbo(TEST_POWER_LCORE_ID);
254 /* test with an invalid lcore id */
255 ret = rte_power_freq_down(TEST_POWER_LCORE_INVALID);
257 printf("Unexpectedly scale down successfully the freq on "
258 "lcore %u\n", TEST_POWER_LCORE_INVALID);
262 /* Scale down to min and then scale down one step */
263 ret = rte_power_freq_min(TEST_POWER_LCORE_ID);
265 printf("Fail to scale down the freq to min on lcore %u\n",
266 TEST_POWER_LCORE_ID);
269 ret = rte_power_freq_down(TEST_POWER_LCORE_ID);
271 printf("Fail to scale down the freq on lcore %u\n",
272 TEST_POWER_LCORE_ID);
276 /* Check the current frequency */
277 ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1, false);
281 /* Scale up to max and then scale down one step */
282 ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
284 printf("Fail to scale up the freq to max on lcore %u\n",
285 TEST_POWER_LCORE_ID);
288 ret = rte_power_freq_down(TEST_POWER_LCORE_ID);
290 printf("Fail to scale down the freq on lcore %u\n",
291 TEST_POWER_LCORE_ID);
295 /* Check the current frequency */
296 ret = check_cur_freq(TEST_POWER_LCORE_ID, 1, false);
303 /* Check rte_power_freq_up() */
305 check_power_freq_up(void)
309 /* test with an invalid lcore id */
310 ret = rte_power_freq_up(TEST_POWER_LCORE_INVALID);
312 printf("Unexpectedly scale up successfully the freq on %u\n",
313 TEST_POWER_LCORE_INVALID);
317 /* Scale down to min and then scale up one step */
318 ret = rte_power_freq_min(TEST_POWER_LCORE_ID);
320 printf("Fail to scale down the freq to min on lcore %u\n",
321 TEST_POWER_LCORE_ID);
324 ret = rte_power_freq_up(TEST_POWER_LCORE_ID);
326 printf("Fail to scale up the freq on lcore %u\n",
327 TEST_POWER_LCORE_ID);
331 /* Check the current frequency */
332 ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 2, false);
336 /* Scale up to max and then scale up one step */
337 ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
339 printf("Fail to scale up the freq to max on lcore %u\n",
340 TEST_POWER_LCORE_ID);
343 ret = rte_power_freq_up(TEST_POWER_LCORE_ID);
345 printf("Fail to scale up the freq on lcore %u\n",
346 TEST_POWER_LCORE_ID);
350 /* Check the current frequency */
351 ret = check_cur_freq(TEST_POWER_LCORE_ID, 0, true);
358 /* Check rte_power_freq_max() */
360 check_power_freq_max(void)
364 /* test with an invalid lcore id */
365 ret = rte_power_freq_max(TEST_POWER_LCORE_INVALID);
367 printf("Unexpectedly scale up successfully the freq to max on "
368 "lcore %u\n", TEST_POWER_LCORE_INVALID);
371 ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
373 printf("Fail to scale up the freq to max on lcore %u\n",
374 TEST_POWER_LCORE_ID);
378 /* Check the current frequency */
379 ret = check_cur_freq(TEST_POWER_LCORE_ID, 0, true);
386 /* Check rte_power_freq_min() */
388 check_power_freq_min(void)
392 /* test with an invalid lcore id */
393 ret = rte_power_freq_min(TEST_POWER_LCORE_INVALID);
395 printf("Unexpectedly scale down successfully the freq to min "
396 "on lcore %u\n", TEST_POWER_LCORE_INVALID);
399 ret = rte_power_freq_min(TEST_POWER_LCORE_ID);
401 printf("Fail to scale down the freq to min on lcore %u\n",
402 TEST_POWER_LCORE_ID);
406 /* Check the current frequency */
407 ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1, false);
414 /* Check rte_power_turbo() */
416 check_power_turbo(void)
420 if (rte_power_turbo_status(TEST_POWER_LCORE_ID) == 0) {
421 printf("Turbo not available on lcore %u, skipping test\n",
422 TEST_POWER_LCORE_ID);
426 /* test with an invalid lcore id */
427 ret = rte_power_freq_enable_turbo(TEST_POWER_LCORE_INVALID);
429 printf("Unexpectedly enable turbo successfully on lcore %u\n",
430 TEST_POWER_LCORE_INVALID);
433 ret = rte_power_freq_enable_turbo(TEST_POWER_LCORE_ID);
435 printf("Fail to enable turbo on lcore %u\n",
436 TEST_POWER_LCORE_ID);
439 ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
441 printf("Fail to scale up the freq to max on lcore %u\n",
442 TEST_POWER_LCORE_ID);
446 /* Check the current frequency */
447 ret = check_cur_freq(TEST_POWER_LCORE_ID, 0, true);
451 /* test with an invalid lcore id */
452 ret = rte_power_freq_disable_turbo(TEST_POWER_LCORE_INVALID);
454 printf("Unexpectedly disable turbo successfully on lcore %u\n",
455 TEST_POWER_LCORE_INVALID);
458 ret = rte_power_freq_disable_turbo(TEST_POWER_LCORE_ID);
460 printf("Fail to disable turbo on lcore %u\n",
461 TEST_POWER_LCORE_ID);
464 ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
466 printf("Fail to scale up the freq to max on lcore %u\n",
467 TEST_POWER_LCORE_ID);
471 /* Check the current frequency */
472 ret = check_cur_freq(TEST_POWER_LCORE_ID, 1, false);
480 test_power_cpufreq(void)
483 enum power_management_env env;
485 /* Test initialisation of a valid lcore */
486 ret = rte_power_init(TEST_POWER_LCORE_ID);
488 printf("Cannot initialise power management for lcore %u, this "
489 "may occur if environment is not configured "
490 "correctly(APCI cpufreq) or operating in another valid "
491 "Power management environment\n",
492 TEST_POWER_LCORE_ID);
493 rte_power_unset_env();
497 /* Test environment configuration */
498 env = rte_power_get_env();
499 if ((env != PM_ENV_ACPI_CPUFREQ) && (env != PM_ENV_PSTATE_CPUFREQ)) {
500 printf("Unexpectedly got an environment other than ACPI/PSTATE\n");
504 /* verify that function pointers are not NULL */
505 if (rte_power_freqs == NULL) {
506 printf("rte_power_freqs should not be NULL, environment has not been "
510 if (rte_power_get_freq == NULL) {
511 printf("rte_power_get_freq should not be NULL, environment has not "
512 "been initialised\n");
515 if (rte_power_set_freq == NULL) {
516 printf("rte_power_set_freq should not be NULL, environment has not "
517 "been initialised\n");
520 if (rte_power_freq_up == NULL) {
521 printf("rte_power_freq_up should not be NULL, environment has not "
522 "been initialised\n");
525 if (rte_power_freq_down == NULL) {
526 printf("rte_power_freq_down should not be NULL, environment has not "
527 "been initialised\n");
530 if (rte_power_freq_max == NULL) {
531 printf("rte_power_freq_max should not be NULL, environment has not "
532 "been initialised\n");
535 if (rte_power_freq_min == NULL) {
536 printf("rte_power_freq_min should not be NULL, environment has not "
537 "been initialised\n");
540 if (rte_power_turbo_status == NULL) {
541 printf("rte_power_turbo_status should not be NULL, environment has not "
542 "been initialised\n");
545 if (rte_power_freq_enable_turbo == NULL) {
546 printf("rte_power_freq_enable_turbo should not be NULL, environment has not "
547 "been initialised\n");
550 if (rte_power_freq_disable_turbo == NULL) {
551 printf("rte_power_freq_disable_turbo should not be NULL, environment has not "
552 "been initialised\n");
556 ret = rte_power_exit(TEST_POWER_LCORE_ID);
558 printf("Cannot exit power management for lcore %u\n",
559 TEST_POWER_LCORE_ID);
560 rte_power_unset_env();
564 /* test of init power management for an invalid lcore */
565 ret = rte_power_init(TEST_POWER_LCORE_INVALID);
567 printf("Unexpectedly initialise power management successfully "
568 "for lcore %u\n", TEST_POWER_LCORE_INVALID);
569 rte_power_unset_env();
573 /* Test initialisation of a valid lcore */
574 ret = rte_power_init(TEST_POWER_LCORE_ID);
576 printf("Cannot initialise power management for lcore %u, this "
577 "may occur if environment is not configured "
578 "correctly(APCI cpufreq) or operating in another valid "
579 "Power management environment\n", TEST_POWER_LCORE_ID);
580 rte_power_unset_env();
585 * test of initialising power management for the lcore which has
588 ret = rte_power_init(TEST_POWER_LCORE_ID);
590 printf("Unexpectedly init successfully power twice on "
591 "lcore %u\n", TEST_POWER_LCORE_ID);
595 ret = check_power_freqs();
599 if (total_freq_num < 2) {
600 rte_power_exit(TEST_POWER_LCORE_ID);
601 printf("Frequency can not be changed due to CPU itself\n");
602 rte_power_unset_env();
606 ret = check_power_get_freq();
610 ret = check_power_set_freq();
614 ret = check_power_freq_down();
618 ret = check_power_freq_up();
622 ret = check_power_freq_max();
626 ret = check_power_freq_min();
630 ret = check_power_turbo();
634 ret = rte_power_exit(TEST_POWER_LCORE_ID);
636 printf("Cannot exit power management for lcore %u\n",
637 TEST_POWER_LCORE_ID);
638 rte_power_unset_env();
643 * test of exiting power management for the lcore which has been exited
645 ret = rte_power_exit(TEST_POWER_LCORE_ID);
647 printf("Unexpectedly exit successfully power management twice "
648 "on lcore %u\n", TEST_POWER_LCORE_ID);
649 rte_power_unset_env();
653 /* test of exit power management for an invalid lcore */
654 ret = rte_power_exit(TEST_POWER_LCORE_INVALID);
656 printf("Unpectedly exit power management successfully for "
657 "lcore %u\n", TEST_POWER_LCORE_INVALID);
658 rte_power_unset_env();
661 rte_power_unset_env();
665 rte_power_exit(TEST_POWER_LCORE_ID);
666 rte_power_unset_env();
671 test_power_caps(void)
673 struct rte_power_core_capabilities caps;
676 ret = rte_power_init(TEST_POWER_LCORE_ID);
678 printf("Cannot initialise power management for lcore %u, this "
679 "may occur if environment is not configured "
680 "correctly(APCI cpufreq) or operating in another valid "
681 "Power management environment\n", TEST_POWER_LCORE_ID);
682 rte_power_unset_env();
686 ret = rte_power_get_capabilities(TEST_POWER_LCORE_ID, &caps);
688 printf("POWER: Error getting capabilities\n");
692 printf("POWER: Capabilities %"PRIx64"\n", caps.capabilities);
694 rte_power_unset_env();
700 REGISTER_TEST_COMMAND(power_cpufreq_autotest, test_power_cpufreq);
701 REGISTER_TEST_COMMAND(power_caps_autotest, test_power_caps);