Message ID | 20190613225022.932697232@redhat.com (mailing list archive) |
---|---|
State | Changes Requested, archived |
Headers | show |
Series | cpuidle haltpoll driver and governor (v4) | expand |
On Fri, Jun 14, 2019 at 12:55 AM Marcelo Tosatti <mtosatti@redhat.com> wrote: > > 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(-) > > Index: linux-2.6.git/arch/x86/kernel/process.c > =================================================================== > --- linux-2.6.git.orig/arch/x86/kernel/process.c 2019-06-13 16:19:27.877064340 -0400 > +++ linux-2.6.git/arch/x86/kernel/process.c 2019-06-13 16:19:48.795544892 -0400 > @@ -580,7 +580,7 @@ > 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.git/drivers/cpuidle/Kconfig > =================================================================== > --- linux-2.6.git.orig/drivers/cpuidle/Kconfig 2019-06-13 16:19:27.878064316 -0400 > +++ linux-2.6.git/drivers/cpuidle/Kconfig 2019-06-13 18:41:40.599912671 -0400 > @@ -51,6 +51,15 @@ > source "drivers/cpuidle/Kconfig.powerpc" > endmenu > > +config HALTPOLL_CPUIDLE > + tristate "Halt poll cpuidle driver" > + depends on X86 > + 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.git/drivers/cpuidle/Makefile > =================================================================== > --- linux-2.6.git.orig/drivers/cpuidle/Makefile 2019-06-13 16:19:27.878064316 -0400 > +++ linux-2.6.git/drivers/cpuidle/Makefile 2019-06-13 16:19:48.796544867 -0400 > @@ -7,6 +7,7 @@ > 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.git/drivers/cpuidle/cpuidle-haltpoll.c > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ linux-2.6.git/drivers/cpuidle/cpuidle-haltpoll.c 2019-06-13 18:41:39.305933413 -0400 > @@ -0,0 +1,65 @@ > +// 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> > + > +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 = 0, > + .target_residency = 0, > + .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); > + > + return cpuidle_register(&haltpoll_driver, NULL); Would it be practical to prevent this driver from loading on non-virt? > +} > + > +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>"); > + Apart from the above it is simple enough.
On Fri, Jun 14, 2019 at 12:55 AM Marcelo Tosatti <mtosatti@redhat.com> wrote: > > 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(-) > > Index: linux-2.6.git/arch/x86/kernel/process.c > =================================================================== > --- linux-2.6.git.orig/arch/x86/kernel/process.c 2019-06-13 16:19:27.877064340 -0400 > +++ linux-2.6.git/arch/x86/kernel/process.c 2019-06-13 16:19:48.795544892 -0400 > @@ -580,7 +580,7 @@ > 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.git/drivers/cpuidle/Kconfig > =================================================================== > --- linux-2.6.git.orig/drivers/cpuidle/Kconfig 2019-06-13 16:19:27.878064316 -0400 > +++ linux-2.6.git/drivers/cpuidle/Kconfig 2019-06-13 18:41:40.599912671 -0400 > @@ -51,6 +51,15 @@ > source "drivers/cpuidle/Kconfig.powerpc" > endmenu > > +config HALTPOLL_CPUIDLE > + tristate "Halt poll cpuidle driver" > + depends on X86 > + 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.git/drivers/cpuidle/Makefile > =================================================================== > --- linux-2.6.git.orig/drivers/cpuidle/Makefile 2019-06-13 16:19:27.878064316 -0400 > +++ linux-2.6.git/drivers/cpuidle/Makefile 2019-06-13 16:19:48.796544867 -0400 > @@ -7,6 +7,7 @@ > 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.git/drivers/cpuidle/cpuidle-haltpoll.c > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ linux-2.6.git/drivers/cpuidle/cpuidle-haltpoll.c 2019-06-13 18:41:39.305933413 -0400 > @@ -0,0 +1,65 @@ > +// 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> > + > +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 = 0, > + .target_residency = 0, On a second thought, I think that you need a target residency of at least 1 (and an exit latency of at least 1) here to distinguish this state from the polling one. And if they both really were 0, polling wouldn't be needed at all ... > + .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); > + > + 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>"); > + > >
Index: linux-2.6.git/arch/x86/kernel/process.c =================================================================== --- linux-2.6.git.orig/arch/x86/kernel/process.c 2019-06-13 16:19:27.877064340 -0400 +++ linux-2.6.git/arch/x86/kernel/process.c 2019-06-13 16:19:48.795544892 -0400 @@ -580,7 +580,7 @@ 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.git/drivers/cpuidle/Kconfig =================================================================== --- linux-2.6.git.orig/drivers/cpuidle/Kconfig 2019-06-13 16:19:27.878064316 -0400 +++ linux-2.6.git/drivers/cpuidle/Kconfig 2019-06-13 18:41:40.599912671 -0400 @@ -51,6 +51,15 @@ source "drivers/cpuidle/Kconfig.powerpc" endmenu +config HALTPOLL_CPUIDLE + tristate "Halt poll cpuidle driver" + depends on X86 + 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.git/drivers/cpuidle/Makefile =================================================================== --- linux-2.6.git.orig/drivers/cpuidle/Makefile 2019-06-13 16:19:27.878064316 -0400 +++ linux-2.6.git/drivers/cpuidle/Makefile 2019-06-13 16:19:48.796544867 -0400 @@ -7,6 +7,7 @@ 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.git/drivers/cpuidle/cpuidle-haltpoll.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.git/drivers/cpuidle/cpuidle-haltpoll.c 2019-06-13 18:41:39.305933413 -0400 @@ -0,0 +1,65 @@ +// 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> + +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 = 0, + .target_residency = 0, + .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); + + 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(-)