Commit fa86ee90 authored by Marcelo Tosatti's avatar Marcelo Tosatti Committed by Rafael J. Wysocki
Browse files

add cpuidle-haltpoll driver



Add a cpuidle driver that calls the architecture default_idle routine.

To be used in conjunction with the haltpoll governor.

Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 609488bc
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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

+9 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
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
+68 −0
Original line number Diff line number Diff line
// 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>");