ethdev: remove underscore prefix from internal API
[dpdk.git] / app / test / test_power_cpufreq.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <unistd.h>
8 #include <limits.h>
9 #include <string.h>
10 #include <inttypes.h>
11
12 #include "test.h"
13
14 #ifndef RTE_LIBRTE_POWER
15
16 static int
17 test_power_cpufreq(void)
18 {
19         printf("Power management library not supported, skipping test\n");
20         return TEST_SKIPPED;
21 }
22
23 static int
24 test_power_caps(void)
25 {
26         printf("Power management library not supported, skipping test\n");
27         return TEST_SKIPPED;
28 }
29
30 #else
31 #include <rte_power.h>
32
33 #define TEST_POWER_LCORE_ID      2U
34 #define TEST_POWER_LCORE_INVALID ((unsigned)RTE_MAX_LCORE)
35 #define TEST_POWER_FREQS_NUM_MAX ((unsigned)RTE_MAX_LCORE_FREQS)
36
37 #define TEST_POWER_SYSFILE_CUR_FREQ \
38         "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_cur_freq"
39
40 static uint32_t total_freq_num;
41 static uint32_t freqs[TEST_POWER_FREQS_NUM_MAX];
42
43 static int
44 check_cur_freq(unsigned lcore_id, uint32_t idx)
45 {
46 #define TEST_POWER_CONVERT_TO_DECIMAL 10
47         FILE *f;
48         char fullpath[PATH_MAX];
49         char buf[BUFSIZ];
50         uint32_t cur_freq;
51         int ret = -1;
52
53         if (snprintf(fullpath, sizeof(fullpath),
54                 TEST_POWER_SYSFILE_CUR_FREQ, lcore_id) < 0) {
55                 return 0;
56         }
57         f = fopen(fullpath, "r");
58         if (f == NULL) {
59                 return 0;
60         }
61         if (fgets(buf, sizeof(buf), f) == NULL) {
62                 goto fail_get_cur_freq;
63         }
64         cur_freq = strtoul(buf, NULL, TEST_POWER_CONVERT_TO_DECIMAL);
65         ret = (freqs[idx] == cur_freq ? 0 : -1);
66
67 fail_get_cur_freq:
68         fclose(f);
69
70         return ret;
71 }
72
73 /* Check rte_power_freqs() */
74 static int
75 check_power_freqs(void)
76 {
77         uint32_t ret;
78
79         total_freq_num = 0;
80         memset(freqs, 0, sizeof(freqs));
81
82         /* test with an invalid lcore id */
83         ret = rte_power_freqs(TEST_POWER_LCORE_INVALID, freqs,
84                                         TEST_POWER_FREQS_NUM_MAX);
85         if (ret > 0) {
86                 printf("Unexpectedly get available freqs successfully on "
87                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
88                 return -1;
89         }
90
91         /* test with NULL buffer to save available freqs */
92         ret = rte_power_freqs(TEST_POWER_LCORE_ID, NULL,
93                                 TEST_POWER_FREQS_NUM_MAX);
94         if (ret > 0) {
95                 printf("Unexpectedly get available freqs successfully with "
96                         "NULL buffer on lcore %u\n", TEST_POWER_LCORE_ID);
97                 return -1;
98         }
99
100         /* test of getting zero number of freqs */
101         ret = rte_power_freqs(TEST_POWER_LCORE_ID, freqs, 0);
102         if (ret > 0) {
103                 printf("Unexpectedly get available freqs successfully with "
104                         "zero buffer size on lcore %u\n", TEST_POWER_LCORE_ID);
105                 return -1;
106         }
107
108         /* test with all valid input parameters */
109         ret = rte_power_freqs(TEST_POWER_LCORE_ID, freqs,
110                                 TEST_POWER_FREQS_NUM_MAX);
111         if (ret == 0 || ret > TEST_POWER_FREQS_NUM_MAX) {
112                 printf("Fail to get available freqs on lcore %u\n",
113                                                 TEST_POWER_LCORE_ID);
114                 return -1;
115         }
116
117         /* Save the total number of available freqs */
118         total_freq_num = ret;
119
120         return 0;
121 }
122
123 /* Check rte_power_get_freq() */
124 static int
125 check_power_get_freq(void)
126 {
127         int ret;
128         uint32_t count;
129
130         /* test with an invalid lcore id */
131         count = rte_power_get_freq(TEST_POWER_LCORE_INVALID);
132         if (count < TEST_POWER_FREQS_NUM_MAX) {
133                 printf("Unexpectedly get freq index successfully on "
134                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
135                 return -1;
136         }
137
138         count = rte_power_get_freq(TEST_POWER_LCORE_ID);
139         if (count >= TEST_POWER_FREQS_NUM_MAX) {
140                 printf("Fail to get the freq index on lcore %u\n",
141                                                 TEST_POWER_LCORE_ID);
142                 return -1;
143         }
144
145         /* Check the current frequency */
146         ret = check_cur_freq(TEST_POWER_LCORE_ID, count);
147         if (ret < 0)
148                 return -1;
149
150         return 0;
151 }
152
153 /* Check rte_power_set_freq() */
154 static int
155 check_power_set_freq(void)
156 {
157         int ret;
158
159         /* test with an invalid lcore id */
160         ret = rte_power_set_freq(TEST_POWER_LCORE_INVALID, 0);
161         if (ret >= 0) {
162                 printf("Unexpectedly set freq index successfully on "
163                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
164                 return -1;
165         }
166
167         /* test with an invalid freq index */
168         ret = rte_power_set_freq(TEST_POWER_LCORE_ID,
169                                 TEST_POWER_FREQS_NUM_MAX);
170         if (ret >= 0) {
171                 printf("Unexpectedly set an invalid freq index (%u)"
172                         "successfully on lcore %u\n", TEST_POWER_FREQS_NUM_MAX,
173                                                         TEST_POWER_LCORE_ID);
174                 return -1;
175         }
176
177         /**
178          * test with an invalid freq index which is right one bigger than
179          * total number of freqs
180          */
181         ret = rte_power_set_freq(TEST_POWER_LCORE_ID, total_freq_num);
182         if (ret >= 0) {
183                 printf("Unexpectedly set an invalid freq index (%u)"
184                         "successfully on lcore %u\n", total_freq_num,
185                                                 TEST_POWER_LCORE_ID);
186                 return -1;
187         }
188         ret = rte_power_set_freq(TEST_POWER_LCORE_ID, total_freq_num - 1);
189         if (ret < 0) {
190                 printf("Fail to set freq index on lcore %u\n",
191                                         TEST_POWER_LCORE_ID);
192                 return -1;
193         }
194
195         /* Check the current frequency */
196         ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1);
197         if (ret < 0)
198                 return -1;
199
200         return 0;
201 }
202
203 /* Check rte_power_freq_down() */
204 static int
205 check_power_freq_down(void)
206 {
207         int ret;
208
209         /* test with an invalid lcore id */
210         ret = rte_power_freq_down(TEST_POWER_LCORE_INVALID);
211         if (ret >= 0) {
212                 printf("Unexpectedly scale down successfully the freq on "
213                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
214                 return -1;
215         }
216
217         /* Scale down to min and then scale down one step */
218         ret = rte_power_freq_min(TEST_POWER_LCORE_ID);
219         if (ret < 0) {
220                 printf("Fail to scale down the freq to min on lcore %u\n",
221                                                         TEST_POWER_LCORE_ID);
222                 return -1;
223         }
224         ret = rte_power_freq_down(TEST_POWER_LCORE_ID);
225         if (ret < 0) {
226                 printf("Fail to scale down the freq on lcore %u\n",
227                                                 TEST_POWER_LCORE_ID);
228                 return -1;
229         }
230
231         /* Check the current frequency */
232         ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1);
233         if (ret < 0)
234                 return -1;
235
236         /* Scale up to max and then scale down one step */
237         ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
238         if (ret < 0) {
239                 printf("Fail to scale up the freq to max on lcore %u\n",
240                                                         TEST_POWER_LCORE_ID);
241                 return -1;
242         }
243         ret = rte_power_freq_down(TEST_POWER_LCORE_ID);
244         if (ret < 0) {
245                 printf("Fail to scale down the freq on lcore %u\n",
246                                                 TEST_POWER_LCORE_ID);
247                 return -1;
248         }
249
250         /* Check the current frequency */
251         ret = check_cur_freq(TEST_POWER_LCORE_ID, 1);
252         if (ret < 0)
253                 return -1;
254
255         return 0;
256 }
257
258 /* Check rte_power_freq_up() */
259 static int
260 check_power_freq_up(void)
261 {
262         int ret;
263
264         /* test with an invalid lcore id */
265         ret = rte_power_freq_up(TEST_POWER_LCORE_INVALID);
266         if (ret >= 0) {
267                 printf("Unexpectedly scale up successfully the freq on %u\n",
268                                                 TEST_POWER_LCORE_INVALID);
269                 return -1;
270         }
271
272         /* Scale down to min and then scale up one step */
273         ret = rte_power_freq_min(TEST_POWER_LCORE_ID);
274         if (ret < 0) {
275                 printf("Fail to scale down the freq to min on lcore %u\n",
276                                                         TEST_POWER_LCORE_ID);
277                 return -1;
278         }
279         ret = rte_power_freq_up(TEST_POWER_LCORE_ID);
280         if (ret < 0) {
281                 printf("Fail to scale up the freq on lcore %u\n",
282                                                 TEST_POWER_LCORE_ID);
283                 return -1;
284         }
285
286         /* Check the current frequency */
287         ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 2);
288         if (ret < 0)
289                 return -1;
290
291         /* Scale up to max and then scale up one step */
292         ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
293         if (ret < 0) {
294                 printf("Fail to scale up the freq to max on lcore %u\n",
295                                                 TEST_POWER_LCORE_ID);
296                 return -1;
297         }
298         ret = rte_power_freq_up(TEST_POWER_LCORE_ID);
299         if (ret < 0) {
300                 printf("Fail to scale up the freq on lcore %u\n",
301                                                 TEST_POWER_LCORE_ID);
302                 return -1;
303         }
304
305         /* Check the current frequency */
306         ret = check_cur_freq(TEST_POWER_LCORE_ID, 0);
307         if (ret < 0)
308                 return -1;
309
310         return 0;
311 }
312
313 /* Check rte_power_freq_max() */
314 static int
315 check_power_freq_max(void)
316 {
317         int ret;
318
319         /* test with an invalid lcore id */
320         ret = rte_power_freq_max(TEST_POWER_LCORE_INVALID);
321         if (ret >= 0) {
322                 printf("Unexpectedly scale up successfully the freq to max on "
323                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
324                 return -1;
325         }
326         ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
327         if (ret < 0) {
328                 printf("Fail to scale up the freq to max on lcore %u\n",
329                                                 TEST_POWER_LCORE_ID);
330                 return -1;
331         }
332
333         /* Check the current frequency */
334         ret = check_cur_freq(TEST_POWER_LCORE_ID, 0);
335         if (ret < 0)
336                 return -1;
337
338         return 0;
339 }
340
341 /* Check rte_power_freq_min() */
342 static int
343 check_power_freq_min(void)
344 {
345         int ret;
346
347         /* test with an invalid lcore id */
348         ret = rte_power_freq_min(TEST_POWER_LCORE_INVALID);
349         if (ret >= 0) {
350                 printf("Unexpectedly scale down successfully the freq to min "
351                                 "on lcore %u\n", TEST_POWER_LCORE_INVALID);
352                 return -1;
353         }
354         ret = rte_power_freq_min(TEST_POWER_LCORE_ID);
355         if (ret < 0) {
356                 printf("Fail to scale down the freq to min on lcore %u\n",
357                                                         TEST_POWER_LCORE_ID);
358                 return -1;
359         }
360
361         /* Check the current frequency */
362         ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1);
363         if (ret < 0)
364                 return -1;
365
366         return 0;
367 }
368
369 /* Check rte_power_turbo() */
370 static int
371 check_power_turbo(void)
372 {
373         int ret;
374
375         if (rte_power_turbo_status(TEST_POWER_LCORE_ID) == 0) {
376                 printf("Turbo not available on lcore %u, skipping test\n",
377                                 TEST_POWER_LCORE_ID);
378                 return 0;
379         }
380
381         /* test with an invalid lcore id */
382         ret = rte_power_freq_enable_turbo(TEST_POWER_LCORE_INVALID);
383         if (ret >= 0) {
384                 printf("Unexpectedly enable turbo successfully on lcore %u\n",
385                                 TEST_POWER_LCORE_INVALID);
386                 return -1;
387         }
388         ret = rte_power_freq_enable_turbo(TEST_POWER_LCORE_ID);
389         if (ret < 0) {
390                 printf("Fail to enable turbo on lcore %u\n",
391                                 TEST_POWER_LCORE_ID);
392                 return -1;
393         }
394
395         /* Check the current frequency */
396         ret = check_cur_freq(TEST_POWER_LCORE_ID, 0);
397         if (ret < 0)
398                 return -1;
399
400         /* test with an invalid lcore id */
401         ret = rte_power_freq_disable_turbo(TEST_POWER_LCORE_INVALID);
402         if (ret >= 0) {
403                 printf("Unexpectedly disable turbo successfully on lcore %u\n",
404                                 TEST_POWER_LCORE_INVALID);
405                 return -1;
406         }
407         ret = rte_power_freq_disable_turbo(TEST_POWER_LCORE_ID);
408         if (ret < 0) {
409                 printf("Fail to disable turbo on lcore %u\n",
410                                 TEST_POWER_LCORE_ID);
411                 return -1;
412         }
413
414         /* Check the current frequency */
415         ret = check_cur_freq(TEST_POWER_LCORE_ID, 1);
416         if (ret < 0)
417                 return -1;
418
419         return 0;
420 }
421
422 static int
423 test_power_cpufreq(void)
424 {
425         int ret = -1;
426         enum power_management_env env;
427
428         /* Test initialisation of a valid lcore */
429         ret = rte_power_init(TEST_POWER_LCORE_ID);
430         if (ret < 0) {
431                 printf("Cannot initialise power management for lcore %u, this "
432                                 "may occur if environment is not configured "
433                                 "correctly(APCI cpufreq) or operating in another valid "
434                                 "Power management environment\n",
435                                 TEST_POWER_LCORE_ID);
436                 rte_power_unset_env();
437                 return TEST_SKIPPED;
438         }
439
440         /* Test environment configuration */
441         env = rte_power_get_env();
442         if ((env != PM_ENV_ACPI_CPUFREQ) && (env != PM_ENV_PSTATE_CPUFREQ)) {
443                 printf("Unexpectedly got an environment other than ACPI/PSTATE\n");
444                 goto fail_all;
445         }
446
447         /* verify that function pointers are not NULL */
448         if (rte_power_freqs == NULL) {
449                 printf("rte_power_freqs should not be NULL, environment has not been "
450                                 "initialised\n");
451                 goto fail_all;
452         }
453         if (rte_power_get_freq == NULL) {
454                 printf("rte_power_get_freq should not be NULL, environment has not "
455                                 "been initialised\n");
456                 goto fail_all;
457         }
458         if (rte_power_set_freq == NULL) {
459                 printf("rte_power_set_freq should not be NULL, environment has not "
460                                 "been initialised\n");
461                 goto fail_all;
462         }
463         if (rte_power_freq_up == NULL) {
464                 printf("rte_power_freq_up should not be NULL, environment has not "
465                                 "been initialised\n");
466                 goto fail_all;
467         }
468         if (rte_power_freq_down == NULL) {
469                 printf("rte_power_freq_down should not be NULL, environment has not "
470                                 "been initialised\n");
471                 goto fail_all;
472         }
473         if (rte_power_freq_max == NULL) {
474                 printf("rte_power_freq_max should not be NULL, environment has not "
475                                 "been initialised\n");
476                 goto fail_all;
477         }
478         if (rte_power_freq_min == NULL) {
479                 printf("rte_power_freq_min should not be NULL, environment has not "
480                                 "been initialised\n");
481                 goto fail_all;
482         }
483         if (rte_power_turbo_status == NULL) {
484                 printf("rte_power_turbo_status should not be NULL, environment has not "
485                                 "been initialised\n");
486                 goto fail_all;
487         }
488         if (rte_power_freq_enable_turbo == NULL) {
489                 printf("rte_power_freq_enable_turbo should not be NULL, environment has not "
490                                 "been initialised\n");
491                 goto fail_all;
492         }
493         if (rte_power_freq_disable_turbo == NULL) {
494                 printf("rte_power_freq_disable_turbo should not be NULL, environment has not "
495                                 "been initialised\n");
496                 goto fail_all;
497         }
498
499         ret = rte_power_exit(TEST_POWER_LCORE_ID);
500         if (ret < 0) {
501                 printf("Cannot exit power management for lcore %u\n",
502                                                 TEST_POWER_LCORE_ID);
503                 rte_power_unset_env();
504                 return -1;
505         }
506
507         /* test of init power management for an invalid lcore */
508         ret = rte_power_init(TEST_POWER_LCORE_INVALID);
509         if (ret == 0) {
510                 printf("Unexpectedly initialise power management successfully "
511                                 "for lcore %u\n", TEST_POWER_LCORE_INVALID);
512                 rte_power_unset_env();
513                 return -1;
514         }
515
516         /* Test initialisation of a valid lcore */
517         ret = rte_power_init(TEST_POWER_LCORE_ID);
518         if (ret < 0) {
519                 printf("Cannot initialise power management for lcore %u, this "
520                                 "may occur if environment is not configured "
521                                 "correctly(APCI cpufreq) or operating in another valid "
522                                 "Power management environment\n", TEST_POWER_LCORE_ID);
523                 rte_power_unset_env();
524                 return TEST_SKIPPED;
525         }
526
527         /**
528          * test of initialising power management for the lcore which has
529          * been initialised
530          */
531         ret = rte_power_init(TEST_POWER_LCORE_ID);
532         if (ret == 0) {
533                 printf("Unexpectedly init successfully power twice on "
534                                         "lcore %u\n", TEST_POWER_LCORE_ID);
535                 goto fail_all;
536         }
537
538         ret = check_power_freqs();
539         if (ret < 0)
540                 goto fail_all;
541
542         if (total_freq_num < 2) {
543                 rte_power_exit(TEST_POWER_LCORE_ID);
544                 printf("Frequency can not be changed due to CPU itself\n");
545                 rte_power_unset_env();
546                 return 0;
547         }
548
549         ret = check_power_get_freq();
550         if (ret < 0)
551                 goto fail_all;
552
553         ret = check_power_set_freq();
554         if (ret < 0)
555                 goto fail_all;
556
557         ret = check_power_freq_down();
558         if (ret < 0)
559                 goto fail_all;
560
561         ret = check_power_freq_up();
562         if (ret < 0)
563                 goto fail_all;
564
565         ret = check_power_freq_max();
566         if (ret < 0)
567                 goto fail_all;
568
569         ret = check_power_freq_min();
570         if (ret < 0)
571                 goto fail_all;
572
573         ret = check_power_turbo();
574         if (ret < 0)
575                 goto fail_all;
576
577         ret = rte_power_exit(TEST_POWER_LCORE_ID);
578         if (ret < 0) {
579                 printf("Cannot exit power management for lcore %u\n",
580                                                 TEST_POWER_LCORE_ID);
581                 rte_power_unset_env();
582                 return -1;
583         }
584
585         /**
586          * test of exiting power management for the lcore which has been exited
587          */
588         ret = rte_power_exit(TEST_POWER_LCORE_ID);
589         if (ret == 0) {
590                 printf("Unexpectedly exit successfully power management twice "
591                                         "on lcore %u\n", TEST_POWER_LCORE_ID);
592                 rte_power_unset_env();
593                 return -1;
594         }
595
596         /* test of exit power management for an invalid lcore */
597         ret = rte_power_exit(TEST_POWER_LCORE_INVALID);
598         if (ret == 0) {
599                 printf("Unpectedly exit power management successfully for "
600                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
601                 rte_power_unset_env();
602                 return -1;
603         }
604         rte_power_unset_env();
605         return 0;
606
607 fail_all:
608         rte_power_exit(TEST_POWER_LCORE_ID);
609         rte_power_unset_env();
610         return -1;
611 }
612
613 static int
614 test_power_caps(void)
615 {
616         struct rte_power_core_capabilities caps;
617         int ret;
618
619         ret = rte_power_init(TEST_POWER_LCORE_ID);
620         if (ret < 0) {
621                 printf("Cannot initialise power management for lcore %u, this "
622                         "may occur if environment is not configured "
623                         "correctly(APCI cpufreq) or operating in another valid "
624                         "Power management environment\n", TEST_POWER_LCORE_ID);
625                 rte_power_unset_env();
626                 return -1;
627         }
628
629         ret = rte_power_get_capabilities(TEST_POWER_LCORE_ID, &caps);
630         if (ret) {
631                 printf("POWER: Error getting capabilities\n");
632                 return -1;
633         }
634
635         printf("POWER: Capabilities %"PRIx64"\n", caps.capabilities);
636
637         rte_power_unset_env();
638         return 0;
639 }
640
641 #endif
642
643 REGISTER_TEST_COMMAND(power_cpufreq_autotest, test_power_cpufreq);
644 REGISTER_TEST_COMMAND(power_caps_autotest, test_power_caps);