Skip to content

Commit

Permalink
Merge branches 'pm-cpuidle', 'pm-cpufreq' and 'pm-devfreq'
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rafaeljw committed Jan 8, 2024
4 parents 4ee4ffc + c8f5cae + e956c88 + bfd7b2d commit 0b055cf
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 37 deletions.
3 changes: 3 additions & 0 deletions Documentation/ABI/testing/sysfs-class-devfreq
Original file line number Diff line number Diff line change
Expand Up @@ -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 <[email protected]>
Expand Down
4 changes: 2 additions & 2 deletions drivers/cpufreq/armada-8k-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand Down
15 changes: 8 additions & 7 deletions drivers/cpufreq/intel_pstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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.
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 5 additions & 2 deletions drivers/cpufreq/scmi-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 4 additions & 5 deletions drivers/cpuidle/cpuidle-haltpoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
80 changes: 59 additions & 21 deletions drivers/devfreq/devfreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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);
Expand All @@ -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);

Expand All @@ -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);
Expand Down Expand Up @@ -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;

Expand All @@ -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 &&
Expand All @@ -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 += sysfs_emit_at(buf, len, " From : To\n");
len += sysfs_emit_at(buf, len, " :");
for (i = 0; i < max_state; i++) {
if (len >= PAGE_SIZE - 1)
break;
len += sysfs_emit_at(buf, len, "%10lu",
df->freq_table[i]);
}

len += sprintf(buf + len, " time(ms)\n");
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 (df->freq_table[i] == df->previous_freq)
len += sprintf(buf + len, "*");
if (len >= PAGE_SIZE - 1)
break;
if (df->freq_table[2] == df->previous_freq)
len += sysfs_emit_at(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",
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]));
}

len += sprintf(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;
}

Expand Down
114 changes: 114 additions & 0 deletions drivers/idle/intel_idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
};
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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),
Expand All @@ -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),
{}
};

Expand Down

0 comments on commit 0b055cf

Please sign in to comment.