linux-cpupower-6.4-rc3
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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEPZKym/RZuOCGeA/kCwJExA0NQxwFAmRlGnYACgkQCwJExA0N Qxx80A//RtYobNoT+VANs3ZWoioGF1r0l4abxRXgGOTIPe+CsPtYF1OT3eUyj1as 2VoOdt6UT4X46RkGmgcyAYJon9tVaINVVm0ssk2zyXBsbf5NyNOECuO1HAiH8f3W T15HYB+ilGpj2yH969+Ggw/sFzhPwEJQCCJvOk1/ESiL/XCp24eEsMRxYtwjMXC2 rdOCUOP1+4vXywytiraYNee4eNIae66x1Mg7+mCortQyyvXtt1VaOmlZHwk1gdgs P5kZjVwYzczNlxeQCkjaPtgOT13iqwo4+GUq1ezjSKtTXAZB4HgWYAaHKjqzOxRp STGaNwFyzF/+LkPLHwe9cgm1STGgX/LvyH/SI8hziqtJzkgTTOTxbDWh+GCtVJsR HRJdrLe2k5bEW0ygV/01ACDiOJLY3tikUhZi1wrjQ1THAbUsIGIBRCooL7/q8iUQ UsLCsOLBUI82oy3M/r0ZkLAZ3gC2aOmxPyp7AcGL17V90+2k90uZL99Ir8HJMtob FdEXztPh8x1lYhZoj1DJd1YXA/sxNG0n9CqhLJGcXkwf6L4V+uyoQlDoQrKjky9C Dvtd0cGrPaOEGoLj1ABvwFagmU1oDqkd4OeHx2bxZnpipBGLxQTAKwaBjp6+FFEk lOMPAzEU8hXVo5Bj/nNmxZmwraEzcV0WwFiLCLvOUUt5dFhZIns= =eD91 -----END PGP SIGNATURE----- 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()
This commit is contained in:
Коммит
eab866bfff
|
@ -40,25 +40,34 @@ static int sysfs_get_enabled(char *path, int *mode)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
char yes_no;
|
char yes_no;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
*mode = 0;
|
*mode = 0;
|
||||||
|
|
||||||
fd = open(path, O_RDONLY);
|
fd = open(path, O_RDONLY);
|
||||||
if (fd == -1)
|
if (fd == -1) {
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (read(fd, &yes_no, 1) != 1) {
|
if (read(fd, &yes_no, 1) != 1) {
|
||||||
close(fd);
|
ret = -1;
|
||||||
return -1;
|
goto out_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (yes_no == '1') {
|
if (yes_no == '1') {
|
||||||
*mode = 1;
|
*mode = 1;
|
||||||
return 0;
|
goto out_close;
|
||||||
} else if (yes_no == '0') {
|
} else if (yes_no == '0') {
|
||||||
return 0;
|
goto out_close;
|
||||||
|
} else {
|
||||||
|
ret = -1;
|
||||||
|
goto out_close;
|
||||||
}
|
}
|
||||||
return -1;
|
out_close:
|
||||||
|
close(fd);
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int powercap_get_enabled(int *mode)
|
int powercap_get_enabled(int *mode)
|
||||||
|
|
|
@ -70,8 +70,8 @@ static int max_freq_mode;
|
||||||
*/
|
*/
|
||||||
static unsigned long max_frequency;
|
static unsigned long max_frequency;
|
||||||
|
|
||||||
static unsigned long long tsc_at_measure_start;
|
static unsigned long long *tsc_at_measure_start;
|
||||||
static unsigned long long tsc_at_measure_end;
|
static unsigned long long *tsc_at_measure_end;
|
||||||
static unsigned long long *mperf_previous_count;
|
static unsigned long long *mperf_previous_count;
|
||||||
static unsigned long long *aperf_previous_count;
|
static unsigned long long *aperf_previous_count;
|
||||||
static unsigned long long *mperf_current_count;
|
static unsigned long long *mperf_current_count;
|
||||||
|
@ -169,7 +169,7 @@ static int mperf_get_count_percent(unsigned int id, double *percent,
|
||||||
aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];
|
aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];
|
||||||
|
|
||||||
if (max_freq_mode == MAX_FREQ_TSC_REF) {
|
if (max_freq_mode == MAX_FREQ_TSC_REF) {
|
||||||
tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
|
tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu];
|
||||||
*percent = 100.0 * mperf_diff / tsc_diff;
|
*percent = 100.0 * mperf_diff / tsc_diff;
|
||||||
dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n",
|
dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n",
|
||||||
mperf_cstates[id].name, mperf_diff, tsc_diff);
|
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,
|
||||||
|
|
||||||
if (max_freq_mode == MAX_FREQ_TSC_REF) {
|
if (max_freq_mode == MAX_FREQ_TSC_REF) {
|
||||||
/* Calculate max_freq from TSC count */
|
/* Calculate max_freq from TSC count */
|
||||||
tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
|
tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu];
|
||||||
time_diff = timespec_diff_us(time_start, time_end);
|
time_diff = timespec_diff_us(time_start, time_end);
|
||||||
max_frequency = tsc_diff / time_diff;
|
max_frequency = tsc_diff / time_diff;
|
||||||
}
|
}
|
||||||
|
@ -225,33 +225,27 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
|
||||||
static int mperf_start(void)
|
static int mperf_start(void)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
unsigned long long dbg;
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_REALTIME, &time_start);
|
clock_gettime(CLOCK_REALTIME, &time_start);
|
||||||
mperf_get_tsc(&tsc_at_measure_start);
|
|
||||||
|
|
||||||
for (cpu = 0; cpu < cpu_count; cpu++)
|
for (cpu = 0; cpu < cpu_count; cpu++) {
|
||||||
|
mperf_get_tsc(&tsc_at_measure_start[cpu]);
|
||||||
mperf_init_stats(cpu);
|
mperf_init_stats(cpu);
|
||||||
|
}
|
||||||
|
|
||||||
mperf_get_tsc(&dbg);
|
|
||||||
dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mperf_stop(void)
|
static int mperf_stop(void)
|
||||||
{
|
{
|
||||||
unsigned long long dbg;
|
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
for (cpu = 0; cpu < cpu_count; cpu++)
|
for (cpu = 0; cpu < cpu_count; cpu++) {
|
||||||
mperf_measure_stats(cpu);
|
mperf_measure_stats(cpu);
|
||||||
|
mperf_get_tsc(&tsc_at_measure_end[cpu]);
|
||||||
|
}
|
||||||
|
|
||||||
mperf_get_tsc(&tsc_at_measure_end);
|
|
||||||
clock_gettime(CLOCK_REALTIME, &time_end);
|
clock_gettime(CLOCK_REALTIME, &time_end);
|
||||||
|
|
||||||
mperf_get_tsc(&dbg);
|
|
||||||
dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,7 +347,8 @@ struct cpuidle_monitor *mperf_register(void)
|
||||||
aperf_previous_count = calloc(cpu_count, sizeof(unsigned long long));
|
aperf_previous_count = calloc(cpu_count, sizeof(unsigned long long));
|
||||||
mperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
|
mperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
|
||||||
aperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
|
aperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
|
||||||
|
tsc_at_measure_start = calloc(cpu_count, sizeof(unsigned long long));
|
||||||
|
tsc_at_measure_end = calloc(cpu_count, sizeof(unsigned long long));
|
||||||
mperf_monitor.name_len = strlen(mperf_monitor.name);
|
mperf_monitor.name_len = strlen(mperf_monitor.name);
|
||||||
return &mperf_monitor;
|
return &mperf_monitor;
|
||||||
}
|
}
|
||||||
|
@ -364,6 +359,8 @@ void mperf_unregister(void)
|
||||||
free(aperf_previous_count);
|
free(aperf_previous_count);
|
||||||
free(mperf_current_count);
|
free(mperf_current_count);
|
||||||
free(aperf_current_count);
|
free(aperf_current_count);
|
||||||
|
free(tsc_at_measure_start);
|
||||||
|
free(tsc_at_measure_end);
|
||||||
free(is_valid);
|
free(is_valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче