Skip to content

Commit 63a8636

Browse files
committed
Merge tag 'pm-4.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management fixes from Rafael Wysocki: "These are two stable-candidate fixes for the intel_pstate driver and the generic power domains (genpd) framework. Specifics: - Fix the average CPU load computations in the intel_pstate driver on Knights Landing (Xeon Phi) processors that require an extra factor to compensate for a rate change differences between the TSC and MPERF which is missing (Srinivas Pandruvada). - Fix an initialization ordering issue in the generic power domains (genpd) framework (Sudeep Holla)" * tag 'pm-4.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: PM / Domains: defer dev_pm_domain_set() until genpd->attach_dev succeeds if present cpufreq: intel_pstate: Correct the busy calculation for KNL
2 parents 54a7d50 + ffa64d5 commit 63a8636

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed

drivers/base/power/domain.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,8 +1222,6 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
12221222

12231223
spin_unlock_irq(&dev->power.lock);
12241224

1225-
dev_pm_domain_set(dev, &genpd->domain);
1226-
12271225
return gpd_data;
12281226

12291227
err_free:
@@ -1237,8 +1235,6 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
12371235
static void genpd_free_dev_data(struct device *dev,
12381236
struct generic_pm_domain_data *gpd_data)
12391237
{
1240-
dev_pm_domain_set(dev, NULL);
1241-
12421238
spin_lock_irq(&dev->power.lock);
12431239

12441240
dev->power.subsys_data->domain_data = NULL;
@@ -1275,6 +1271,8 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
12751271
if (ret)
12761272
goto out;
12771273

1274+
dev_pm_domain_set(dev, &genpd->domain);
1275+
12781276
genpd->device_count++;
12791277
genpd->max_off_time_changed = true;
12801278

@@ -1336,6 +1334,8 @@ static int genpd_remove_device(struct generic_pm_domain *genpd,
13361334
if (genpd->detach_dev)
13371335
genpd->detach_dev(genpd, dev);
13381336

1337+
dev_pm_domain_set(dev, NULL);
1338+
13391339
list_del_init(&pdd->list_node);
13401340

13411341
genpd_unlock(genpd);

drivers/cpufreq/intel_pstate.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ struct global_params {
225225
* @vid: Stores VID limits for this CPU
226226
* @pid: Stores PID parameters for this CPU
227227
* @last_sample_time: Last Sample time
228+
* @aperf_mperf_shift: Number of clock cycles after aperf, merf is incremented
229+
* This shift is a multiplier to mperf delta to
230+
* calculate CPU busy.
228231
* @prev_aperf: Last APERF value read from APERF MSR
229232
* @prev_mperf: Last MPERF value read from MPERF MSR
230233
* @prev_tsc: Last timestamp counter (TSC) value
@@ -259,6 +262,7 @@ struct cpudata {
259262

260263
u64 last_update;
261264
u64 last_sample_time;
265+
u64 aperf_mperf_shift;
262266
u64 prev_aperf;
263267
u64 prev_mperf;
264268
u64 prev_tsc;
@@ -321,6 +325,7 @@ struct pstate_funcs {
321325
int (*get_min)(void);
322326
int (*get_turbo)(void);
323327
int (*get_scaling)(void);
328+
int (*get_aperf_mperf_shift)(void);
324329
u64 (*get_val)(struct cpudata*, int pstate);
325330
void (*get_vid)(struct cpudata *);
326331
void (*update_util)(struct update_util_data *data, u64 time,
@@ -1486,6 +1491,11 @@ static u64 core_get_val(struct cpudata *cpudata, int pstate)
14861491
return val;
14871492
}
14881493

1494+
static int knl_get_aperf_mperf_shift(void)
1495+
{
1496+
return 10;
1497+
}
1498+
14891499
static int knl_get_turbo_pstate(void)
14901500
{
14911501
u64 value;
@@ -1543,6 +1553,9 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
15431553
cpu->pstate.max_freq = cpu->pstate.max_pstate * cpu->pstate.scaling;
15441554
cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * cpu->pstate.scaling;
15451555

1556+
if (pstate_funcs.get_aperf_mperf_shift)
1557+
cpu->aperf_mperf_shift = pstate_funcs.get_aperf_mperf_shift();
1558+
15461559
if (pstate_funcs.get_vid)
15471560
pstate_funcs.get_vid(cpu);
15481561

@@ -1616,7 +1629,8 @@ static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu)
16161629
int32_t busy_frac, boost;
16171630
int target, avg_pstate;
16181631

1619-
busy_frac = div_fp(sample->mperf, sample->tsc);
1632+
busy_frac = div_fp(sample->mperf << cpu->aperf_mperf_shift,
1633+
sample->tsc);
16201634

16211635
boost = cpu->iowait_boost;
16221636
cpu->iowait_boost >>= 1;
@@ -1675,7 +1689,8 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
16751689
sample_ratio = div_fp(pid_params.sample_rate_ns, duration_ns);
16761690
perf_scaled = mul_fp(perf_scaled, sample_ratio);
16771691
} else {
1678-
sample_ratio = div_fp(100 * cpu->sample.mperf, cpu->sample.tsc);
1692+
sample_ratio = div_fp(100 * (cpu->sample.mperf << cpu->aperf_mperf_shift),
1693+
cpu->sample.tsc);
16791694
if (sample_ratio < int_tofp(1))
16801695
perf_scaled = 0;
16811696
}
@@ -1807,6 +1822,7 @@ static const struct pstate_funcs knl_funcs = {
18071822
.get_max_physical = core_get_max_pstate_physical,
18081823
.get_min = core_get_min_pstate,
18091824
.get_turbo = knl_get_turbo_pstate,
1825+
.get_aperf_mperf_shift = knl_get_aperf_mperf_shift,
18101826
.get_scaling = core_get_scaling,
18111827
.get_val = core_get_val,
18121828
.update_util = intel_pstate_update_util_pid,
@@ -2403,6 +2419,7 @@ static void __init copy_cpu_funcs(struct pstate_funcs *funcs)
24032419
pstate_funcs.get_val = funcs->get_val;
24042420
pstate_funcs.get_vid = funcs->get_vid;
24052421
pstate_funcs.update_util = funcs->update_util;
2422+
pstate_funcs.get_aperf_mperf_shift = funcs->get_aperf_mperf_shift;
24062423

24072424
intel_pstate_use_acpi_profile();
24082425
}

0 commit comments

Comments
 (0)