Skip to content

Commit 73784fb

Browse files
committed
Merge tag 'pm-4.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management fixes from Rafael Wysocki: "These fix two cpufreq issues, one introduced recently and one related to recent changes, fix cpufreq documentation, fix up recently added code in the Thunderbolt driver and update runtime PM framework documentation. Specifics: - Fix the handling of the scaling_cur_freq cpufreq policy attribute on x86 systems with the MPERF/APERF registers present to make it behave more as expected after recent changes (Rafael Wysocki). - Drop a leftover callback from the intel_pstate driver which also prevents the cpuinfo_cur_freq cpufreq policy attribute from being incorrectly exposed when intel_pstate works in the active mode (Rafael Wysocki). - Add a missing piece describing the cpuinfo_cur_freq policy attribute to cpufreq documentation (Rafael Wysocki). - Fix up a recently added part of the Thunderbolt driver to avoid aborting system suspends if its mailbox commands time out (Rafael Wysocki). - Update device runtime PM framework documentation to reflect the current behavior of the code (Johan Hovold)" * tag 'pm-4.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: thunderbolt: icm: Ignore mailbox errors in icm_suspend() cpufreq: x86: Make scaling_cur_freq behave more as expected PM / runtime: Document new pm_runtime_set_suspended() constraint cpufreq: docs: Add missing cpuinfo_cur_freq description cpufreq: intel_pstate: Drop ->get from intel_pstate structure
2 parents 19ec50a + 78aa904 commit 73784fb

File tree

5 files changed

+44
-24
lines changed

5 files changed

+44
-24
lines changed

Documentation/admin-guide/pm/cpufreq.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,14 @@ are the following:
237237
This attribute is not present if the scaling driver in use does not
238238
support it.
239239

240+
``cpuinfo_cur_freq``
241+
Current frequency of the CPUs belonging to this policy as obtained from
242+
the hardware (in KHz).
243+
244+
This is expected to be the frequency the hardware actually runs at.
245+
If that frequency cannot be determined, this attribute should not
246+
be present.
247+
240248
``cpuinfo_max_freq``
241249
Maximum possible operating frequency the CPUs belonging to this policy
242250
can run at (in kHz).

Documentation/power/runtime_pm.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,8 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
435435
PM status to 'suspended' and update its parent's counter of 'active'
436436
children as appropriate (it is only valid to use this function if
437437
'power.runtime_error' is set or 'power.disable_depth' is greater than
438-
zero)
438+
zero); it will fail and return an error code if the device has a child
439+
which is active and the 'power.ignore_children' flag is unset
439440

440441
bool pm_runtime_active(struct device *dev);
441442
- return true if the device's runtime PM status is 'active' or its

arch/x86/kernel/cpu/aperfmperf.c

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,25 @@
88
* This file is licensed under GPLv2.
99
*/
1010

11-
#include <linux/jiffies.h>
11+
#include <linux/delay.h>
12+
#include <linux/ktime.h>
1213
#include <linux/math64.h>
1314
#include <linux/percpu.h>
1415
#include <linux/smp.h>
1516

1617
struct aperfmperf_sample {
1718
unsigned int khz;
18-
unsigned long jiffies;
19+
ktime_t time;
1920
u64 aperf;
2021
u64 mperf;
2122
};
2223

2324
static DEFINE_PER_CPU(struct aperfmperf_sample, samples);
2425

26+
#define APERFMPERF_CACHE_THRESHOLD_MS 10
27+
#define APERFMPERF_REFRESH_DELAY_MS 20
28+
#define APERFMPERF_STALE_THRESHOLD_MS 1000
29+
2530
/*
2631
* aperfmperf_snapshot_khz()
2732
* On the current CPU, snapshot APERF, MPERF, and jiffies
@@ -33,9 +38,11 @@ static void aperfmperf_snapshot_khz(void *dummy)
3338
u64 aperf, aperf_delta;
3439
u64 mperf, mperf_delta;
3540
struct aperfmperf_sample *s = this_cpu_ptr(&samples);
41+
ktime_t now = ktime_get();
42+
s64 time_delta = ktime_ms_delta(now, s->time);
3643

37-
/* Don't bother re-computing within 10 ms */
38-
if (time_before(jiffies, s->jiffies + HZ/100))
44+
/* Don't bother re-computing within the cache threshold time. */
45+
if (time_delta < APERFMPERF_CACHE_THRESHOLD_MS)
3946
return;
4047

