aboutsummaryrefslogtreecommitdiffstats
path: root/tools/power/cpupower/utils
diff options
context:
space:
mode:
authorPrarit Bhargava <prarit@redhat.com>2014-04-24 10:32:07 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-05-06 18:19:06 -0400
commite091abc7f92b45010992df1ceb5da023d8faf13b (patch)
tree526d39f91334dbbf2c1d9600a546bd3cbae127f2 /tools/power/cpupower/utils
parent3482124a6a22c631df23958df497f000ba0e1667 (diff)
PM / tools: cpupower: add option to display values without round offs
The command "cpupower frequency-info" can be used when using cpupower to monitor and test processor behaviour to determine if the processor is behaving as expected. This data can be compared to the output of /proc/cpuinfo or the output of /sys/devices/system/cpu/cpuX/cpufreq/scaling_available_frequencies to determine if the cpu is in an expected state. When doing this I noticed comparison test failures due to the way the data is displayed in cpupower. For example, [root@intel-s3e37-02 cpupower]# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies 2262000 2261000 2128000 1995000 1862000 1729000 1596000 1463000 1330000 1197000 1064000 compared to [root@intel-s3e37-02 cpupower]# cpupower frequency-info analyzing CPU 0: driver: acpi-cpufreq CPUs which run at the same hardware frequency: 0 CPUs which need to have their frequency coordinated by software: 0 maximum transition latency: 10.0 us. hardware limits: 1.06 GHz - 2.26 GHz available frequency steps: 2.26 GHz, 2.26 GHz, 2.13 GHz, 2.00 GHz, 1.86 GHz, 1.73 GHz, 1.60 GHz, 1.46 GHz, 1.33 GHz, 1.20 GHz, 1.06 GHz available cpufreq governors: conservative, userspace, powersave, ondemand, performance current policy: frequency should be within 1.06 GHz and 2.26 GHz. The governor "performance" may decide which speed to use within this range. current CPU frequency is 2.26 GHz (asserted by call to hardware). boost state support: Supported: yes Active: yes shows very different values for the available frequency steps. The cpupower output rounds off values at 2 decimal points and this causes problems with test scripts. For example, with the data above, 1.064 is 1.06 1.197 is 1.20 1.596 is 1.60 1.995 is 2.00 2.128 is 2.13 and most confusingly, 2.261 is 2.26 2.262 is 2.26 Truncating these values serves no real purpose other than making the output pretty. Since the default has been to round off these values I am adding a -n/--no-rounding option to the cpupower utility that will display the data without rounding off the still significant digits. After patch, analyzing CPU 0: driver: acpi-cpufreq CPUs which run at the same hardware frequency: 0 CPUs which need to have their frequency coordinated by software: 0 maximum transition latency: 10.000 us. hardware limits: 1.064000 GHz - 2.262000 GHz available frequency steps: 2.262000 GHz, 2.261000 GHz, 2.128000 GHz, 1.995000 GHz, 1.862000 GHz, 1.729000 GHz, 1.596000 GHz, 1.463000 GHz, 1.330000 GHz, 1.197000 GHz, 1.064000 GHz available cpufreq governors: conservative, userspace, powersave, ondemand, performance current policy: frequency should be within 1.064000 GHz and 2.262000 GHz. The governor "performance" may decide which speed to use within this range. current CPU frequency is 2.262000 GHz (asserted by call to hardware). boost state support: Supported: yes Active: yes Acked-by: Thomas Renninger <trenn@suse.de> Signed-off-by: Prarit Bhargava <prarit@redhat.com> [rjw: Subject] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'tools/power/cpupower/utils')
-rw-r--r--tools/power/cpupower/utils/cpufreq-info.c110
1 files changed, 70 insertions, 40 deletions
diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c
index 28953c9a7bd5..b4b90a97662c 100644
--- a/tools/power/cpupower/utils/cpufreq-info.c
+++ b/tools/power/cpupower/utils/cpufreq-info.c
@@ -82,29 +82,42 @@ static void proc_cpufreq_output(void)
82 } 82 }
83} 83}
84 84
85static int no_rounding;
85static void print_speed(unsigned long speed) 86static void print_speed(unsigned long speed)
86{ 87{
87 unsigned long tmp; 88 unsigned long tmp;
88 89
89 if (speed > 1000000) { 90 if (no_rounding) {
90 tmp = speed % 10000; 91 if (speed > 1000000)
91 if (tmp >= 5000) 92 printf("%u.%06u GHz", ((unsigned int) speed/1000000),
92 speed += 10000; 93 ((unsigned int) speed%1000000));
93 printf("%u.%02u GHz", ((unsigned int) speed/1000000), 94 else if (speed > 100000)
94 ((unsigned int) (speed%1000000)/10000)); 95 printf("%u MHz", (unsigned int) speed);
95 } else if (speed > 100000) { 96 else if (speed > 1000)
96 tmp = speed % 1000; 97 printf("%u.%03u MHz", ((unsigned int) speed/1000),
97 if (tmp >= 500) 98 (unsigned int) (speed%1000));
98 speed += 1000; 99 else
99 printf("%u MHz", ((unsigned int) speed / 1000)); 100 printf("%lu kHz", speed);
100 } else if (speed > 1000) { 101 } else {
101 tmp = speed % 100; 102 if (speed > 1000000) {
102 if (tmp >= 50) 103 tmp = speed%10000;
103 speed += 100; 104 if (tmp >= 5000)
104 printf("%u.%01u MHz", ((unsigned int) speed/1000), 105 speed += 10000;
105 ((unsigned int) (speed%1000)/100)); 106 printf("%u.%02u GHz", ((unsigned int) speed/1000000),
106 } else 107 ((unsigned int) (speed%1000000)/10000));
107 printf("%lu kHz", speed); 108 } else if (speed > 100000) {
109 tmp = speed%1000;
110 if (tmp >= 500)
111 speed += 1000;
112 printf("%u MHz", ((unsigned int) speed/1000));
113 } else if (speed > 1000) {
114 tmp = speed%100;
115 if (tmp >= 50)
116 speed += 100;
117 printf("%u.%01u MHz", ((unsigned int) speed/1000),
118 ((unsigned int) (speed%1000)/100));
119 }
120 }
108 121
109 return; 122 return;
110} 123}
@@ -113,26 +126,38 @@ static void print_duration(unsigned long duration)
113{ 126{
114 unsigned long tmp; 127 unsigned long tmp;
115 128
116 if (duration > 1000000) { 129 if (no_rounding) {
117 tmp = duration % 10000; 130 if (duration > 1000000)
118 if (tmp >= 5000) 131 printf("%u.%06u ms", ((unsigned int) duration/1000000),
119 duration += 10000; 132 ((unsigned int) duration%1000000));
120 printf("%u.%02u ms", ((unsigned int) duration/1000000), 133 else if (duration > 100000)
121 ((unsigned int) (duration%1000000)/10000)); 134 printf("%u us", ((unsigned int) duration/1000));
122 } else if (duration > 100000) { 135 else if (duration > 1000)
123 tmp = duration % 1000; 136 printf("%u.%03u us", ((unsigned int) duration/1000),
124 if (tmp >= 500) 137 ((unsigned int) duration%1000));
125 duration += 1000; 138 else
126 printf("%u us", ((unsigned int) duration / 1000)); 139 printf("%lu ns", duration);
127 } else if (duration > 1000) { 140 } else {
128 tmp = duration % 100; 141 if (duration > 1000000) {
129 if (tmp >= 50) 142 tmp = duration%10000;
130 duration += 100; 143 if (tmp >= 5000)
131 printf("%u.%01u us", ((unsigned int) duration/1000), 144 duration += 10000;
132 ((unsigned int) (duration%1000)/100)); 145 printf("%u.%02u ms", ((unsigned int) duration/1000000),
133 } else 146 ((unsigned int) (duration%1000000)/10000));
134 printf("%lu ns", duration); 147 } else if (duration > 100000) {
135 148 tmp = duration%1000;
149 if (tmp >= 500)
150 duration += 1000;
151 printf("%u us", ((unsigned int) duration / 1000));
152 } else if (duration > 1000) {
153 tmp = duration%100;
154 if (tmp >= 50)
155 duration += 100;
156 printf("%u.%01u us", ((unsigned int) duration/1000),
157 ((unsigned int) (duration%1000)/100));
158 } else
159 printf("%lu ns", duration);
160 }
136 return; 161 return;
137} 162}
138 163
@@ -525,6 +550,7 @@ static struct option info_opts[] = {
525 { .name = "latency", .has_arg = no_argument, .flag = NULL, .val = 'y'}, 550 { .name = "latency", .has_arg = no_argument, .flag = NULL, .val = 'y'},
526 { .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'}, 551 { .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'},
527 { .name = "human", .has_arg = no_argument, .flag = NULL, .val = 'm'}, 552 { .name = "human", .has_arg = no_argument, .flag = NULL, .val = 'm'},
553 { .name = "no-rounding", .has_arg = no_argument, .flag = NULL, .val = 'n'},
528 { }, 554 { },
529}; 555};
530 556
@@ -538,7 +564,8 @@ int cmd_freq_info(int argc, char **argv)
538 int output_param = 0; 564 int output_param = 0;
539 565
540 do { 566 do {
541 ret = getopt_long(argc, argv, "oefwldpgrasmyb", info_opts, NULL); 567 ret = getopt_long(argc, argv, "oefwldpgrasmybn", info_opts,
568 NULL);
542 switch (ret) { 569 switch (ret) {
543 case '?': 570 case '?':
544 output_param = '?'; 571 output_param = '?';
@@ -575,6 +602,9 @@ int cmd_freq_info(int argc, char **argv)
575 } 602 }
576 human = 1; 603 human = 1;
577 break; 604 break;
605 case 'n':
606 no_rounding = 1;
607 break;
578 default: 608 default:
579 fprintf(stderr, "invalid or unknown argument\n"); 609 fprintf(stderr, "invalid or unknown argument\n");
580 return EXIT_FAILURE; 610 return EXIT_FAILURE;