Commit d3f70431 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pm-6.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

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()
parents c8306329 5783ecc9
......@@ -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__);
......
......@@ -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;
......
......@@ -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)
......
......@@ -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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment