1e6e0d5e09d0ad6ec988a6f1c8568c93a872b8d3
[dpdk.git] / app / test / test_power.c
1 /*-
2  *   BSD LICENSE
3  * 
4  *   Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  * 
7  *   Redistribution and use in source and binary forms, with or without 
8  *   modification, are permitted provided that the following conditions 
9  *   are met:
10  * 
11  *     * Redistributions of source code must retain the above copyright 
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright 
14  *       notice, this list of conditions and the following disclaimer in 
15  *       the documentation and/or other materials provided with the 
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its 
18  *       contributors may be used to endorse or promote products derived 
19  *       from this software without specific prior written permission.
20  * 
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  * 
33  */
34
35 #include <stdio.h>
36 #include <stdint.h>
37 #include <unistd.h>
38 #include <limits.h>
39 #include <string.h>
40
41 #include <cmdline_parse.h>
42
43 #include "test.h"
44
45 #ifdef RTE_LIBRTE_POWER
46
47 #include <rte_power.h>
48
49 #define TEST_POWER_LCORE_ID      2U
50 #define TEST_POWER_LCORE_INVALID ((unsigned)RTE_MAX_LCORE)
51 #define TEST_POWER_FREQS_NUM_MAX ((unsigned)RTE_MAX_LCORE_FREQS)
52
53 #define TEST_POWER_SYSFILE_CUR_FREQ \
54         "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq"
55
56 static uint32_t total_freq_num;
57 static uint32_t freqs[TEST_POWER_FREQS_NUM_MAX];
58
59 static int
60 check_cur_freq(unsigned lcore_id, uint32_t idx)
61 {
62 #define TEST_POWER_CONVERT_TO_DECIMAL 10
63         FILE *f;
64         char fullpath[PATH_MAX];
65         char buf[BUFSIZ];
66         uint32_t cur_freq;
67         int ret = -1;
68
69         if (rte_snprintf(fullpath, sizeof(fullpath),
70                 TEST_POWER_SYSFILE_CUR_FREQ, lcore_id) < 0) {
71                 return 0;
72         }
73         f = fopen(fullpath, "r");
74         if (f == NULL) {
75                 return 0;
76         }
77         if (fgets(buf, sizeof(buf), f) == NULL) {
78                 goto fail_get_cur_freq;
79         }
80         cur_freq = strtoul(buf, NULL, TEST_POWER_CONVERT_TO_DECIMAL);
81         ret = (freqs[idx] == cur_freq ? 0 : -1);
82
83 fail_get_cur_freq:
84         fclose(f);
85
86         return ret;
87 }
88
89 /* Check rte_power_freqs() */
90 static int
91 check_power_freqs(void)
92 {
93         uint32_t ret;
94
95         total_freq_num = 0;
96         memset(freqs, 0, sizeof(freqs));
97
98         /* test with an invalid lcore id */
99         ret = rte_power_freqs(TEST_POWER_LCORE_INVALID, freqs,
100                                         TEST_POWER_FREQS_NUM_MAX);
101         if (ret > 0) {
102                 printf("Unexpectedly get available freqs successfully on "
103                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
104                 return -1;
105         }
106
107         /* test with NULL buffer to save available freqs */
108         ret = rte_power_freqs(TEST_POWER_LCORE_ID, NULL,
109                                 TEST_POWER_FREQS_NUM_MAX);
110         if (ret > 0) {
111                 printf("Unexpectedly get available freqs successfully with "
112                         "NULL buffer on lcore %u\n", TEST_POWER_LCORE_ID);
113                 return -1;
114         }
115
116         /* test of getting zero number of freqs */
117         ret = rte_power_freqs(TEST_POWER_LCORE_ID, freqs, 0);
118         if (ret > 0) {
119                 printf("Unexpectedly get available freqs successfully with "
120                         "zero buffer size on lcore %u\n", TEST_POWER_LCORE_ID);
121                 return -1;
122         }
123
124         /* test with all valid input parameters */
125         ret = rte_power_freqs(TEST_POWER_LCORE_ID, freqs,
126                                 TEST_POWER_FREQS_NUM_MAX);
127         if (ret == 0 || ret > TEST_POWER_FREQS_NUM_MAX) {
128                 printf("Fail to get available freqs on lcore %u\n",
129                                                 TEST_POWER_LCORE_ID);
130                 return -1;
131         }
132
133         /* Save the total number of available freqs */
134         total_freq_num = ret;
135
136         return 0;
137 }
138
139 /* Check rte_power_get_freq() */
140 static int
141 check_power_get_freq(void)
142 {
143         int ret;
144         uint32_t count;
145
146         /* test with an invalid lcore id */
147         count = rte_power_get_freq(TEST_POWER_LCORE_INVALID);
148         if (count < TEST_POWER_FREQS_NUM_MAX) {
149                 printf("Unexpectedly get freq index successfully on "
150                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
151                 return -1;
152         }
153
154         count = rte_power_get_freq(TEST_POWER_LCORE_ID);
155         if (count >= TEST_POWER_FREQS_NUM_MAX) {
156                 printf("Fail to get the freq index on lcore %u\n",
157                                                 TEST_POWER_LCORE_ID);
158                 return -1;
159         }
160
161         /* Check the current frequency */
162         ret = check_cur_freq(TEST_POWER_LCORE_ID, count);
163         if (ret < 0)
164                 return -1;
165
166         return 0;
167 }
168
169 /* Check rte_power_set_freq() */
170 static int
171 check_power_set_freq(void)
172 {
173         int ret;
174
175         /* test with an invalid lcore id */
176         ret = rte_power_set_freq(TEST_POWER_LCORE_INVALID, 0);
177         if (ret >= 0) {
178                 printf("Unexpectedly set freq index successfully on "
179                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
180                 return -1;
181         }
182
183         /* test with an invalid freq index */
184         ret = rte_power_set_freq(TEST_POWER_LCORE_ID,
185                                 TEST_POWER_FREQS_NUM_MAX);
186         if (ret >= 0) {
187                 printf("Unexpectedly set an invalid freq index (%u)"
188                         "successfully on lcore %u\n", TEST_POWER_FREQS_NUM_MAX,
189                                                         TEST_POWER_LCORE_ID);
190                 return -1;
191         }
192
193         /**
194          * test with an invalid freq index which is right one bigger than
195          * total number of freqs
196          */
197         ret = rte_power_set_freq(TEST_POWER_LCORE_ID, total_freq_num);
198         if (ret >= 0) {
199                 printf("Unexpectedly set an invalid freq index (%u)"
200                         "successfully on lcore %u\n", total_freq_num,
201                                                 TEST_POWER_LCORE_ID);
202                 return -1;
203         }
204         ret = rte_power_set_freq(TEST_POWER_LCORE_ID, 3);
205         if (ret < 0) {
206                 printf("Fail to set freq index on lcore %u\n",
207                                         TEST_POWER_LCORE_ID);
208                 return -1;
209         }
210
211         /* Check the current frequency */
212         ret = check_cur_freq(TEST_POWER_LCORE_ID, 3);
213         if (ret < 0)
214                 return -1;
215
216         return 0;
217 }
218
219 /* Check rte_power_freq_down() */
220 static int
221 check_power_freq_down(void)
222 {
223         int ret;
224
225         /* test with an invalid lcore id */
226         ret = rte_power_freq_down(TEST_POWER_LCORE_INVALID);
227         if (ret >= 0) {
228                 printf("Unexpectedly scale down successfully the freq on "
229                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
230                 return -1;
231         }
232
233         /* Scale down to min and then scale down one step */
234         ret = rte_power_freq_min(TEST_POWER_LCORE_ID);
235         if (ret < 0) {
236                 printf("Fail to scale down the freq to min on lcore %u\n",
237                                                         TEST_POWER_LCORE_ID);
238                 return -1;
239         }
240         ret = rte_power_freq_down(TEST_POWER_LCORE_ID);
241         if (ret < 0) {
242                 printf("Fail to scale down the freq on lcore %u\n",
243                                                 TEST_POWER_LCORE_ID);
244                 return -1;
245         }
246
247         /* Check the current frequency */
248         ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1);
249         if (ret < 0)
250                 return -1;
251
252         /* Scale up to max and then scale down one step */
253         ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
254         if (ret < 0) {
255                 printf("Fail to scale up the freq to max on lcore %u\n",
256                                                         TEST_POWER_LCORE_ID);
257                 return -1;
258         }
259         ret = rte_power_freq_down(TEST_POWER_LCORE_ID);
260         if (ret < 0) {
261                 printf ("Fail to scale down the freq on lcore %u\n",
262                                                 TEST_POWER_LCORE_ID);
263                 return -1;
264         }
265
266         /* Check the current frequency */
267         ret = check_cur_freq(TEST_POWER_LCORE_ID, 1);
268         if (ret < 0)
269                 return -1;
270
271         return 0;
272 }
273
274 /* Check rte_power_freq_up() */
275 static int
276 check_power_freq_up(void)
277 {
278         int ret;
279
280         /* test with an invalid lcore id */
281         ret = rte_power_freq_up(TEST_POWER_LCORE_INVALID);
282         if (ret >= 0) {
283                 printf("Unexpectedly scale up successfully the freq on %u\n",
284                                                 TEST_POWER_LCORE_INVALID);
285                 return -1;
286         }
287
288         /* Scale down to min and then scale up one step */
289         ret = rte_power_freq_min(TEST_POWER_LCORE_ID);
290         if (ret < 0) {
291                 printf("Fail to scale down the freq to min on lcore %u\n",
292                                                         TEST_POWER_LCORE_ID);
293                 return -1;
294         }
295         ret = rte_power_freq_up(TEST_POWER_LCORE_ID);
296         if (ret < 0) {
297                 printf("Fail to scale up the freq on lcore %u\n",
298                                                 TEST_POWER_LCORE_ID);
299                 return -1;
300         }
301
302         /* Check the current frequency */
303         ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 2);
304         if (ret < 0)
305                 return -1;
306
307         /* Scale up to max and then scale up one step */
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         ret = rte_power_freq_up(TEST_POWER_LCORE_ID);
315         if (ret < 0) {
316                 printf("Fail to scale up the freq on lcore %u\n",
317                                                 TEST_POWER_LCORE_ID);
318                 return -1;
319         }
320
321         /* Check the current frequency */
322         ret = check_cur_freq(TEST_POWER_LCORE_ID, 0);
323         if (ret < 0)
324                 return -1;
325
326         return 0;
327 }
328
329 /* Check rte_power_freq_max() */
330 static int
331 check_power_freq_max(void)
332 {
333         int ret;
334
335         /* test with an invalid lcore id */
336         ret = rte_power_freq_max(TEST_POWER_LCORE_INVALID);
337         if (ret >= 0) {
338                 printf("Unexpectedly scale up successfully the freq to max on "
339                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
340                 return -1;
341         }
342         ret = rte_power_freq_max(TEST_POWER_LCORE_ID);
343         if (ret < 0) {
344                 printf("Fail to scale up the freq to max on lcore %u\n",
345                                                 TEST_POWER_LCORE_ID);
346                 return -1;
347         }
348
349         /* Check the current frequency */
350         ret = check_cur_freq(TEST_POWER_LCORE_ID, 0);
351         if (ret < 0)
352                 return -1;
353
354         return 0;
355 }
356
357 /* Check rte_power_freq_min() */
358 static int
359 check_power_freq_min(void)
360 {
361         int ret;
362
363         /* test with an invalid lcore id */
364         ret = rte_power_freq_min(TEST_POWER_LCORE_INVALID);
365         if (ret >= 0) {
366                 printf("Unexpectedly scale down successfully the freq to min "
367                                 "on lcore %u\n", TEST_POWER_LCORE_INVALID);
368                 return -1;
369         }
370         ret = rte_power_freq_min(TEST_POWER_LCORE_ID);
371         if (ret < 0) {
372                 printf("Fail to scale down the freq to min on lcore %u\n",
373                                                         TEST_POWER_LCORE_ID);
374                 return -1;
375         }
376
377         /* Check the current frequency */
378         ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1);
379         if (ret < 0)
380                 return -1;
381
382         return 0;
383 }
384
385 int
386 test_power(void)
387 {
388         int ret = -1;
389
390         /* test of init power management for an invalid lcore */
391         ret = rte_power_init(TEST_POWER_LCORE_INVALID);
392         if (ret == 0) {
393                 printf("Unexpectedly initialise power management successfully "
394                                 "for lcore %u\n", TEST_POWER_LCORE_INVALID);
395                 return -1;
396         }
397
398         ret = rte_power_init(TEST_POWER_LCORE_ID);
399         if (ret < 0) {
400                 printf("Cannot initialise power management for lcore %u\n",
401                                                         TEST_POWER_LCORE_ID);
402                 return -1;
403         }
404
405         /**
406          * test of initialising power management for the lcore which has
407          * been initialised
408          */
409         ret = rte_power_init(TEST_POWER_LCORE_ID);
410         if (ret == 0) {
411                 printf("Unexpectedly init successfully power twice on "
412                                         "lcore %u\n", TEST_POWER_LCORE_ID);
413                 return -1;
414         }
415
416         ret = check_power_freqs();
417         if (ret < 0)
418                 goto fail_all;
419
420         ret = check_power_get_freq();
421         if (ret < 0)
422                 goto fail_all;
423
424         ret = check_power_set_freq();
425         if (ret < 0)
426                 goto fail_all;
427
428         ret = check_power_freq_down();
429         if (ret < 0)
430                 goto fail_all;
431
432         ret = check_power_freq_up();
433         if (ret < 0)
434                 goto fail_all;
435
436         ret = check_power_freq_max();
437         if (ret < 0)
438                 goto fail_all;
439
440         ret = check_power_freq_min();
441         if (ret < 0)
442                 goto fail_all;
443
444         ret = rte_power_exit(TEST_POWER_LCORE_ID);
445         if (ret < 0) {
446                 printf("Cannot exit power management for lcore %u\n",
447                                                 TEST_POWER_LCORE_ID);
448                 return -1;
449         }
450
451         /**
452          * test of exiting power management for the lcore which has been exited
453          */
454         ret = rte_power_exit(TEST_POWER_LCORE_ID);
455         if (ret == 0) {
456                 printf("Unexpectedly exit successfully power management twice "
457                                         "on lcore %u\n", TEST_POWER_LCORE_ID);
458                 return -1;
459         }
460
461         /* test of exit power management for an invalid lcore */
462         ret = rte_power_exit(TEST_POWER_LCORE_INVALID);
463         if (ret == 0) {
464                 printf("Unpectedly exit power management successfully for "
465                                 "lcore %u\n", TEST_POWER_LCORE_INVALID);
466                 return -1;
467         }
468
469         return 0;
470
471 fail_all:
472         rte_power_exit(TEST_POWER_LCORE_ID);
473
474         return -1;
475 }
476
477 #else /* RTE_LIBRTE_POWER */
478
479 int
480 test_power(void)
481 {
482         printf("The power library is not included in this build\n");
483         return 0;
484 }
485
486 #endif /* RTE_LIBRTE_POWER */
487