提交 165097ba 编写于 作者: X Xiangyou Xie 提交者: Zheng Zengkai

cpuidle: add cpuidle-haltpoll driver module parameter

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I6404X?from=project-issue
CVE: NA

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

To ensure energy efficiency, haltpoll is disabled by default.
But In some performance scenarios, you can enable haltpoll using
the following methods:

echo Y > /sys/module/cpuidle_haltpoll/parameters/force
Signed-off-by: NXiangyou Xie <xiexiangyou@huawei.com>
Reviewed-by: NKeqian Zhu <zhukeqian1@huawei.com>
Reviewed-by: NQingqing Li <liqingqing3@huawei.com>
Reviewed-by: Nchenhui <judy.chenhui@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 6f2a1173
...@@ -18,9 +18,17 @@ ...@@ -18,9 +18,17 @@
#include <linux/kvm_para.h> #include <linux/kvm_para.h>
#include <linux/cpuidle_haltpoll.h> #include <linux/cpuidle_haltpoll.h>
static bool force __read_mostly; static bool force;
module_param(force, bool, 0444); MODULE_PARM_DESC(force, "bool, enable haltpoll driver");
MODULE_PARM_DESC(force, "Load unconditionally"); static int enable_haltpoll_driver(const char *val, const struct kernel_param *kp);
static int register_haltpoll_driver(void);
static void unregister_haltpoll_driver(void);
static const struct kernel_param_ops enable_haltpoll_ops = {
.set = enable_haltpoll_driver,
.get = param_get_bool,
};
module_param_cb(force, &enable_haltpoll_ops, &force, 0644);
static struct cpuidle_device __percpu *haltpoll_cpuidle_devices; static struct cpuidle_device __percpu *haltpoll_cpuidle_devices;
static enum cpuhp_state haltpoll_hp_state; static enum cpuhp_state haltpoll_hp_state;
...@@ -36,6 +44,42 @@ static int default_enter_idle(struct cpuidle_device *dev, ...@@ -36,6 +44,42 @@ static int default_enter_idle(struct cpuidle_device *dev,
return index; return index;
} }
static int enable_haltpoll_driver(const char *val, const struct kernel_param *kp)
{
#ifdef CONFIG_ARM64
int ret;
bool do_enable;
if (!val)
return 0;
ret = strtobool(val, &do_enable);
if (ret || force == do_enable)
return ret;
if (do_enable) {
ret = register_haltpoll_driver();
if (!ret) {
pr_info("Enable haltpoll driver.\n");
force = 1;
} else {
pr_err("Fail to enable haltpoll driver.\n");
}
} else {
unregister_haltpoll_driver();
force = 0;
pr_info("Unregister haltpoll driver.\n");
}
return ret;
#else
return -1;
#endif
}
static struct cpuidle_driver haltpoll_driver = { static struct cpuidle_driver haltpoll_driver = {
.name = "haltpoll", .name = "haltpoll",
.governor = "haltpoll", .governor = "haltpoll",
...@@ -84,22 +128,18 @@ static int haltpoll_cpu_offline(unsigned int cpu) ...@@ -84,22 +128,18 @@ static int haltpoll_cpu_offline(unsigned int cpu)
return 0; return 0;
} }
static void haltpoll_uninit(void)
{
if (haltpoll_hp_state)
cpuhp_remove_state(haltpoll_hp_state);
cpuidle_unregister_driver(&haltpoll_driver);
free_percpu(haltpoll_cpuidle_devices);
haltpoll_cpuidle_devices = NULL;
}
static bool haltpoll_want(void) static bool haltpoll_want(void)
{ {
return kvm_para_has_hint(KVM_HINTS_REALTIME); return kvm_para_has_hint(KVM_HINTS_REALTIME);
} }
static int __init haltpoll_init(void) static void haltpoll_uninit(void)
{
unregister_haltpoll_driver();
}
static int register_haltpoll_driver(void)
{ {
int ret; int ret;
struct cpuidle_driver *drv = &haltpoll_driver; struct cpuidle_driver *drv = &haltpoll_driver;
...@@ -112,9 +152,6 @@ static int __init haltpoll_init(void) ...@@ -112,9 +152,6 @@ static int __init haltpoll_init(void)
cpuidle_poll_state_init(drv); cpuidle_poll_state_init(drv);
if (!force && (!kvm_para_available() || !haltpoll_want()))
return -ENODEV;
ret = cpuidle_register_driver(drv); ret = cpuidle_register_driver(drv);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -137,9 +174,35 @@ static int __init haltpoll_init(void) ...@@ -137,9 +174,35 @@ static int __init haltpoll_init(void)
return ret; return ret;
} }
static void unregister_haltpoll_driver(void)
{
if (haltpoll_hp_state)
cpuhp_remove_state(haltpoll_hp_state);
cpuidle_unregister_driver(&haltpoll_driver);
free_percpu(haltpoll_cpuidle_devices);
haltpoll_cpuidle_devices = NULL;
}
static int __init haltpoll_init(void)
{
int ret = 0;
#ifdef CONFIG_X86
/* Do not load haltpoll if idle= is passed */
if (boot_option_idle_override != IDLE_NO_OVERRIDE)
return -ENODEV;
#endif
if (force || (haltpoll_want() && kvm_para_available()))
ret = register_haltpoll_driver();
return ret;
}
static void __exit haltpoll_exit(void) static void __exit haltpoll_exit(void)
{ {
haltpoll_uninit(); if (haltpoll_cpuidle_devices)
haltpoll_uninit();
} }
module_init(haltpoll_init); module_init(haltpoll_init);
......
...@@ -39,7 +39,7 @@ module_param(guest_halt_poll_grow_start, uint, 0644); ...@@ -39,7 +39,7 @@ module_param(guest_halt_poll_grow_start, uint, 0644);
static bool guest_halt_poll_allow_shrink __read_mostly = true; static bool guest_halt_poll_allow_shrink __read_mostly = true;
module_param(guest_halt_poll_allow_shrink, bool, 0644); module_param(guest_halt_poll_allow_shrink, bool, 0644);
static bool enable __read_mostly; static bool enable __read_mostly = true;
module_param(enable, bool, 0444); module_param(enable, bool, 0444);
MODULE_PARM_DESC(enable, "Load unconditionally"); MODULE_PARM_DESC(enable, "Load unconditionally");
...@@ -144,7 +144,7 @@ static struct cpuidle_governor haltpoll_governor = { ...@@ -144,7 +144,7 @@ static struct cpuidle_governor haltpoll_governor = {
static int __init init_haltpoll(void) static int __init init_haltpoll(void)
{ {
if (kvm_para_available() || enable) if (enable)
return cpuidle_register_governor(&haltpoll_governor); return cpuidle_register_governor(&haltpoll_governor);
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册