Power management fixes for v4.13-rc2
- 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). -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJZcR+XAAoJEILEb/54YlRxxeMP/0jSKXDbZzCm+CnMwteRf28/ NISgVVxKdacdMrWhTVZnNVMxpMMJWQLn4xIxvJghw2UoRscW3zFzHtz71B/bhSh/ VGW0U7sHdHBFWwFCByEu/fy0UZddQsUAsaOzjR7xnmCd7D7KOyu4AVl6QjQywmWL cmG19Vh6mFnIjBlhmlAHCP+sGb2AawPgUch1jvsP3lB1hh38DP21cXjULLTd1jFK Fd/h5w0n8vhlrLkXiDMDdsQEp+Xxo49s7GSCyEC75BHzEjrxnp3TV/fvbuHkUEr6 phZm4uCmuzLo06OPJdJDyix1jk1DDi8ZY1Xb8iIjQuVF0FOYrH1K5+IclWj2fsmL hfl6XiiQsyt6H+wN/XmpQ7nMV56y2Pj4wEEl3lrfE7/00CUmOgSBZ9MKjas/PgUx Eof8bscZu750xya1yTZ02ZYUmtGod+aEn5OXqJXV4QGT12kh0T6T3sRkH5AssZyU bZsTPBB5tLuoybVUsPKa4SazFbtfZmFZhg4U6iMFHhEVmzl+6ZZjI1aWYP1O8mZ2 sJhZHhI9LIHC0RX4OPFAGwjHG/2uTmBXOS8auzTRxCkYiudK6vRt7QZLV5lzwYFA U89cMo+3iHAy7Rh5wgG9gkwtZE2cfk+/6xMr4ED6omBsI2bsiy7Svy0+aoE8zQRG pWkDWbuuFBd2+MJ69U8/ =ORNK -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
63a8636213
|
@ -1222,8 +1222,6 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
|
||||||
|
|
||||||
spin_unlock_irq(&dev->power.lock);
|
spin_unlock_irq(&dev->power.lock);
|
||||||
|
|
||||||
dev_pm_domain_set(dev, &genpd->domain);
|
|
||||||
|
|
||||||
return gpd_data;
|
return gpd_data;
|
||||||
|
|
||||||
err_free:
|
err_free:
|
||||||
|
@ -1237,8 +1235,6 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
|
||||||
static void genpd_free_dev_data(struct device *dev,
|
static void genpd_free_dev_data(struct device *dev,
|
||||||
struct generic_pm_domain_data *gpd_data)
|
struct generic_pm_domain_data *gpd_data)
|
||||||
{
|
{
|
||||||
dev_pm_domain_set(dev, NULL);
|
|
||||||
|
|
||||||
spin_lock_irq(&dev->power.lock);
|
spin_lock_irq(&dev->power.lock);
|
||||||
|
|
||||||
dev->power.subsys_data->domain_data = NULL;
|
dev->power.subsys_data->domain_data = NULL;
|
||||||
|
@ -1275,6 +1271,8 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
dev_pm_domain_set(dev, &genpd->domain);
|
||||||
|
|
||||||
genpd->device_count++;
|
genpd->device_count++;
|
||||||
genpd->max_off_time_changed = true;
|
genpd->max_off_time_changed = true;
|
||||||
|
|
||||||
|
@ -1336,6 +1334,8 @@ static int genpd_remove_device(struct generic_pm_domain *genpd,
|
||||||
if (genpd->detach_dev)
|
if (genpd->detach_dev)
|
||||||
genpd->detach_dev(genpd, dev);
|
genpd->detach_dev(genpd, dev);
|
||||||
|
|
||||||
|
dev_pm_domain_set(dev, NULL);
|
||||||
|
|
||||||
list_del_init(&pdd->list_node);
|
list_del_init(&pdd->list_node);
|
||||||
|
|
||||||
genpd_unlock(genpd);
|
genpd_unlock(genpd);
|
||||||
|
|
|
@ -225,6 +225,9 @@ struct global_params {
|
||||||
* @vid: Stores VID limits for this CPU
|
* @vid: Stores VID limits for this CPU
|
||||||
* @pid: Stores PID parameters for this CPU
|
* @pid: Stores PID parameters for this CPU
|
||||||
* @last_sample_time: Last Sample time
|
* @last_sample_time: Last Sample time
|
||||||
|
* @aperf_mperf_shift: Number of clock cycles after aperf, merf is incremented
|
||||||
|
* This shift is a multiplier to mperf delta to
|
||||||
|
* calculate CPU busy.
|
||||||
* @prev_aperf: Last APERF value read from APERF MSR
|
* @prev_aperf: Last APERF value read from APERF MSR
|
||||||
* @prev_mperf: Last MPERF value read from MPERF MSR
|
* @prev_mperf: Last MPERF value read from MPERF MSR
|
||||||
* @prev_tsc: Last timestamp counter (TSC) value
|
* @prev_tsc: Last timestamp counter (TSC) value
|
||||||
|
@ -259,6 +262,7 @@ struct cpudata {
|
||||||
|
|
||||||
u64 last_update;
|
u64 last_update;
|
||||||
u64 last_sample_time;
|
u64 last_sample_time;
|
||||||
|
u64 aperf_mperf_shift;
|
||||||
u64 prev_aperf;
|
u64 prev_aperf;
|
||||||
u64 prev_mperf;
|
u64 prev_mperf;
|
||||||
u64 prev_tsc;
|
u64 prev_tsc;
|
||||||
|
@ -321,6 +325,7 @@ struct pstate_funcs {
|
||||||
int (*get_min)(void);
|
int (*get_min)(void);
|
||||||
int (*get_turbo)(void);
|
int (*get_turbo)(void);
|
||||||
int (*get_scaling)(void);
|
int (*get_scaling)(void);
|
||||||
|
int (*get_aperf_mperf_shift)(void);
|
||||||
u64 (*get_val)(struct cpudata*, int pstate);
|
u64 (*get_val)(struct cpudata*, int pstate);
|
||||||
void (*get_vid)(struct cpudata *);
|
void (*get_vid)(struct cpudata *);
|
||||||
void (*update_util)(struct update_util_data *data, u64 time,
|
void (*update_util)(struct update_util_data *data, u64 time,
|
||||||
|
@ -1486,6 +1491,11 @@ static u64 core_get_val(struct cpudata *cpudata, int pstate)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int knl_get_aperf_mperf_shift(void)
|
||||||
|
{
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
|
||||||
static int knl_get_turbo_pstate(void)
|
static int knl_get_turbo_pstate(void)
|
||||||
{
|
{
|
||||||
u64 value;
|
u64 value;
|
||||||
|
@ -1543,6 +1553,9 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
|
||||||
cpu->pstate.max_freq = cpu->pstate.max_pstate * cpu->pstate.scaling;
|
cpu->pstate.max_freq = cpu->pstate.max_pstate * cpu->pstate.scaling;
|
||||||
cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * cpu->pstate.scaling;
|
cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * cpu->pstate.scaling;
|
||||||
|
|
||||||
|
if (pstate_funcs.get_aperf_mperf_shift)
|
||||||
|
cpu->aperf_mperf_shift = pstate_funcs.get_aperf_mperf_shift();
|
||||||
|
|
||||||
if (pstate_funcs.get_vid)
|
if (pstate_funcs.get_vid)
|
||||||
pstate_funcs.get_vid(cpu);
|
pstate_funcs.get_vid(cpu);
|
||||||
|
|
||||||
|
@ -1616,7 +1629,8 @@ static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu)
|
||||||
int32_t busy_frac, boost;
|
int32_t busy_frac, boost;
|
||||||
int target, avg_pstate;
|
int target, avg_pstate;
|
||||||
|
|
||||||
busy_frac = div_fp(sample->mperf, sample->tsc);
|
busy_frac = div_fp(sample->mperf << cpu->aperf_mperf_shift,
|
||||||
|
sample->tsc);
|
||||||
|
|
||||||
boost = cpu->iowait_boost;
|
boost = cpu->iowait_boost;
|
||||||
cpu->iowait_boost >>= 1;
|
cpu->iowait_boost >>= 1;
|
||||||
|
@ -1675,7 +1689,8 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
|
||||||
sample_ratio = div_fp(pid_params.sample_rate_ns, duration_ns);
|
sample_ratio = div_fp(pid_params.sample_rate_ns, duration_ns);
|
||||||
perf_scaled = mul_fp(perf_scaled, sample_ratio);
|
perf_scaled = mul_fp(perf_scaled, sample_ratio);
|
||||||
} else {
|
} else {
|
||||||
sample_ratio = div_fp(100 * cpu->sample.mperf, cpu->sample.tsc);
|
sample_ratio = div_fp(100 * (cpu->sample.mperf << cpu->aperf_mperf_shift),
|
||||||
|
cpu->sample.tsc);
|
||||||
if (sample_ratio < int_tofp(1))
|
if (sample_ratio < int_tofp(1))
|
||||||
perf_scaled = 0;
|
perf_scaled = 0;
|
||||||
}
|
}
|
||||||
|
@ -1807,6 +1822,7 @@ static const struct pstate_funcs knl_funcs = {
|
||||||
.get_max_physical = core_get_max_pstate_physical,
|
.get_max_physical = core_get_max_pstate_physical,
|
||||||
.get_min = core_get_min_pstate,
|
.get_min = core_get_min_pstate,
|
||||||
.get_turbo = knl_get_turbo_pstate,
|
.get_turbo = knl_get_turbo_pstate,
|
||||||
|
.get_aperf_mperf_shift = knl_get_aperf_mperf_shift,
|
||||||
.get_scaling = core_get_scaling,
|
.get_scaling = core_get_scaling,
|
||||||
.get_val = core_get_val,
|
.get_val = core_get_val,
|
||||||
.update_util = intel_pstate_update_util_pid,
|
.update_util = intel_pstate_update_util_pid,
|
||||||
|
@ -2403,6 +2419,7 @@ static void __init copy_cpu_funcs(struct pstate_funcs *funcs)
|
||||||
pstate_funcs.get_val = funcs->get_val;
|
pstate_funcs.get_val = funcs->get_val;
|
||||||
pstate_funcs.get_vid = funcs->get_vid;
|
pstate_funcs.get_vid = funcs->get_vid;
|
||||||
pstate_funcs.update_util = funcs->update_util;
|
pstate_funcs.update_util = funcs->update_util;
|
||||||
|
pstate_funcs.get_aperf_mperf_shift = funcs->get_aperf_mperf_shift;
|
||||||
|
|
||||||
intel_pstate_use_acpi_profile();
|
intel_pstate_use_acpi_profile();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue