Skip to content

Commit c2adb18

Browse files
wkarnyshuahkh
authored andcommitted
cpupower: Make TSC read per CPU for Mperf monitor
System-wide TSC read could cause a drift in C0 percentage calculation. Because if first TSC is read and then one by one mperf is read for all cpus, this introduces drift between mperf reading of later CPUs and TSC reading. To lower this drift read TSC per CPU and also just after mperf read. This technique improves C0 percentage calculation in Mperf monitor. Before fix: (System 100% busy) | Mperf || RAPL || Idle_Stats PKG|CORE| CPU| C0 | Cx | Freq || pack | core || POLL | C1 | C2 0| 0| 0| 87.15| 12.85| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 0| 256| 84.62| 15.38| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 1| 1| 87.15| 12.85| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 1| 257| 84.08| 15.92| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 2| 2| 86.61| 13.39| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 2| 258| 83.26| 16.74| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 3| 3| 86.61| 13.39| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 3| 259| 83.60| 16.40| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 4| 4| 86.33| 13.67| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 4| 260| 83.33| 16.67| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 5| 5| 86.06| 13.94| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 5| 261| 83.05| 16.95| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 6| 6| 85.51| 14.49| 2695||168659003|3970468|| 0.00| 0.00| 0.00 After fix: (System 100% busy) | Mperf || RAPL || Idle_Stats PKG|CORE| CPU| C0 | Cx | Freq || pack | core || POLL | C1 | C2 0| 0| 0| 98.03| 1.97| 2415||163295480|3811189|| 0.00| 0.00| 0.00 0| 0| 256| 98.50| 1.50| 2394||163295480|3811189|| 0.00| 0.00| 0.00 0| 1| 1| 99.99| 0.01| 2401||163295480|3811189|| 0.00| 0.00| 0.00 0| 1| 257| 99.99| 0.01| 2375||163295480|3811189|| 0.00| 0.00| 0.00 0| 2| 2| 99.99| 0.01| 2401||163295480|3811189|| 0.00| 0.00| 0.00 0| 2| 258|100.00| 0.00| 2401||163295480|3811189|| 0.00| 0.00| 0.00 0| 3| 3|100.00| 0.00| 2401||163295480|3811189|| 0.00| 0.00| 0.00 0| 3| 259| 99.99| 0.01| 2435||163295480|3811189|| 0.00| 0.00| 0.00 0| 4| 4|100.00| 0.00| 2401||163295480|3811189|| 0.00| 0.00| 0.00 0| 4| 260|100.00| 0.00| 2435||163295480|3811189|| 0.00| 0.00| 0.00 0| 5| 5| 99.99| 0.01| 2401||163295480|3811189|| 0.00| 0.00| 0.00 0| 5| 261|100.00| 0.00| 2435||163295480|3811189|| 0.00| 0.00| 0.00 0| 6| 6|100.00| 0.00| 2401||163295480|3811189|| 0.00| 0.00| 0.00 0| 6| 262|100.00| 0.00| 2435||163295480|3811189|| 0.00| 0.00| 0.00 Cc: Thomas Renninger <trenn@suse.com> Cc: Shuah Khan <shuah@kernel.org> Cc: Dominik Brodowski <linux@dominikbrodowski.net> Fixes: 7fe2f63 ("cpupowerutils - cpufrequtils extended with quite some features") Signed-off-by: Wyes Karny <wyes.karny@amd.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
1 parent e652be0 commit c2adb18

File tree

1 file changed

+14
-17
lines changed

1 file changed

+14
-17
lines changed

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

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ static int max_freq_mode;
7070
*/
7171
static unsigned long max_frequency;
7272

73-
static unsigned long long tsc_at_measure_start;
74-
static unsigned long long tsc_at_measure_end;
73+
static unsigned long long *tsc_at_measure_start;
74+
static unsigned long long *tsc_at_measure_end;
7575
static unsigned long long *mperf_previous_count;
7676
static unsigned long long *aperf_previous_count;
7777
static unsigned long long *mperf_current_count;
@@ -169,7 +169,7 @@ static int mperf_get_count_percent(unsigned int id, double *percent,
169169
aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];
170170

171171
if (max_freq_mode == MAX_FREQ_TSC_REF) {
172-
tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
172+
tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu];
173173
*percent = 100.0 * mperf_diff / tsc_diff;
174174
dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n",
175175
mperf_cstates[id].name, mperf_diff, tsc_diff);
@@ -206,7 +206,7 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
206206

207207
if (max_freq_mode == MAX_FREQ_TSC_REF) {
208208
/* Calculate max_freq from TSC count */
209-
tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
209+
tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu];
210210
time_diff = timespec_diff_us(time_start, time_end);
211211
max_frequency = tsc_diff / time_diff;
212212
}
@@ -225,33 +225,27 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
225225
static int mperf_start(void)
226226
{
227227
int cpu;
228-
unsigned long long dbg;
229228

230229
clock_gettime(CLOCK_REALTIME, &time_start);
231-
mperf_get_tsc(&tsc_at_measure_start);
232230

233-
for (cpu = 0; cpu < cpu_count; cpu++)
231+
for (cpu = 0; cpu < cpu_count; cpu++) {
232+
mperf_get_tsc(&tsc_at_measure_start[cpu]);
234233
mperf_init_stats(cpu);
234+
}
235235

236-
mperf_get_tsc(&dbg);
237-
dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start);
238236
return 0;
239237
}
240238

241239
static int mperf_stop(void)
242240
{
243-
unsigned long long dbg;
244241
int cpu;
245242

246-
for (cpu = 0; cpu < cpu_count; cpu++)
243+
for (cpu = 0; cpu < cpu_count; cpu++) {
247244
mperf_measure_stats(cpu);
245+
mperf_get_tsc(&tsc_at_measure_end[cpu]);
246+
}
248247

249-
mperf_get_tsc(&tsc_at_measure_end);
250248
clock_gettime(CLOCK_REALTIME, &time_end);
251-
252-
mperf_get_tsc(&dbg);
253-
dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end);
254-
255249
return 0;
256250
}
257251

@@ -353,7 +347,8 @@ struct cpuidle_monitor *mperf_register(void)
353347
aperf_previous_count = calloc(cpu_count, sizeof(unsigned long long));
354348
mperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
355349
aperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
356-
350+
tsc_at_measure_start = calloc(cpu_count, sizeof(unsigned long long));
351+
tsc_at_measure_end = calloc(cpu_count, sizeof(unsigned long long));
357352
mperf_monitor.name_len = strlen(mperf_monitor.name);
358353
return &mperf_monitor;
359354
}
@@ -364,6 +359,8 @@ void mperf_unregister(void)
364359
free(aperf_previous_count);
365360
free(mperf_current_count);
366361
free(aperf_current_count);
362+
free(tsc_at_measure_start);
363+
free(tsc_at_measure_end);
367364
free(is_valid);
368365
}
369366

0 commit comments

Comments
 (0)