Skip to content

Commit eab866b

Browse files
committed
Merge tag 'linux-cpupower-6.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux
Pull cpupower utility fixes for 6.4-rc3 from Shuah Khan: "This cpupower fixes update for Linux 67.4-rc3 consists of: - a resource leak fix - fix drift in C0 percentage calculation due to System-wide TSC read. To lower this drift read TSC per CPU and also just after mperf read. This technique improves C0 percentage calculation in Mperf monitor" * tag 'linux-cpupower-6.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux: cpupower: Make TSC read per CPU for Mperf monitor cpupower:Fix resource leaks in sysfs_get_enabled()
2 parents f1fcbaa + c2adb18 commit eab866b

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)