4148
rdmsrl(MSR_IA32_APERF, aperf);
@@ -51,29 +58,34 @@ static void aperfmperf_snapshot_khz(void *dummy)
5158
if (mperf_delta == 0)
5259
return;
5360

54-
/*
55-
* if (cpu_khz * aperf_delta) fits into ULLONG_MAX, then
56-
* khz = (cpu_khz * aperf_delta) / mperf_delta
57-
*/
58-
if (div64_u64(ULLONG_MAX, cpu_khz) > aperf_delta)
59-
s->khz = div64_u64((cpu_khz * aperf_delta), mperf_delta);
60-
else /* khz = aperf_delta / (mperf_delta / cpu_khz) */
61-
s->khz = div64_u64(aperf_delta,
62-
div64_u64(mperf_delta, cpu_khz));
63-
s->jiffies = jiffies;
61+
s->time = now;
6462
s->aperf = aperf;
6563
s->mperf = mperf;
64+
65+
/* If the previous iteration was too long ago, discard it. */
66+
if (time_delta > APERFMPERF_STALE_THRESHOLD_MS)
67+
s->khz = 0;
68+
else
69+
s->khz = div64_u64((cpu_khz * aperf_delta), mperf_delta);
6670
}
6771

6872
unsigned int arch_freq_get_on_cpu(int cpu)
6973
{
74+
unsigned int khz;
75+
7076
if (!cpu_khz)
7177
return 0;
7278

7379
if (!static_cpu_has(X86_FEATURE_APERFMPERF))
7480
return 0;
7581

7682
smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);
83+
khz = per_cpu(samples.khz, cpu);
84+
if (khz)
85+
return khz;
86+
87+
msleep(APERFMPERF_REFRESH_DELAY_MS);
88+
smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);
7789

7890
return per_cpu(samples.khz, cpu);
7991
}

drivers/cpufreq/intel_pstate.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1922,13 +1922,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
19221922
return 0;
19231923
}
19241924

1925-
static unsigned int intel_pstate_get(unsigned int cpu_num)
1926-
{
1927-
struct cpudata *cpu = all_cpu_data[cpu_num];
1928-
1929-
return cpu ? get_avg_frequency(cpu) : 0;
1930-
}
1931-
19321925
static void intel_pstate_set_update_util_hook(unsigned int cpu_num)
19331926
{
19341927
struct cpudata *cpu = all_cpu_data[cpu_num];
@@ -2169,7 +2162,6 @@ static struct cpufreq_driver intel_pstate = {
21692162
.setpolicy = intel_pstate_set_policy,
21702163
.suspend = intel_pstate_hwp_save_state,
21712164
.resume = intel_pstate_resume,
2172-
.get = intel_pstate_get,
21732165
.init = intel_pstate_cpu_init,
21742166
.exit = intel_pstate_cpu_exit,
21752167
.stop_cpu = intel_pstate_stop_cpu,

drivers/thunderbolt/icm.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,14 @@ static int icm_driver_ready(struct tb *tb)
904904

905905
static int icm_suspend(struct tb *tb)
906906
{
907-
return nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_SAVE_DEVS, 0);
907+
int ret;
908+
909+
ret = nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_SAVE_DEVS, 0);
910+
if (ret)
911+
tb_info(tb, "Ignoring mailbox command error (%d) in %s\n",
912+
ret, __func__);
913+
914+
return 0;
908915
}
909916

910917
/*

0 commit comments

Comments
 (0)