Merge branches 'pm-cpuidle', 'pm-cpufreq' and 'pm-devfreq'
Merge cpuidle, cpufreq and devfreq updates for 6.8-rc1: - Add support for the Sierra Forest, Grand Ridge and Meteorlake SoCs to the intel_idle cpuidle driver (Artem Bityutskiy, Zhang Rui). - Do not enable interrupts when entering idle in the haltpoll cpuidle driver (Borislav Petkov). - Add Emerald Rapids support in no-HWP mode to the intel_pstate cpufreq driver (Zhenguo Yao). - Use EPP values programmed by the platform firmware as balance performance ones by default in intel_pstate (Srinivas Pandruvada). - Add a missing function return value check to the SCMI cpufreq driver to avoid unexpected behavior (Alexandra Diupina). - Fix parameter type warning in the armada-8k cpufreq driver (Gregory CLEMENT). - Rework trans_stat_show() in the devfreq core code to avoid buffer overflows (Christian Marangi). - Synchronize devfreq_monitor_[start/stop] so as to prevent a timer list corruption from occurring when devfreq governors are switched frequently (Mukesh Ojha). * pm-cpuidle: cpuidle: haltpoll: Do not enable interrupts when entering idle intel_idle: add Sierra Forest SoC support intel_idle: add Grand Ridge SoC support intel_idle: Add Meteorlake support * pm-cpufreq: cpufreq: intel_pstate: Add Emerald Rapids support in no-HWP mode cpufreq: armada-8k: Fix parameter type warning cpufreq: scmi: process the result of devm_of_clk_add_hw_provider() cpufreq: intel_pstate: Prioritize firmware-provided balance performance EPP * pm-devfreq: PM / devfreq: Synchronize devfreq_monitor_[start/stop] PM / devfreq: Convert to use sysfs_emit_at() API PM / devfreq: Fix buffer overflow in trans_stat_show
This commit is contained in:
@@ -52,6 +52,9 @@ Description:
|
||||
|
||||
echo 0 > /sys/class/devfreq/.../trans_stat
|
||||
|
||||
If the transition table is bigger than PAGE_SIZE, reading
|
||||
this will return an -EFBIG error.
|
||||
|
||||
What: /sys/class/devfreq/.../available_frequencies
|
||||
Date: October 2012
|
||||
Contact: Nishanth Menon <nm@ti.com>
|
||||
|
||||
@@ -57,7 +57,7 @@ static void __init armada_8k_get_sharing_cpus(struct clk *cur_clk,
|
||||
continue;
|
||||
}
|
||||
|
||||
clk = clk_get(cpu_dev, 0);
|
||||
clk = clk_get(cpu_dev, NULL);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_warn("Cannot get clock for CPU %d\n", cpu);
|
||||
} else {
|
||||
@@ -165,7 +165,7 @@ static int __init armada_8k_cpufreq_init(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
clk = clk_get(cpu_dev, 0);
|
||||
clk = clk_get(cpu_dev, NULL);
|
||||
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("Cannot get clock for CPU %d\n", cpu);
|
||||
|
||||
@@ -1691,13 +1691,6 @@ static void intel_pstate_update_epp_defaults(struct cpudata *cpudata)
|
||||
{
|
||||
cpudata->epp_default = intel_pstate_get_epp(cpudata, 0);
|
||||
|
||||
/*
|
||||
* If this CPU gen doesn't call for change in balance_perf
|
||||
* EPP return.
|
||||
*/
|
||||
if (epp_values[EPP_INDEX_BALANCE_PERFORMANCE] == HWP_EPP_BALANCE_PERFORMANCE)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If the EPP is set by firmware, which means that firmware enabled HWP
|
||||
* - Is equal or less than 0x80 (default balance_perf EPP)
|
||||
@@ -1710,6 +1703,13 @@ static void intel_pstate_update_epp_defaults(struct cpudata *cpudata)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this CPU gen doesn't call for change in balance_perf
|
||||
* EPP return.
|
||||
*/
|
||||
if (epp_values[EPP_INDEX_BALANCE_PERFORMANCE] == HWP_EPP_BALANCE_PERFORMANCE)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Use hard coded value per gen to update the balance_perf
|
||||
* and default EPP.
|
||||
@@ -2406,6 +2406,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
|
||||
X86_MATCH(ICELAKE_X, core_funcs),
|
||||
X86_MATCH(TIGERLAKE, core_funcs),
|
||||
X86_MATCH(SAPPHIRERAPIDS_X, core_funcs),
|
||||
X86_MATCH(EMERALDRAPIDS_X, core_funcs),
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids);
|
||||
|
||||
@@ -334,8 +334,11 @@ static int scmi_cpufreq_probe(struct scmi_device *sdev)
|
||||
|
||||
#ifdef CONFIG_COMMON_CLK
|
||||
/* dummy clock provider as needed by OPP if clocks property is used */
|
||||
if (of_property_present(dev->of_node, "#clock-cells"))
|
||||
devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL);
|
||||
if (of_property_present(dev->of_node, "#clock-cells")) {
|
||||
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "%s: registering clock provider failed\n", __func__);
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = cpufreq_register_driver(&scmi_cpufreq_driver);
|
||||
|
||||
@@ -25,13 +25,12 @@ MODULE_PARM_DESC(force, "Load unconditionally");
|
||||
static struct cpuidle_device __percpu *haltpoll_cpuidle_devices;
|
||||
static enum cpuhp_state haltpoll_hp_state;
|
||||
|
||||
static int default_enter_idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index)
|
||||
static __cpuidle int default_enter_idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index)
|
||||
{
|
||||
if (current_clr_polling_and_test()) {
|
||||
local_irq_enable();
|
||||
if (current_clr_polling_and_test())
|
||||
return index;
|
||||
}
|
||||
|
||||
arch_cpu_idle();
|
||||
return index;
|
||||
}
|
||||
|
||||
+64
-26
@@ -461,10 +461,14 @@ static void devfreq_monitor(struct work_struct *work)
|
||||
if (err)
|
||||
dev_err(&devfreq->dev, "dvfs failed with (%d) error\n", err);
|
||||
|
||||
if (devfreq->stop_polling)
|
||||
goto out;
|
||||
|
||||
queue_delayed_work(devfreq_wq, &devfreq->work,
|
||||
msecs_to_jiffies(devfreq->profile->polling_ms));
|
||||
mutex_unlock(&devfreq->lock);
|
||||
|
||||
out:
|
||||
mutex_unlock(&devfreq->lock);
|
||||
trace_devfreq_monitor(devfreq);
|
||||
}
|
||||
|
||||
@@ -483,6 +487,10 @@ void devfreq_monitor_start(struct devfreq *devfreq)
|
||||
if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN))
|
||||
return;
|
||||
|
||||
mutex_lock(&devfreq->lock);
|
||||
if (delayed_work_pending(&devfreq->work))
|
||||
goto out;
|
||||
|
||||
switch (devfreq->profile->timer) {
|
||||
case DEVFREQ_TIMER_DEFERRABLE:
|
||||
INIT_DEFERRABLE_WORK(&devfreq->work, devfreq_monitor);
|
||||
@@ -491,12 +499,16 @@ void devfreq_monitor_start(struct devfreq *devfreq)
|
||||
INIT_DELAYED_WORK(&devfreq->work, devfreq_monitor);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (devfreq->profile->polling_ms)
|
||||
queue_delayed_work(devfreq_wq, &devfreq->work,
|
||||
msecs_to_jiffies(devfreq->profile->polling_ms));
|
||||
|
||||
out:
|
||||
devfreq->stop_polling = false;
|
||||
mutex_unlock(&devfreq->lock);
|
||||
}
|
||||
EXPORT_SYMBOL(devfreq_monitor_start);
|
||||
|
||||
@@ -513,6 +525,14 @@ void devfreq_monitor_stop(struct devfreq *devfreq)
|
||||
if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN))
|
||||
return;
|
||||
|
||||
mutex_lock(&devfreq->lock);
|
||||
if (devfreq->stop_polling) {
|
||||
mutex_unlock(&devfreq->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
devfreq->stop_polling = true;
|
||||
mutex_unlock(&devfreq->lock);
|
||||
cancel_delayed_work_sync(&devfreq->work);
|
||||
}
|
||||
EXPORT_SYMBOL(devfreq_monitor_stop);
|
||||
@@ -1688,7 +1708,7 @@ static ssize_t trans_stat_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct devfreq *df = to_devfreq(dev);
|
||||
ssize_t len;
|
||||
ssize_t len = 0;
|
||||
int i, j;
|
||||
unsigned int max_state;
|
||||
|
||||
@@ -1697,7 +1717,7 @@ static ssize_t trans_stat_show(struct device *dev,
|
||||
max_state = df->max_state;
|
||||
|
||||
if (max_state == 0)
|
||||
return sprintf(buf, "Not Supported.\n");
|
||||
return sysfs_emit(buf, "Not Supported.\n");
|
||||
|
||||
mutex_lock(&df->lock);
|
||||
if (!df->stop_polling &&
|
||||
@@ -1707,31 +1727,49 @@ static ssize_t trans_stat_show(struct device *dev,
|
||||
}
|
||||
mutex_unlock(&df->lock);
|
||||
|
||||
len = sprintf(buf, " From : To\n");
|
||||
len += sprintf(buf + len, " :");
|
||||
for (i = 0; i < max_state; i++)
|
||||
len += sprintf(buf + len, "%10lu",
|
||||
df->freq_table[i]);
|
||||
|
||||
len += sprintf(buf + len, " time(ms)\n");
|
||||
|
||||
len += sysfs_emit_at(buf, len, " From : To\n");
|
||||
len += sysfs_emit_at(buf, len, " :");
|
||||
for (i = 0; i < max_state; i++) {
|
||||
if (df->freq_table[i] == df->previous_freq)
|
||||
len += sprintf(buf + len, "*");
|
||||
else
|
||||
len += sprintf(buf + len, " ");
|
||||
|
||||
len += sprintf(buf + len, "%10lu:", df->freq_table[i]);
|
||||
for (j = 0; j < max_state; j++)
|
||||
len += sprintf(buf + len, "%10u",
|
||||
df->stats.trans_table[(i * max_state) + j]);
|
||||
|
||||
len += sprintf(buf + len, "%10llu\n", (u64)
|
||||
jiffies64_to_msecs(df->stats.time_in_state[i]));
|
||||
if (len >= PAGE_SIZE - 1)
|
||||
break;
|
||||
len += sysfs_emit_at(buf, len, "%10lu",
|
||||
df->freq_table[i]);
|
||||
}
|
||||
|
||||
if (len >= PAGE_SIZE - 1)
|
||||
return PAGE_SIZE - 1;
|
||||
len += sysfs_emit_at(buf, len, " time(ms)\n");
|
||||
|
||||
for (i = 0; i < max_state; i++) {
|
||||
if (len >= PAGE_SIZE - 1)
|
||||
break;
|
||||
if (df->freq_table[2] == df->previous_freq)
|
||||
len += sysfs_emit_at(buf, len, "*");
|
||||
else
|
||||
len += sysfs_emit_at(buf, len, " ");
|
||||
if (len >= PAGE_SIZE - 1)
|
||||
break;
|
||||
len += sysfs_emit_at(buf, len, "%10lu:", df->freq_table[i]);
|
||||
for (j = 0; j < max_state; j++) {
|
||||
if (len >= PAGE_SIZE - 1)
|
||||
break;
|
||||
len += sysfs_emit_at(buf, len, "%10u",
|
||||
df->stats.trans_table[(i * max_state) + j]);
|
||||
}
|
||||
if (len >= PAGE_SIZE - 1)
|
||||
break;
|
||||
len += sysfs_emit_at(buf, len, "%10llu\n", (u64)
|
||||
jiffies64_to_msecs(df->stats.time_in_state[i]));
|
||||
}
|
||||
|
||||
if (len < PAGE_SIZE - 1)
|
||||
len += sysfs_emit_at(buf, len, "Total transition : %u\n",
|
||||
df->stats.total_trans);
|
||||
if (len >= PAGE_SIZE - 1) {
|
||||
pr_warn_once("devfreq transition table exceeds PAGE_SIZE. Disabling\n");
|
||||
return -EFBIG;
|
||||
}
|
||||
|
||||
len += sprintf(buf + len, "Total transition : %u\n",
|
||||
df->stats.total_trans);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
@@ -923,6 +923,35 @@ static struct cpuidle_state adl_l_cstates[] __initdata = {
|
||||
.enter = NULL }
|
||||
};
|
||||
|
||||
static struct cpuidle_state mtl_l_cstates[] __initdata = {
|
||||
{
|
||||
.name = "C1E",
|
||||
.desc = "MWAIT 0x01",
|
||||
.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
|
||||
.exit_latency = 1,
|
||||
.target_residency = 1,
|
||||
.enter = &intel_idle,
|
||||
.enter_s2idle = intel_idle_s2idle, },
|
||||
{
|
||||
.name = "C6",
|
||||
.desc = "MWAIT 0x20",
|
||||
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
|
||||
.exit_latency = 140,
|
||||
.target_residency = 420,
|
||||
.enter = &intel_idle,
|
||||
.enter_s2idle = intel_idle_s2idle, },
|
||||
{
|
||||
.name = "C10",
|
||||
.desc = "MWAIT 0x60",
|
||||
.flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
|
||||
.exit_latency = 310,
|
||||
.target_residency = 930,
|
||||
.enter = &intel_idle,
|
||||
.enter_s2idle = intel_idle_s2idle, },
|
||||
{
|
||||
.enter = NULL }
|
||||
};
|
||||
|
||||
static struct cpuidle_state gmt_cstates[] __initdata = {
|
||||
{
|
||||
.name = "C1",
|
||||
@@ -1242,6 +1271,72 @@ static struct cpuidle_state snr_cstates[] __initdata = {
|
||||
.enter = NULL }
|
||||
};
|
||||
|
||||
static struct cpuidle_state grr_cstates[] __initdata = {
|
||||
{
|
||||
.name = "C1",
|
||||
.desc = "MWAIT 0x00",
|
||||
.flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_ALWAYS_ENABLE,
|
||||
.exit_latency = 1,
|
||||
.target_residency = 1,
|
||||
.enter = &intel_idle,
|
||||
.enter_s2idle = intel_idle_s2idle, },
|
||||
{
|
||||
.name = "C1E",
|
||||
.desc = "MWAIT 0x01",
|
||||
.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
|
||||
.exit_latency = 2,
|
||||
.target_residency = 10,
|
||||
.enter = &intel_idle,
|
||||
.enter_s2idle = intel_idle_s2idle, },
|
||||
{
|
||||
.name = "C6S",
|
||||
.desc = "MWAIT 0x22",
|
||||
.flags = MWAIT2flg(0x22) | CPUIDLE_FLAG_TLB_FLUSHED,
|
||||
.exit_latency = 140,
|
||||
.target_residency = 500,
|
||||
.enter = &intel_idle,
|
||||
.enter_s2idle = intel_idle_s2idle, },
|
||||
{
|
||||
.enter = NULL }
|
||||
};
|
||||
|
||||
static struct cpuidle_state srf_cstates[] __initdata = {
|
||||
{
|
||||
.name = "C1",
|
||||
.desc = "MWAIT 0x00",
|
||||
.flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_ALWAYS_ENABLE,
|
||||
.exit_latency = 1,
|
||||
.target_residency = 1,
|
||||
.enter = &intel_idle,
|
||||
.enter_s2idle = intel_idle_s2idle, },
|
||||
{
|
||||
.name = "C1E",
|
||||
.desc = "MWAIT 0x01",
|
||||
.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
|
||||
.exit_latency = 2,
|
||||
.target_residency = 10,
|
||||
.enter = &intel_idle,
|
||||
.enter_s2idle = intel_idle_s2idle, },
|
||||
{
|
||||
.name = "C6S",
|
||||
.desc = "MWAIT 0x22",
|
||||
.flags = MWAIT2flg(0x22) | CPUIDLE_FLAG_TLB_FLUSHED,
|
||||
.exit_latency = 270,
|
||||
.target_residency = 700,
|
||||
.enter = &intel_idle,
|
||||
.enter_s2idle = intel_idle_s2idle, },
|
||||
{
|
||||
.name = "C6SP",
|
||||
.desc = "MWAIT 0x23",
|
||||
.flags = MWAIT2flg(0x23) | CPUIDLE_FLAG_TLB_FLUSHED,
|
||||
.exit_latency = 310,
|
||||
.target_residency = 900,
|
||||
.enter = &intel_idle,
|
||||
.enter_s2idle = intel_idle_s2idle, },
|
||||
{
|
||||
.enter = NULL }
|
||||
};
|
||||
|
||||
static const struct idle_cpu idle_cpu_nehalem __initconst = {
|
||||
.state_table = nehalem_cstates,
|
||||
.auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE,
|
||||
@@ -1349,6 +1444,10 @@ static const struct idle_cpu idle_cpu_adl_l __initconst = {
|
||||
.state_table = adl_l_cstates,
|
||||
};
|
||||
|
||||
static const struct idle_cpu idle_cpu_mtl_l __initconst = {
|
||||
.state_table = mtl_l_cstates,
|
||||
};
|
||||
|
||||
static const struct idle_cpu idle_cpu_gmt __initconst = {
|
||||
.state_table = gmt_cstates,
|
||||
};
|
||||
@@ -1387,6 +1486,18 @@ static const struct idle_cpu idle_cpu_snr __initconst = {
|
||||
.use_acpi = true,
|
||||
};
|
||||
|
||||
static const struct idle_cpu idle_cpu_grr __initconst = {
|
||||
.state_table = grr_cstates,
|
||||
.disable_promotion_to_c1e = true,
|
||||
.use_acpi = true,
|
||||
};
|
||||
|
||||
static const struct idle_cpu idle_cpu_srf __initconst = {
|
||||
.state_table = srf_cstates,
|
||||
.disable_promotion_to_c1e = true,
|
||||
.use_acpi = true,
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id intel_idle_ids[] __initconst = {
|
||||
X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EP, &idle_cpu_nhx),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(NEHALEM, &idle_cpu_nehalem),
|
||||
@@ -1423,6 +1534,7 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = {
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &idle_cpu_icx),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &idle_cpu_adl),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &idle_cpu_adl_l),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE_L, &idle_cpu_mtl_l),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ATOM_GRACEMONT, &idle_cpu_gmt),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &idle_cpu_spr),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, &idle_cpu_spr),
|
||||
@@ -1432,6 +1544,8 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = {
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS, &idle_cpu_bxt),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D, &idle_cpu_dnv),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &idle_cpu_snr),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ATOM_CRESTMONT, &idle_cpu_grr),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ATOM_CRESTMONT_X, &idle_cpu_srf),
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user