History

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()

Linus Torvalds committed 3 years ago

Commit d3f70432 parents c830632 5783ecc4 files · +32 −26Browse files

Unified · Split

4 files
  1. drivers/cpufreq/acpi-cpufreq.c +1 −1
  2. drivers/cpufreq/pcc-cpufreq.c +1 −1
  3. tools/power/cpupower/lib/powercap.c +16 −7
  4. tools/power/cpupower/utils/idle_monitor/mperf_monitor.c +14 −17
drivers/cpufreq/acpi-cpufreq.c+1−1
@@ -975,7 +975,7 @@ static int __init acpi_cpufreq_probe(struct platform_device *pdev) · 974 unmodified lines
975 975
976 /* don't keep reloading if cpufreq_driver exists */976 /* don't keep reloading if cpufreq_driver exists */
977 if (cpufreq_get_current_driver())977 if (cpufreq_get_current_driver())
978 return -EEXIST;978 return -ENODEV;
979 979
980 pr_debug("%s\n", __func__);980 pr_debug("%s\n", __func__);
981 981
drivers/cpufreq/pcc-cpufreq.c+1−1
@@ -583,7 +583,7 @@ static int __init pcc_cpufreq_probe(struct platform_device *pdev) · 582 unmodified lines
583 583
584 /* Skip initialization if another cpufreq driver is there. */584 /* Skip initialization if another cpufreq driver is there. */
585 if (cpufreq_get_current_driver())585 if (cpufreq_get_current_driver())
586 return -EEXIST;586 return -ENODEV;
587 587
588 if (acpi_disabled)588 if (acpi_disabled)
589 return -ENODEV;589 return -ENODEV;
tools/power/cpupower/lib/powercap.c+16−7
@@ -40,25 +40,34 @@ static int sysfs_get_enabled(char *path, int *mode) · 39 unmodified lines
40{40{
41 int fd;41 int fd;
42 char yes_no;42 char yes_no;
43 int ret = 0;
43 44
44 *mode = 0;45 *mode = 0;
45 46
46 fd = open(path, O_RDONLY);47 fd = open(path, O_RDONLY);
47 if (fd == -1)48 if (fd == -1) {
48 return -1;49 ret = -1;
50 goto out;
51 }
49 52
50 if (read(fd, &yes_no, 1) != 1) {53 if (read(fd, &yes_no, 1) != 1) {
51 close(fd);54 ret = -1;
52 return -1;55 goto out_close;
53 }56 }
54 57
55 if (yes_no == '1') {58 if (yes_no == '1') {
56 *mode = 1;59 *mode = 1;
57 return 0;60 goto out_close;
58 } else if (yes_no == '0') {61 } else if (yes_no == '0') {
59 return 0;62 goto out_close;
63 } else {
64 ret = -1;
65 goto out_close;
60 }66 }
61 return -1;67out_close:
68 close(fd);
69out:
70 return ret;
62}71}
63 72
64int powercap_get_enabled(int *mode)73int powercap_get_enabled(int *mode)
tools/power/cpupower/utils/idle_monitor/mperf_monitor.c+14−17
@@ -70,8 +70,8 @@ static int max_freq_mode; · 69 unmodified lines
70 */70 */
71static unsigned long max_frequency;71static unsigned long max_frequency;
72 72
73static unsigned long long tsc_at_measure_start;73static unsigned long long *tsc_at_measure_start;
74static unsigned long long tsc_at_measure_end;74static unsigned long long *tsc_at_measure_end;
75static unsigned long long *mperf_previous_count;75static unsigned long long *mperf_previous_count;
76static unsigned long long *aperf_previous_count;76static unsigned long long *aperf_previous_count;
77static unsigned long long *mperf_current_count;77static unsigned long long *mperf_current_count;
@@ -169,7 +169,7 @@ static int mperf_get_count_percent(unsigned int id, double *percent, · 91 unmodified lines
169 aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];169 aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];
170 170
171 if (max_freq_mode == MAX_FREQ_TSC_REF) {171 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];
173 *percent = 100.0 * mperf_diff / tsc_diff;173 *percent = 100.0 * mperf_diff / tsc_diff;
174 dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n",174 dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n",
175 mperf_cstates[id].name, mperf_diff, tsc_diff);175 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, · 30 unmodified lines
206 206
207 if (max_freq_mode == MAX_FREQ_TSC_REF) {207 if (max_freq_mode == MAX_FREQ_TSC_REF) {
208 /* Calculate max_freq from TSC count */208 /* 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];
210 time_diff = timespec_diff_us(time_start, time_end);210 time_diff = timespec_diff_us(time_start, time_end);
211 max_frequency = tsc_diff / time_diff;211 max_frequency = tsc_diff / time_diff;
212 }212 }
@@ -225,33 +225,27 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count, · 12 unmodified lines
225static int mperf_start(void)225static int mperf_start(void)
226{226{
227 int cpu;227 int cpu;
228 unsigned long long dbg;
229 228
230 clock_gettime(CLOCK_REALTIME, &time_start);229 clock_gettime(CLOCK_REALTIME, &time_start);
231 mperf_get_tsc(&tsc_at_measure_start);
232 230
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]);
234 mperf_init_stats(cpu);233 mperf_init_stats(cpu);
234 }
235 235
236 mperf_get_tsc(&dbg);
237 dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start);
238 return 0;236 return 0;
239}237}
240 238
241static int mperf_stop(void)239static int mperf_stop(void)
242{240{
243 unsigned long long dbg;
244 int cpu;241 int cpu;
245 242
246 for (cpu = 0; cpu < cpu_count; cpu++)243 for (cpu = 0; cpu < cpu_count; cpu++) {
247 mperf_measure_stats(cpu);244 mperf_measure_stats(cpu);
245 mperf_get_tsc(&tsc_at_measure_end[cpu]);
246 }
248 247
249 mperf_get_tsc(&tsc_at_measure_end);
250 clock_gettime(CLOCK_REALTIME, &time_end);248 clock_gettime(CLOCK_REALTIME, &time_end);
251
252 mperf_get_tsc(&dbg);
253 dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end);
254
255 return 0;249 return 0;
256}250}
257 251
@@ -353,7 +347,8 @@ struct cpuidle_monitor *mperf_register(void) · 95 unmodified lines
353 aperf_previous_count = calloc(cpu_count, sizeof(unsigned long long));347 aperf_previous_count = calloc(cpu_count, sizeof(unsigned long long));
354 mperf_current_count = calloc(cpu_count, sizeof(unsigned long long));348 mperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
355 aperf_current_count = calloc(cpu_count, sizeof(unsigned long long));349 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));
357 mperf_monitor.name_len = strlen(mperf_monitor.name);352 mperf_monitor.name_len = strlen(mperf_monitor.name);
358 return &mperf_monitor;353 return &mperf_monitor;
359}354}
@@ -364,6 +359,8 @@ void mperf_unregister(void) · 4 unmodified lines
364 free(aperf_previous_count);359 free(aperf_previous_count);
365 free(mperf_current_count);360 free(mperf_current_count);
366 free(aperf_current_count);361 free(aperf_current_count);
362 free(tsc_at_measure_start);
363 free(tsc_at_measure_end);
367 free(is_valid);364 free(is_valid);
368}365}
369 366