aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-05-19 11:44:08 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2023-05-19 11:44:08 -0700
commitd3f704310cc7e04e89d178ea080a2e74dae9db67 (patch)
tree21410e1e53c38306d4c4a71f347fabf31e3399a4
parentc83063298b206dc806a7f1e8724336e4962daeed (diff)
parent5783ecc90e24a870a563b1acbfd13cad3786e519 (diff)
downloadlinux-master.tar.gz
Merge tag 'pm-6.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pmHEADmaster
Pull power management fixes from Rafael Wysocki: "These fix two issues in the cpupower utility and get rid of a spurious warning message printed to the kernel log by the ACPI cpufreq driver after recent changes. Specifics: - Get rid of a warning message printed by the ACPI cpufreq driver after recent changes in it when anohter CPU performance scaling driver is registered already when it starts (Petr Pavlu) - Make cpupower 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 the sysfs_get_enabled() function in cpupower (Hao Zeng)" * tag 'pm-6.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: cpufreq: ACPI: Prevent a warning when another frequency driver is loaded cpupower: Make TSC read per CPU for Mperf monitor cpupower:Fix resource leaks in sysfs_get_enabled()
-rw-r--r--drivers/cpufreq/acpi-cpufreq.c2
-rw-r--r--drivers/cpufreq/pcc-cpufreq.c2
-rw-r--r--tools/power/cpupower/lib/powercap.c23
-rw-r--r--tools/power/cpupower/utils/idle_monitor/mperf_monitor.c31
4 files changed, 32 insertions, 26 deletions
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index 29904395e95f9c..b2f05d27167e39 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -975,7 +975,7 @@ static int __init acpi_cpufreq_probe(struct platform_device *pdev)
/* don't keep reloading if cpufreq_driver exists */
if (cpufreq_get_current_driver())
- return -EEXIST;
+ return -ENODEV;
pr_debug("%s\n", __func__);
diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c
index 1d2cfea9858afc..73efbcf5513b2c 100644
--- a/drivers/cpufreq/pcc-cpufreq.c
+++ b/drivers/cpufreq/pcc-cpufreq.c
@@ -583,7 +583,7 @@ static int __init pcc_cpufreq_probe(struct platform_device *pdev)
/* Skip initialization if another cpufreq driver is there. */
if (cpufreq_get_current_driver())
- return -EEXIST;
+ return -ENODEV;
if (acpi_disabled)
return -ENODEV;
diff --git a/tools/power/cpupower/lib/powercap.c b/tools/power/cpupower/lib/powercap.c
index 0ce29ee4c2e463..a7a59c6bacda81 100644
--- a/tools/power/cpupower/lib/powercap.c
+++ b/tools/power/cpupower/lib/powercap.c
@@ -40,25 +40,34 @@ static int sysfs_get_enabled(char *path, int *mode)
{
int fd;
char yes_no;
+ int ret = 0;
*mode = 0;
fd = open(path, O_RDONLY);
- if (fd == -1)
- return -1;
+ if (fd == -1) {
+ ret = -1;
+ goto out;
+ }
if (read(fd, &yes_no, 1) != 1) {
- close(fd);
- return -1;
+ ret = -1;
+ goto out_close;
}
if (yes_no == '1') {
*mode = 1;
- return 0;
+ goto out_close;
} 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)
diff --git a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
index e7d48cb563c0ef..ae6af354a81db5 100644
--- a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
+++ b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
@@ -70,8 +70,8 @@ static int max_freq_mode;
*/
static unsigned long max_frequency;
-static unsigned long long tsc_at_measure_start;
-static unsigned long long tsc_at_measure_end;
+static unsigned long long *tsc_at_measure_start;
+static unsigned long long *tsc_at_measure_end;
static unsigned long long *mperf_previous_count;
static unsigned long long *aperf_previous_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];
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;
dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n",
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) {
/* 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);
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)
{
int cpu;
- unsigned long long dbg;
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_get_tsc(&dbg);
- dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start);
return 0;
}
static int mperf_stop(void)
{
- unsigned long long dbg;
int cpu;
- for (cpu = 0; cpu < cpu_count; cpu++)
+ for (cpu = 0; cpu < cpu_count; 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);
-
- mperf_get_tsc(&dbg);
- dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end);
-
return 0;
}
@@ -353,7 +347,8 @@ struct cpuidle_monitor *mperf_register(void)
aperf_previous_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));
-
+ 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);
return &mperf_monitor;
}
@@ -364,6 +359,8 @@ void mperf_unregister(void)
free(aperf_previous_count);
free(mperf_current_count);
free(aperf_current_count);
+ free(tsc_at_measure_start);
+ free(tsc_at_measure_end);
free(is_valid);
}