New upstream version 18.02
[deb_dpdk.git] / test / test / test_power_acpi_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
11 #include "test.h"
12
13 #ifndef RTE_LIBRTE_POWER
14
15 static int
16 test_power_acpi_cpufreq(void)
17 {
18         printf("Power management library not supported, skipping test\n");
19         return TEST_SKIPPED;
20 }
21
22 #else
23 #include <rte_power.h>
24
25 #define TEST_POWER_LCORE_ID      2U
26 #define TEST_POWER_LCORE_INVALID ((unsigned)RTE_MAX_LCORE)
27 #define TEST_POWER_FREQS_NUM_MAX ((unsigned)RTE_MAX_LCORE_FREQS)
28
29 #define TEST_POWER_SYSFILE_CUR_FREQ \
30         "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq"
31
32 static uint32_t total_freq_num;
33 static uint32_t freqs[TEST_POWER_FREQS_NUM_MAX];
34
35 static int
36 check_cur_freq(unsigned lcore_id, uint32_t idx)
37 {
38 #define TEST_POWER_CONVERT_TO_DECIMAL 10
39         FILE *f;
40         char fullpath[PATH_MAX];
41         char buf[BUFSIZ];
42         uint32_t cur_freq;
43         int ret = -1;
44
45         if (snprintf(fullpath, sizeof(fullpath),
46                 TEST_POWER_SYSFILE_CUR_FREQ, lcore_id) < 0) {
47                 return 0;
48         }
49         f = fopen(fullpath, "r");
50         if (f == NULL) {
51                 return 0;
52         }
53         if (fgets(buf, sizeof(buf), f) == NULL) {
54                 goto fail_get_cur_freq;
55         }
56         cur_freq = strtoul(buf, NULL, TEST_POWER_CONVERT_TO_DECIMAL);
57         ret = (freqs[idx] == cur_freq ? 0 : -1);
58
59 fail_get_cur_freq:
60         fclose(f);
61
62         return ret;
63 }
64
65 /* Check rte_power_freqs() */
66 static int
67 check_power_freqs(void)
68 {
69         uint32_t ret;
70
71         total_freq_num = 0;
72         memset(freqs, 0, sizeof(freqs));
73
74         /* test with an invalid lcore id */
75         ret = rte_power_freqs(TEST_POWER_LCORE_INVALID, freqs,
76                                         TEST_POWER_FREQS_NUM_MAX);
77         if (ret > 0) {
78                 printf("Unexpectedly get available freqs successfully on "
79                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
80                 return -1;
81         }
82
83         /* test with NULL buffer to save available freqs */
84         ret = rte_power_freqs(TEST_POWER_LCORE_ID, NULL,
85                                 TEST_POWER_FREQS_NUM_MAX);
86         if (ret > 0) {
87                 printf("Unexpectedly get available freqs successfully with "
88                         "NULL buffer on lcore %u\n", TEST_POWER_LCORE_ID);
89                 return -1;
90         }
91
92         /* test of getting zero number of freqs */
93         ret = rte_power_freqs(TEST_POWER_LCORE_ID, freqs, 0);
94         if (ret > 0) {
95                 printf("Unexpectedly get available freqs successfully with "
96                         "zero buffer size on lcore %u\n", TEST_POWER_LCORE_ID);
97                 return -1;
98         }
99
100         /* test with all valid input parameters */
101         ret = rte_power_freqs(TEST_POWER_LCORE_ID, freqs,
102                                 TEST_POWER_FREQS_NUM_MAX);
103         if (ret == 0 || ret > TEST_POWER_FREQS_NUM_MAX) {
104                 printf("Fail to get available freqs on lcore %u\n",
105                                                 TEST_POWER_LCORE_ID);
106                 return -1;
107         }
108
109         /* Save the total number of available freqs */
110         total_freq_num = ret;
111
112         return 0;
113 }
114
115 /* Check rte_power_get_freq() */
116 static int
117 check_power_get_freq(void)
118 {
119         int ret;
120         uint32_t count;
121
122         /* test with an invalid lcore id */
123         count = rte_power_get_freq(TEST_POWER_LCORE_INVALID);
124         if (count < TEST_POWER_FREQS_NUM_MAX) {
125                 printf("Unexpectedly get freq index successfully on "
126                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
127                 return -1;
128         }
129
130         count = rte_power_get_freq(TEST_POWER_LCORE_ID);
131         if (count >= TEST_POWER_FREQS_NUM_MAX) {
132                 printf("Fail to get the freq index on lcore %u\n",
133                                                 TEST_POWER_LCORE_ID);
134                 return -1;
135         }
136
137         /* Check the current frequency */
138         ret = check_cur_freq(TEST_POWER_LCORE_ID, count);
139         if (ret < 0)
140                 return -1;
141
142         return 0;
143 }
144
145 /* Check rte_power_set_freq() */
146 static int
147 check_power_set_freq(void)
148 {
149         int ret;
150
151         /* test with an invalid lcore id */
152         ret = rte_power_set_freq(TEST_POWER_LCORE_INVALID, 0);
153         if (ret >= 0) {
154                 printf("Unexpectedly set freq index successfully on "
155                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
156                 return -1;
157         }
158
159         /* test with an invalid freq index */
160         ret = rte_power_set_freq(TEST_POWER_LCORE_ID,
161                                 TEST_POWER_FREQS_NUM_MAX);
162         if (ret >= 0) {
163                 printf("Unexpectedly set an invalid freq index (%u)"
164                         "successfully on lcore %u\n", TEST_POWER_FREQS_NUM_MAX,
165                                                         TEST_POWER_LCORE_ID);
166                 return -1;
167         }
168
169         /**
170          * test with an invalid freq index which is right one bigger than
171          * total number of freqs
172          */
173         ret = rte_power_set_freq(TEST_POWER_LCORE_ID, total_freq_num);
174         if (ret >= 0) {
175                 printf("Unexpectedly set an invalid freq index (%u)"
176                         "successfully on lcore %u\n", total_freq_num,
177                                                 TEST_POWER_LCORE_ID);
178                 return -1;
179         }
180         ret = rte_power_set_freq(TEST_POWER_LCORE_ID, total_freq_num - 1);
181         if (ret < 0) {
182                 printf("Fail to set freq index on lcore %u\n",
183                                         TEST_POWER_LCORE_ID);
184                 return -1;
185         }
186
187         /* Check the current frequency */
188         ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1);
189         if (ret < 0)
190                 return -1;
191
192         return 0;
193 }
194
195 /* Check rte_power_freq_down() */
196 static int
197 check_power_freq_down(void)
198 {
199         int ret;
200
201         /* test with an invalid lcore id */
202         ret = rte_power_freq_down(TEST_POWER_LCORE_INVALID);
203         if (ret >= 0) {
204                 printf("Unexpectedly scale down successfully the freq on "
205                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
206                 return -1;
207         }
208
209         /* Scale down to min and then scale down one step */
210         ret = rte_power_freq_min(TEST_POWER_LCORE_ID);
211         if (ret < 0) {
212                 printf("Fail to scale down the freq to min on lcore %u\n",
213                                                         TEST_POWER_LCORE_ID);
214                 return -1;
215         }
216         ret = rte_power_freq_down(TEST_POWER_LCORE_ID);
217         if (ret < 0) {
218                 printf("Fail to scale down the freq on lcore %u\n",
219                                                 TEST_POWER_LCORE_ID);
220                 return -1;
221         }
222
223         /* Check the current frequency */
224         ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1);
225         if (ret < 0)
226                 return -1;
227
228         /* Scale up to max and then scale down one step */
229         ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
230         if (ret < 0) {
231                 printf("Fail to scale up the freq to max on lcore %u\n",
232                                                         TEST_POWER_LCORE_ID);
233                 return -1;
234         }
235         ret = rte_power_freq_down(TEST_POWER_LCORE_ID);
236         if (ret < 0) {
237                 printf("Fail to scale down the freq on lcore %u\n",
238                                                 TEST_POWER_LCORE_ID);
239                 return -1;
240         }
241
242         /* Check the current frequency */
243         ret = check_cur_freq(TEST_POWER_LCORE_ID, 1);
244         if (ret < 0)
245                 return -1;
246
247         return 0;
248 }
249
250 /* Check rte_power_freq_up() */
251 static int
252 check_power_freq_up(void)
253 {
254         int ret;
255
256         /* test with an invalid lcore id */
257         ret = rte_power_freq_up(TEST_POWER_LCORE_INVALID);
258         if (ret >= 0) {
259                 printf("Unexpectedly scale up successfully the freq on %u\n",
260                                                 TEST_POWER_LCORE_INVALID);
261                 return -1;
262         }
263
264         /* Scale down to min and then scale up one step */
265         ret = rte_power_freq_min(TEST_POWER_LCORE_ID);
266         if (ret < 0) {
267                 printf("Fail to scale down the freq to min on lcore %u\n",
268                                                         TEST_POWER_LCORE_ID);
269                 return -1;
270         }
271         ret = rte_power_freq_up(TEST_POWER_LCORE_ID);
272         if (ret < 0) {
273                 printf("Fail to scale up the freq on lcore %u\n",
274                                                 TEST_POWER_LCORE_ID);
275                 return -1;
276         }
277
278         /* Check the current frequency */
279         ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 2);
280         if (ret < 0)
281                 return -1;
282
283         /* Scale up to max and then scale up one step */
284         ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
285         if (ret < 0) {
286                 printf("Fail to scale up the freq to max on lcore %u\n",
287                                                 TEST_POWER_LCORE_ID);
288                 return -1;
289         }
290         ret = rte_power_freq_up(TEST_POWER_LCORE_ID);
291         if (ret < 0) {
292                 printf("Fail to scale up the freq on lcore %u\n",
293                                                 TEST_POWER_LCORE_ID);
294                 return -1;
295         }
296
297         /* Check the current frequency */
298         ret = check_cur_freq(TEST_POWER_LCORE_ID, 0);
299         if (ret < 0)
300                 return -1;
301
302         return 0;
303 }
304
305 /* Check rte_power_freq_max() */
306 static int
307 check_power_freq_max(void)
308 {
309         int ret;
310
311         /* test with an invalid lcore id */
312         ret = rte_power_freq_max(TEST_POWER_LCORE_INVALID);
313         if (ret >= 0) {
314                 printf("Unexpectedly scale up successfully the freq to max on "
315                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
316                 return -1;
317         }
318         ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
319         if (ret < 0) {
320                 printf("Fail to scale up the freq to max on lcore %u\n",
321                                                 TEST_POWER_LCORE_ID);
322                 return -1;
323         }
324
325         /* Check the current frequency */
326         ret = check_cur_freq(TEST_POWER_LCORE_ID, 0);
327         if (ret < 0)
328                 return -1;
329
330         return 0;
331 }
332
333 /* Check rte_power_freq_min() */
334 static int
335 check_power_freq_min(void)
336 {
337         int ret;
338
339         /* test with an invalid lcore id */
340         ret = rte_power_freq_min(TEST_POWER_LCORE_INVALID);
341         if (ret >= 0) {
342                 printf("Unexpectedly scale down successfully the freq to min "
343                                 "on lcore %u\n", TEST_POWER_LCORE_INVALID);
344                 return -1;
345         }
346         ret = rte_power_freq_min(TEST_POWER_LCORE_ID);
347         if (ret < 0) {
348                 printf("Fail to scale down the freq to min on lcore %u\n",
349                                                         TEST_POWER_LCORE_ID);
350                 return -1;
351         }
352
353         /* Check the current frequency */
354         ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1);
355         if (ret < 0)
356                 return -1;
357
358         return 0;
359 }
360
361 static int
362 test_power_acpi_cpufreq(void)
363 {
364         int ret = -1;
365         enum power_management_env env;
366
367         ret = rte_power_set_env(PM_ENV_ACPI_CPUFREQ);
368         if (ret != 0) {
369                 printf("Failed on setting environment to PM_ENV_ACPI_CPUFREQ, this "
370                                 "may occur if environment is not configured correctly or "
371                                 " operating in another valid Power management environment\n");
372                 return -1;
373         }
374
375         /* Test environment configuration */
376         env = rte_power_get_env();
377         if (env != PM_ENV_ACPI_CPUFREQ) {
378                 printf("Unexpectedly got an environment other than ACPI cpufreq\n");
379                 goto fail_all;
380         }
381
382         /* verify that function pointers are not NULL */
383         if (rte_power_freqs == NULL) {
384                 printf("rte_power_freqs should not be NULL, environment has not been "
385                                 "initialised\n");
386                 goto fail_all;
387         }
388         if (rte_power_get_freq == NULL) {
389                 printf("rte_power_get_freq should not be NULL, environment has not "
390                                 "been initialised\n");
391                 goto fail_all;
392         }
393         if (rte_power_set_freq == NULL) {
394                 printf("rte_power_set_freq should not be NULL, environment has not "
395                                 "been initialised\n");
396                 goto fail_all;
397         }
398         if (rte_power_freq_up == NULL) {
399                 printf("rte_power_freq_up should not be NULL, environment has not "
400                                 "been initialised\n");
401                 goto fail_all;
402         }
403         if (rte_power_freq_down == NULL) {
404                 printf("rte_power_freq_down should not be NULL, environment has not "
405                                 "been initialised\n");
406                 goto fail_all;
407         }
408         if (rte_power_freq_max == NULL) {
409                 printf("rte_power_freq_max should not be NULL, environment has not "
410                                 "been initialised\n");
411                 goto fail_all;
412         }
413         if (rte_power_freq_min == NULL) {
414                 printf("rte_power_freq_min should not be NULL, environment has not "
415                                 "been initialised\n");
416                 goto fail_all;
417         }
418
419         /* test of init power management for an invalid lcore */
420         ret = rte_power_init(TEST_POWER_LCORE_INVALID);
421         if (ret == 0) {
422                 printf("Unexpectedly initialise power management successfully "
423                                 "for lcore %u\n", TEST_POWER_LCORE_INVALID);
424                 rte_power_unset_env();
425                 return -1;
426         }
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", TEST_POWER_LCORE_ID);
435                 rte_power_unset_env();
436                 return -1;
437         }
438
439         /**
440          * test of initialising power management for the lcore which has
441          * been initialised
442          */
443         ret = rte_power_init(TEST_POWER_LCORE_ID);
444         if (ret == 0) {
445                 printf("Unexpectedly init successfully power twice on "
446                                         "lcore %u\n", TEST_POWER_LCORE_ID);
447                 goto fail_all;
448         }
449
450         ret = check_power_freqs();
451         if (ret < 0)
452                 goto fail_all;
453
454         if (total_freq_num < 2) {
455                 rte_power_exit(TEST_POWER_LCORE_ID);
456                 printf("Frequency can not be changed due to CPU itself\n");
457                 rte_power_unset_env();
458                 return 0;
459         }
460
461         ret = check_power_get_freq();
462         if (ret < 0)
463                 goto fail_all;
464
465         ret = check_power_set_freq();
466         if (ret < 0)
467                 goto fail_all;
468
469         ret = check_power_freq_down();
470         if (ret < 0)
471                 goto fail_all;
472
473         ret = check_power_freq_up();
474         if (ret < 0)
475                 goto fail_all;
476
477         ret = check_power_freq_max();
478         if (ret < 0)
479                 goto fail_all;
480
481         ret = check_power_freq_min();
482         if (ret < 0)
483                 goto fail_all;
484
485         ret = rte_power_exit(TEST_POWER_LCORE_ID);
486         if (ret < 0) {
487                 printf("Cannot exit power management for lcore %u\n",
488                                                 TEST_POWER_LCORE_ID);
489                 rte_power_unset_env();
490                 return -1;
491         }
492
493         /**
494          * test of exiting power management for the lcore which has been exited
495          */
496         ret = rte_power_exit(TEST_POWER_LCORE_ID);
497         if (ret == 0) {
498                 printf("Unexpectedly exit successfully power management twice "
499                                         "on lcore %u\n", TEST_POWER_LCORE_ID);
500                 rte_power_unset_env();
501                 return -1;
502         }
503
504         /* test of exit power management for an invalid lcore */
505         ret = rte_power_exit(TEST_POWER_LCORE_INVALID);
506         if (ret == 0) {
507                 printf("Unpectedly exit power management successfully for "
508                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
509                 rte_power_unset_env();
510                 return -1;
511         }
512         rte_power_unset_env();
513         return 0;
514
515 fail_all:
516         rte_power_exit(TEST_POWER_LCORE_ID);
517         rte_power_unset_env();
518         return -1;
519 }
520 #endif
521
522 REGISTER_TEST_COMMAND(power_acpi_cpufreq_autotest, test_power_acpi_cpufreq);