Skip to content

Commit 5783ecc

Browse files
committed
Merge branch 'pm-tools'
Merge cpupower utility fixes for 6.4-rc3: - Read TSC on each CPU right before reading MPERF so as to reduce the potential time difference between the TSC and MPERF accesses and improve the C0 percentage calculation (Wyes Karny). - Fix a possible file handle leak and clean up the code in sysfs_get_enabled() (Hao Zeng). * pm-tools: cpupower: Make TSC read per CPU for Mperf monitor cpupower:Fix resource leaks in sysfs_get_enabled()
2 parents 73c7f82 + eab866b commit 5783ecc

File tree

2 files changed

+30
-24
lines changed

2 files changed

+30
-24
lines changed

tools/power/cpupower/lib/powercap.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,25 +40,34 @@ static int sysfs_get_enabled(char *path, int *mode)
4040
{
4141
int fd;
4242
char yes_no;
43+
int ret = 0;
4344

4445
*mode = 0;
4546

4647
fd = open(path, O_RDONLY);
47-
if (fd == -1)
48-
return -1;
48+
if (fd == -1) {
49+
ret = -1;
50+
goto out;
51+
}
4952

5053
if (read(fd, &yes_no, 1) != 1) {
51-
close(fd);
52-
return -1;
54+
ret = -1;
55+
goto out_close;
5356
}
5457

5558
if (yes_no == '1') {
5659
*mode = 1;
57-
return 0;
60+
goto out_close;
5861
} else if (yes_no == '0') {
59-
return 0;
62+
goto out_close;
63+
} else {
64+
ret = -1;
65+
goto out_close;
6066
}
61-
return -1;
67+
out_close:
68+
close(fd);
69+
out:
70+
return ret;
6271
}
6372

6473
int powercap_get_enabled(int *mode)

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)