Message ID | 20190703235828.340866829@amt.cnet (mailing list archive) |
---|---|
State | Mainlined, archived |
Headers | show |
Series | cpuidle haltpoll driver and governor (v6) | expand |
On 7/4/19 12:51 AM, Marcelo Tosatti wrote: > +++ linux-2.6-newcpuidle.git/drivers/cpuidle/cpuidle-haltpoll.c > @@ -0,0 +1,69 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * cpuidle driver for haltpoll governor. > + * > + * Copyright 2019 Red Hat, Inc. and/or its affiliates. > + * > + * This work is licensed under the terms of the GNU GPL, version 2. See > + * the COPYING file in the top-level directory. > + * > + * Authors: Marcelo Tosatti <mtosatti@redhat.com> > + */ > + > +#include <linux/init.h> > +#include <linux/cpuidle.h> > +#include <linux/module.h> > +#include <linux/sched/idle.h> > +#include <linux/kvm_para.h> > + > +static int default_enter_idle(struct cpuidle_device *dev, > + struct cpuidle_driver *drv, int index) > +{ > + if (current_clr_polling_and_test()) { > + local_irq_enable(); > + return index; > + } > + default_idle(); > + return index; > +} > + > +static struct cpuidle_driver haltpoll_driver = { > + .name = "haltpoll", > + .owner = THIS_MODULE, > + .states = { > + { /* entry 0 is for polling */ }, > + { > + .enter = default_enter_idle, > + .exit_latency = 1, > + .target_residency = 1, > + .power_usage = -1, > + .name = "haltpoll idle", > + .desc = "default architecture idle", > + }, > + }, > + .safe_state_index = 0, > + .state_count = 2, > +}; > + > +static int __init haltpoll_init(void) > +{ > + struct cpuidle_driver *drv = &haltpoll_driver; > + > + cpuidle_poll_state_init(drv); > + > + if (!kvm_para_available()) > + return 0; > + Isn't this meant to return -ENODEV value if the module is meant to not load? Also this check should probably be placed before initializing the poll state, provided poll state isn't used anyways if you're not a kvm guest. Joao
On Thu, Jul 04, 2019 at 10:16:47AM +0100, Joao Martins wrote: > On 7/4/19 12:51 AM, Marcelo Tosatti wrote: > > +++ linux-2.6-newcpuidle.git/drivers/cpuidle/cpuidle-haltpoll.c > > @@ -0,0 +1,69 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * cpuidle driver for haltpoll governor. > > + * > > + * Copyright 2019 Red Hat, Inc. and/or its affiliates. > > + * > > + * This work is licensed under the terms of the GNU GPL, version 2. See > > + * the COPYING file in the top-level directory. > > + * > > + * Authors: Marcelo Tosatti <mtosatti@redhat.com> > > + */ > > + > > +#include <linux/init.h> > > +#include <linux/cpuidle.h> > > +#include <linux/module.h> > > +#include <linux/sched/idle.h> > > +#include <linux/kvm_para.h> > > + > > +static int default_enter_idle(struct cpuidle_device *dev, > > + struct cpuidle_driver *drv, int index) > > +{ > > + if (current_clr_polling_and_test()) { > > + local_irq_enable(); > > + return index; > > + } > > + default_idle(); > > + return index; > > +} > > + > > +static struct cpuidle_driver haltpoll_driver = { > > + .name = "haltpoll", > > + .owner = THIS_MODULE, > > + .states = { > > + { /* entry 0 is for polling */ }, > > + { > > + .enter = default_enter_idle, > > + .exit_latency = 1, > > + .target_residency = 1, > > + .power_usage = -1, > > + .name = "haltpoll idle", > > + .desc = "default architecture idle", > > + }, > > + }, > > + .safe_state_index = 0, > > + .state_count = 2, > > +}; > > + > > +static int __init haltpoll_init(void) > > +{ > > + struct cpuidle_driver *drv = &haltpoll_driver; > > + > > + cpuidle_poll_state_init(drv); > > + > > + if (!kvm_para_available()) > > + return 0; > > + > > Isn't this meant to return -ENODEV value if the module is meant to not load? Well, the cpuidle drivers return an error only if registration fails. > Also this check should probably be placed before initializing the poll state, > provided poll state isn't used anyways if you're not a kvm guest. Poll state init is only local variable initialization, it does not have any external effect.
Index: linux-2.6-newcpuidle.git/arch/x86/kernel/process.c =================================================================== --- linux-2.6-newcpuidle.git.orig/arch/x86/kernel/process.c +++ linux-2.6-newcpuidle.git/arch/x86/kernel/process.c @@ -580,7 +580,7 @@ void __cpuidle default_idle(void) safe_halt(); trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); } -#ifdef CONFIG_APM_MODULE +#if defined(CONFIG_APM_MODULE) || defined(CONFIG_HALTPOLL_CPUIDLE_MODULE) EXPORT_SYMBOL(default_idle); #endif Index: linux-2.6-newcpuidle.git/drivers/cpuidle/Kconfig =================================================================== --- linux-2.6-newcpuidle.git.orig/drivers/cpuidle/Kconfig +++ linux-2.6-newcpuidle.git/drivers/cpuidle/Kconfig @@ -51,6 +51,15 @@ depends on PPC source "drivers/cpuidle/Kconfig.powerpc" endmenu +config HALTPOLL_CPUIDLE + tristate "Halt poll cpuidle driver" + depends on X86 && KVM_GUEST + default y + help + This option enables halt poll cpuidle driver, which allows to poll + before halting in the guest (more efficient than polling in the + host via halt_poll_ns for some scenarios). + endif config ARCH_NEEDS_CPU_IDLE_COUPLED Index: linux-2.6-newcpuidle.git/drivers/cpuidle/Makefile =================================================================== --- linux-2.6-newcpuidle.git.orig/drivers/cpuidle/Makefile +++ linux-2.6-newcpuidle.git/drivers/cpuidle/Makefile @@ -7,6 +7,7 @@ obj-y += cpuidle.o driver.o governor.o s obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o obj-$(CONFIG_DT_IDLE_STATES) += dt_idle_states.o obj-$(CONFIG_ARCH_HAS_CPU_RELAX) += poll_state.o +obj-$(CONFIG_HALTPOLL_CPUIDLE) += cpuidle-haltpoll.o ################################################################################## # ARM SoC drivers Index: linux-2.6-newcpuidle.git/drivers/cpuidle/cpuidle-haltpoll.c =================================================================== --- /dev/null +++ linux-2.6-newcpuidle.git/drivers/cpuidle/cpuidle-haltpoll.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * cpuidle driver for haltpoll governor. + * + * Copyright 2019 Red Hat, Inc. and/or its affiliates. + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + * Authors: Marcelo Tosatti <mtosatti@redhat.com> + */ + +#include <linux/init.h> +#include <linux/cpuidle.h> +#include <linux/module.h> +#include <linux/sched/idle.h> +#include <linux/kvm_para.h> + +static int default_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + if (current_clr_polling_and_test()) { + local_irq_enable(); + return index; + } + default_idle(); + return index; +} + +static struct cpuidle_driver haltpoll_driver = { + .name = "haltpoll", + .owner = THIS_MODULE, + .states = { + { /* entry 0 is for polling */ }, + { + .enter = default_enter_idle, + .exit_latency = 1, + .target_residency = 1, + .power_usage = -1, + .name = "haltpoll idle", + .desc = "default architecture idle", + }, + }, + .safe_state_index = 0, + .state_count = 2, +}; + +static int __init haltpoll_init(void) +{ + struct cpuidle_driver *drv = &haltpoll_driver; + + cpuidle_poll_state_init(drv); + + if (!kvm_para_available()) + return 0; + + return cpuidle_register(&haltpoll_driver, NULL); +} + +static void __exit haltpoll_exit(void) +{ + cpuidle_unregister(&haltpoll_driver); +} + +module_init(haltpoll_init); +module_exit(haltpoll_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Marcelo Tosatti <mtosatti@redhat.com>"); +
Add a cpuidle driver that calls the architecture default_idle routine. To be used in conjunction with the haltpoll governor. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> --- arch/x86/kernel/process.c | 2 - drivers/cpuidle/Kconfig | 9 +++++ drivers/cpuidle/Makefile | 1 drivers/cpuidle/cpuidle-haltpoll.c | 65 +++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-)