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