forked from mirrors/linux
		
	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: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
		
							parent
							
								
									609488bc97
								
							
						
					
					
						commit
						fa86ee90eb
					
				
					 4 changed files with 79 additions and 1 deletions
				
			
		|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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
									
								
								drivers/cpuidle/cpuidle-haltpoll.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								drivers/cpuidle/cpuidle-haltpoll.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,68 @@ | |||
| // 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>"); | ||||
		Loading…
	
		Reference in a new issue
	
	 Marcelo Tosatti
						Marcelo Tosatti