提交 bd89b934 编写于 作者: R Rafael J. Wysocki 提交者: Yang Yingliang

Intel: cpuidle: Allow idle states to be disabled by default

mainline inclusion
from mainline-v5.6-rc1
commit 75a80267
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I47H3V
CVE: NA

--------------------------------

commit 75a80267 upstream

In certain situations it may be useful to prevent some idle states
from being used by default while allowing user space to enable them
later on.

For this purpose, introduce a new state flag, CPUIDLE_FLAG_OFF, to
mark idle states that should be disabled by default, make the core
set CPUIDLE_STATE_DISABLED_BY_USER for those states at the
initialization time and add a new state attribute in sysfs,
"default_status", to inform user space of the initial status of
the given idle state ("disabled" if CPUIDLE_FLAG_OFF is set for it,
"enabled" otherwise).
Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Nyjia <yingbao.jia@intel.com>
Signed-off-by: NJackie Liu <liuyun01@kylinos.cn>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
Reviewed-by: NHanjun Guo <guohanjun@huawei.com>
Reviewed-by: NXie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 ad57f5ca
...@@ -188,6 +188,12 @@ Description: ...@@ -188,6 +188,12 @@ Description:
does not reflect it. Likewise, if one enables a deep state but a does not reflect it. Likewise, if one enables a deep state but a
lighter state still is disabled, then this has no effect. lighter state still is disabled, then this has no effect.
What: /sys/devices/system/cpu/cpuX/cpuidle/stateN/default_status
Date: December 2019
KernelVersion: v5.6
Contact: Linux power management list <linux-pm@vger.kernel.org>
Description:
(RO) The default status of this state, "enabled" or "disabled".
What: /sys/devices/system/cpu/cpuX/cpuidle/stateN/residency What: /sys/devices/system/cpu/cpuX/cpuidle/stateN/residency
Date: March 2014 Date: March 2014
......
...@@ -534,8 +534,8 @@ static void __cpuidle_device_init(struct cpuidle_device *dev) ...@@ -534,8 +534,8 @@ static void __cpuidle_device_init(struct cpuidle_device *dev)
*/ */
static int __cpuidle_register_device(struct cpuidle_device *dev) static int __cpuidle_register_device(struct cpuidle_device *dev)
{ {
int ret;
struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
int i, ret;
if (!try_module_get(drv->owner)) if (!try_module_get(drv->owner))
return -EINVAL; return -EINVAL;
...@@ -543,6 +543,11 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) ...@@ -543,6 +543,11 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
per_cpu(cpuidle_devices, dev->cpu) = dev; per_cpu(cpuidle_devices, dev->cpu) = dev;
list_add(&dev->device_list, &cpuidle_detected_devices); list_add(&dev->device_list, &cpuidle_detected_devices);
for (i = 0; i < drv->state_count; i++) {
if (drv->states[i].flags & CPUIDLE_FLAG_OFF)
dev->states_usage[i].disable |= CPUIDLE_STATE_DISABLED_BY_USER;
}
ret = cpuidle_coupled_register_device(dev); ret = cpuidle_coupled_register_device(dev);
if (ret) if (ret)
__cpuidle_unregister_device(dev); __cpuidle_unregister_device(dev);
......
...@@ -292,6 +292,14 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, \ ...@@ -292,6 +292,14 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, \
return sprintf(buf, "%s\n", state->_name);\ return sprintf(buf, "%s\n", state->_name);\
} }
static ssize_t show_state_default_status(struct cpuidle_state *state,
struct cpuidle_state_usage *state_usage,
char *buf)
{
return sprintf(buf, "%s\n",
state->flags & CPUIDLE_FLAG_OFF ? "disabled" : "enabled");
}
define_show_state_function(exit_latency) define_show_state_function(exit_latency)
define_show_state_function(target_residency) define_show_state_function(target_residency)
define_show_state_function(power_usage) define_show_state_function(power_usage)
...@@ -310,6 +318,7 @@ define_one_state_ro(power, show_state_power_usage); ...@@ -310,6 +318,7 @@ define_one_state_ro(power, show_state_power_usage);
define_one_state_ro(usage, show_state_usage); define_one_state_ro(usage, show_state_usage);
define_one_state_ro(time, show_state_time); define_one_state_ro(time, show_state_time);
define_one_state_rw(disable, show_state_disable, store_state_disable); define_one_state_rw(disable, show_state_disable, store_state_disable);
define_one_state_ro(default_status, show_state_default_status);
static struct attribute *cpuidle_state_default_attrs[] = { static struct attribute *cpuidle_state_default_attrs[] = {
&attr_name.attr, &attr_name.attr,
...@@ -320,6 +329,7 @@ static struct attribute *cpuidle_state_default_attrs[] = { ...@@ -320,6 +329,7 @@ static struct attribute *cpuidle_state_default_attrs[] = {
&attr_usage.attr, &attr_usage.attr,
&attr_time.attr, &attr_time.attr,
&attr_disable.attr, &attr_disable.attr,
&attr_default_status.attr,
NULL NULL
}; };
......
...@@ -70,6 +70,7 @@ struct cpuidle_state { ...@@ -70,6 +70,7 @@ struct cpuidle_state {
#define CPUIDLE_FLAG_POLLING BIT(0) /* polling state */ #define CPUIDLE_FLAG_POLLING BIT(0) /* polling state */
#define CPUIDLE_FLAG_COUPLED BIT(1) /* state applies to multiple cpus */ #define CPUIDLE_FLAG_COUPLED BIT(1) /* state applies to multiple cpus */
#define CPUIDLE_FLAG_TIMER_STOP BIT(2) /* timer is stopped on this state */ #define CPUIDLE_FLAG_TIMER_STOP BIT(2) /* timer is stopped on this state */
#define CPUIDLE_FLAG_OFF BIT(4) /* disable this state by default */
struct cpuidle_device_kobj; struct cpuidle_device_kobj;
struct cpuidle_state_kobj; struct cpuidle_state_kobj;
...@@ -117,6 +118,7 @@ static inline int cpuidle_get_last_residency(struct cpuidle_device *dev) ...@@ -117,6 +118,7 @@ static inline int cpuidle_get_last_residency(struct cpuidle_device *dev)
/**************************** /****************************
* CPUIDLE DRIVER INTERFACE * * CPUIDLE DRIVER INTERFACE *
****************************/ ****************************/
#define CPUIDLE_STATE_DISABLED_BY_USER BIT(0)
struct cpuidle_driver { struct cpuidle_driver {
const char *name; const char *name;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册