forked from mirrors/linux
		
	sched: Provide Kconfig support for default dynamic preempt mode
Currently the boot defined preempt behaviour (aka dynamic preempt) selects full preemption by default when the "preempt=" boot parameter is omitted. However distros may rather want to default to either no preemption or voluntary preemption. To provide with this flexibility, make dynamic preemption a visible Kconfig option and adapt the preemption behaviour selected by the user to either static or dynamic preemption. Signed-off-by: Frederic Weisbecker <frederic@kernel.org> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/20210914103134.11309-1-frederic@kernel.org
This commit is contained in:
		
							parent
							
								
									32ed980c30
								
							
						
					
					
						commit
						c597bfddc9
					
				
					 2 changed files with 49 additions and 12 deletions
				
			
		|  | @ -2,10 +2,11 @@ | |||
| 
 | ||||
| choice | ||||
| 	prompt "Preemption Model" | ||||
| 	default PREEMPT_NONE | ||||
| 	default PREEMPT_NONE_BEHAVIOUR | ||||
| 
 | ||||
| config PREEMPT_NONE | ||||
| config PREEMPT_NONE_BEHAVIOUR | ||||
| 	bool "No Forced Preemption (Server)" | ||||
| 	select PREEMPT_NONE if !PREEMPT_DYNAMIC | ||||
| 	help | ||||
| 	  This is the traditional Linux preemption model, geared towards | ||||
| 	  throughput. It will still provide good latencies most of the | ||||
|  | @ -17,9 +18,10 @@ config PREEMPT_NONE | |||
| 	  raw processing power of the kernel, irrespective of scheduling | ||||
| 	  latencies. | ||||
| 
 | ||||
| config PREEMPT_VOLUNTARY | ||||
| config PREEMPT_VOLUNTARY_BEHAVIOUR | ||||
| 	bool "Voluntary Kernel Preemption (Desktop)" | ||||
| 	depends on !ARCH_NO_PREEMPT | ||||
| 	select PREEMPT_VOLUNTARY if !PREEMPT_DYNAMIC | ||||
| 	help | ||||
| 	  This option reduces the latency of the kernel by adding more | ||||
| 	  "explicit preemption points" to the kernel code. These new | ||||
|  | @ -35,12 +37,10 @@ config PREEMPT_VOLUNTARY | |||
| 
 | ||||
| 	  Select this if you are building a kernel for a desktop system. | ||||
| 
 | ||||
| config PREEMPT | ||||
| config PREEMPT_BEHAVIOUR | ||||
| 	bool "Preemptible Kernel (Low-Latency Desktop)" | ||||
| 	depends on !ARCH_NO_PREEMPT | ||||
| 	select PREEMPTION | ||||
| 	select UNINLINE_SPIN_UNLOCK if !ARCH_INLINE_SPIN_UNLOCK | ||||
| 	select PREEMPT_DYNAMIC if HAVE_PREEMPT_DYNAMIC | ||||
| 	select PREEMPT | ||||
| 	help | ||||
| 	  This option reduces the latency of the kernel by making | ||||
| 	  all kernel code (that is not executing in a critical section) | ||||
|  | @ -58,7 +58,7 @@ config PREEMPT | |||
| 
 | ||||
| config PREEMPT_RT | ||||
| 	bool "Fully Preemptible Kernel (Real-Time)" | ||||
| 	depends on EXPERT && ARCH_SUPPORTS_RT | ||||
| 	depends on EXPERT && ARCH_SUPPORTS_RT && !PREEMPT_DYNAMIC | ||||
| 	select PREEMPTION | ||||
| 	help | ||||
| 	  This option turns the kernel into a real-time kernel by replacing | ||||
|  | @ -75,6 +75,17 @@ config PREEMPT_RT | |||
| 
 | ||||
| endchoice | ||||
| 
 | ||||
| config PREEMPT_NONE | ||||
| 	bool | ||||
| 
 | ||||
| config PREEMPT_VOLUNTARY | ||||
| 	bool | ||||
| 
 | ||||
| config PREEMPT | ||||
| 	bool | ||||
| 	select PREEMPTION | ||||
| 	select UNINLINE_SPIN_UNLOCK if !ARCH_INLINE_SPIN_UNLOCK | ||||
| 
 | ||||
| config PREEMPT_COUNT | ||||
|        bool | ||||
| 
 | ||||
|  | @ -83,7 +94,10 @@ config PREEMPTION | |||
|        select PREEMPT_COUNT | ||||
| 
 | ||||
| config PREEMPT_DYNAMIC | ||||
| 	bool | ||||
| 	bool "Preemption behaviour defined on boot" | ||||
| 	depends on HAVE_PREEMPT_DYNAMIC | ||||
| 	select PREEMPT | ||||
| 	default y | ||||
| 	help | ||||
| 	  This option allows to define the preemption model on the kernel | ||||
| 	  command line parameter and thus override the default preemption | ||||
|  |  | |||
|  | @ -6520,12 +6520,13 @@ EXPORT_STATIC_CALL_TRAMP(preempt_schedule_notrace); | |||
|  */ | ||||
| 
 | ||||
| enum { | ||||
| 	preempt_dynamic_none = 0, | ||||
| 	preempt_dynamic_undefined = -1, | ||||
| 	preempt_dynamic_none, | ||||
| 	preempt_dynamic_voluntary, | ||||
| 	preempt_dynamic_full, | ||||
| }; | ||||
| 
 | ||||
| int preempt_dynamic_mode = preempt_dynamic_full; | ||||
| int preempt_dynamic_mode = preempt_dynamic_undefined; | ||||
| 
 | ||||
| int sched_dynamic_mode(const char *str) | ||||
| { | ||||
|  | @ -6598,7 +6599,27 @@ static int __init setup_preempt_mode(char *str) | |||
| } | ||||
| __setup("preempt=", setup_preempt_mode); | ||||
| 
 | ||||
| #endif /* CONFIG_PREEMPT_DYNAMIC */ | ||||
| static void __init preempt_dynamic_init(void) | ||||
| { | ||||
| 	if (preempt_dynamic_mode == preempt_dynamic_undefined) { | ||||
| 		if (IS_ENABLED(CONFIG_PREEMPT_NONE_BEHAVIOUR)) { | ||||
| 			sched_dynamic_update(preempt_dynamic_none); | ||||
| 		} else if (IS_ENABLED(CONFIG_PREEMPT_VOLUNTARY_BEHAVIOUR)) { | ||||
| 			sched_dynamic_update(preempt_dynamic_voluntary); | ||||
| 		} else { | ||||
| 			/* Default static call setting, nothing to do */ | ||||
| 			WARN_ON_ONCE(!IS_ENABLED(CONFIG_PREEMPT_BEHAVIOUR)); | ||||
| 			preempt_dynamic_mode = preempt_dynamic_full; | ||||
| 			pr_info("Dynamic Preempt: full\n"); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #else /* !CONFIG_PREEMPT_DYNAMIC */ | ||||
| 
 | ||||
| static inline void preempt_dynamic_init(void) { } | ||||
| 
 | ||||
| #endif /* #ifdef CONFIG_PREEMPT_DYNAMIC */ | ||||
| 
 | ||||
| /*
 | ||||
|  * This is the entry point to schedule() from kernel preemption | ||||
|  | @ -9398,6 +9419,8 @@ void __init sched_init(void) | |||
| 
 | ||||
| 	init_uclamp(); | ||||
| 
 | ||||
| 	preempt_dynamic_init(); | ||||
| 
 | ||||
| 	scheduler_running = 1; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Frederic Weisbecker
						Frederic Weisbecker