Skip to content

Commit 9d6c0e5

Browse files
He Rongguangshuahkh
authored andcommitted
cpupower: fix TSC MHz calculation
Commit 'cpupower: Make TSC read per CPU for Mperf monitor' (c2adb18) changes TSC counter reads per cpu, but left time diff global (from start of all cpus to end of all cpus), thus diff(time) is too large for a cpu's tsc counting, resulting in far less than acutal TSC_Mhz and thus `cpupower monitor` showing far less than actual cpu realtime frequency. /proc/cpuinfo shows frequency: cat /proc/cpuinfo | egrep -e 'processor' -e 'MHz' ... processor : 171 cpu MHz : 4108.498 ... before fix (System 100% busy): | Mperf || Idle_Stats CPU| C0 | Cx | Freq || POLL | C1 | C2 171| 0.77| 99.23| 2279|| 0.00| 0.00| 0.00 after fix (System 100% busy): | Mperf || Idle_Stats CPU| C0 | Cx | Freq || POLL | C1 | C2 171| 0.46| 99.54| 4095|| 0.00| 0.00| 0.00 Fixes: c2adb18 ("cpupower: Make TSC read per CPU for Mperf monitor") Signed-off-by: He Rongguang <herongguang@linux.alibaba.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
1 parent 46fd8c7 commit 9d6c0e5

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

tools/power/cpupower/utils/idle_monitor/mperf_monitor.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ static int mperf_get_count_percent(unsigned int self_id, double *percent,
3333
unsigned int cpu);
3434
static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
3535
unsigned int cpu);
36-
static struct timespec time_start, time_end;
36+
static struct timespec *time_start, *time_end;
3737

3838
static cstate_t mperf_cstates[MPERF_CSTATE_COUNT] = {
3939
{
@@ -174,7 +174,7 @@ static int mperf_get_count_percent(unsigned int id, double *percent,
174174
dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n",
175175
mperf_cstates[id].name, mperf_diff, tsc_diff);
176176
} else if (max_freq_mode == MAX_FREQ_SYSFS) {
177-
timediff = max_frequency * timespec_diff_us(time_start, time_end);
177+
timediff = max_frequency * timespec_diff_us(time_start[cpu], time_end[cpu]);
178178
*percent = 100.0 * mperf_diff / timediff;
179179
dprint("%s: MAXFREQ - mperf_diff: %llu, time_diff: %llu\n",
180180
mperf_cstates[id].name, mperf_diff, timediff);
@@ -207,7 +207,7 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
207207
if (max_freq_mode == MAX_FREQ_TSC_REF) {
208208
/* Calculate max_freq from TSC count */
209209
tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu];
210-
time_diff = timespec_diff_us(time_start, time_end);
210+
time_diff = timespec_diff_us(time_start[cpu], time_end[cpu]);
211211
max_frequency = tsc_diff / time_diff;
212212
}
213213

@@ -226,9 +226,8 @@ static int mperf_start(void)
226226
{
227227
int cpu;
228228

229-
clock_gettime(CLOCK_REALTIME, &time_start);
230-
231229
for (cpu = 0; cpu < cpu_count; cpu++) {
230+
clock_gettime(CLOCK_REALTIME, &time_start[cpu]);
232231
mperf_get_tsc(&tsc_at_measure_start[cpu]);
233232
mperf_init_stats(cpu);
234233
}
@@ -243,9 +242,9 @@ static int mperf_stop(void)
243242
for (cpu = 0; cpu < cpu_count; cpu++) {
244243
mperf_measure_stats(cpu);
245244
mperf_get_tsc(&tsc_at_measure_end[cpu]);
245+
clock_gettime(CLOCK_REALTIME, &time_end[cpu]);
246246
}
247247

248-
clock_gettime(CLOCK_REALTIME, &time_end);
249248
return 0;
250249
}
251250

@@ -349,6 +348,8 @@ struct cpuidle_monitor *mperf_register(void)
349348
aperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
350349
tsc_at_measure_start = calloc(cpu_count, sizeof(unsigned long long));
351350
tsc_at_measure_end = calloc(cpu_count, sizeof(unsigned long long));
351+
time_start = calloc(cpu_count, sizeof(struct timespec));
352+
time_end = calloc(cpu_count, sizeof(struct timespec));
352353
mperf_monitor.name_len = strlen(mperf_monitor.name);
353354
return &mperf_monitor;
354355
}
@@ -361,6 +362,8 @@ void mperf_unregister(void)
361362
free(aperf_current_count);
362363
free(tsc_at_measure_start);
363364
free(tsc_at_measure_end);
365+
free(time_start);
366+
free(time_end);
364367
free(is_valid);
365368
}
366369

0 commit comments

Comments
 (0)