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 | choice | ||||||
| 	prompt "Preemption Model" | 	prompt "Preemption Model" | ||||||
| 	default PREEMPT_NONE | 	default PREEMPT_NONE_BEHAVIOUR | ||||||
| 
 | 
 | ||||||
| config PREEMPT_NONE | config PREEMPT_NONE_BEHAVIOUR | ||||||
| 	bool "No Forced Preemption (Server)" | 	bool "No Forced Preemption (Server)" | ||||||
|  | 	select PREEMPT_NONE if !PREEMPT_DYNAMIC | ||||||
| 	help | 	help | ||||||
| 	  This is the traditional Linux preemption model, geared towards | 	  This is the traditional Linux preemption model, geared towards | ||||||
| 	  throughput. It will still provide good latencies most of the | 	  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 | 	  raw processing power of the kernel, irrespective of scheduling | ||||||
| 	  latencies. | 	  latencies. | ||||||
| 
 | 
 | ||||||
| config PREEMPT_VOLUNTARY | config PREEMPT_VOLUNTARY_BEHAVIOUR | ||||||
| 	bool "Voluntary Kernel Preemption (Desktop)" | 	bool "Voluntary Kernel Preemption (Desktop)" | ||||||
| 	depends on !ARCH_NO_PREEMPT | 	depends on !ARCH_NO_PREEMPT | ||||||
|  | 	select PREEMPT_VOLUNTARY if !PREEMPT_DYNAMIC | ||||||
| 	help | 	help | ||||||
| 	  This option reduces the latency of the kernel by adding more | 	  This option reduces the latency of the kernel by adding more | ||||||
| 	  "explicit preemption points" to the kernel code. These new | 	  "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. | 	  Select this if you are building a kernel for a desktop system. | ||||||
| 
 | 
 | ||||||
| config PREEMPT | config PREEMPT_BEHAVIOUR | ||||||
| 	bool "Preemptible Kernel (Low-Latency Desktop)" | 	bool "Preemptible Kernel (Low-Latency Desktop)" | ||||||
| 	depends on !ARCH_NO_PREEMPT | 	depends on !ARCH_NO_PREEMPT | ||||||
| 	select PREEMPTION | 	select PREEMPT | ||||||
| 	select UNINLINE_SPIN_UNLOCK if !ARCH_INLINE_SPIN_UNLOCK |  | ||||||
| 	select PREEMPT_DYNAMIC if HAVE_PREEMPT_DYNAMIC |  | ||||||
| 	help | 	help | ||||||
| 	  This option reduces the latency of the kernel by making | 	  This option reduces the latency of the kernel by making | ||||||
| 	  all kernel code (that is not executing in a critical section) | 	  all kernel code (that is not executing in a critical section) | ||||||
|  | @ -58,7 +58,7 @@ config PREEMPT | ||||||
| 
 | 
 | ||||||
| config PREEMPT_RT | config PREEMPT_RT | ||||||
| 	bool "Fully Preemptible Kernel (Real-Time)" | 	bool "Fully Preemptible Kernel (Real-Time)" | ||||||
| 	depends on EXPERT && ARCH_SUPPORTS_RT | 	depends on EXPERT && ARCH_SUPPORTS_RT && !PREEMPT_DYNAMIC | ||||||
| 	select PREEMPTION | 	select PREEMPTION | ||||||
| 	help | 	help | ||||||
| 	  This option turns the kernel into a real-time kernel by replacing | 	  This option turns the kernel into a real-time kernel by replacing | ||||||
|  | @ -75,6 +75,17 @@ config PREEMPT_RT | ||||||
| 
 | 
 | ||||||
| endchoice | 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 | config PREEMPT_COUNT | ||||||
|        bool |        bool | ||||||
| 
 | 
 | ||||||
|  | @ -83,7 +94,10 @@ config PREEMPTION | ||||||
|        select PREEMPT_COUNT |        select PREEMPT_COUNT | ||||||
| 
 | 
 | ||||||
| config PREEMPT_DYNAMIC | config PREEMPT_DYNAMIC | ||||||
| 	bool | 	bool "Preemption behaviour defined on boot" | ||||||
|  | 	depends on HAVE_PREEMPT_DYNAMIC | ||||||
|  | 	select PREEMPT | ||||||
|  | 	default y | ||||||
| 	help | 	help | ||||||
| 	  This option allows to define the preemption model on the kernel | 	  This option allows to define the preemption model on the kernel | ||||||
| 	  command line parameter and thus override the default preemption | 	  command line parameter and thus override the default preemption | ||||||
|  |  | ||||||
|  | @ -6520,12 +6520,13 @@ EXPORT_STATIC_CALL_TRAMP(preempt_schedule_notrace); | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| enum { | enum { | ||||||
| 	preempt_dynamic_none = 0, | 	preempt_dynamic_undefined = -1, | ||||||
|  | 	preempt_dynamic_none, | ||||||
| 	preempt_dynamic_voluntary, | 	preempt_dynamic_voluntary, | ||||||
| 	preempt_dynamic_full, | 	preempt_dynamic_full, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| int preempt_dynamic_mode = preempt_dynamic_full; | int preempt_dynamic_mode = preempt_dynamic_undefined; | ||||||
| 
 | 
 | ||||||
| int sched_dynamic_mode(const char *str) | int sched_dynamic_mode(const char *str) | ||||||
| { | { | ||||||
|  | @ -6598,7 +6599,27 @@ static int __init setup_preempt_mode(char *str) | ||||||
| } | } | ||||||
| __setup("preempt=", setup_preempt_mode); | __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 |  * This is the entry point to schedule() from kernel preemption | ||||||
|  | @ -9398,6 +9419,8 @@ void __init sched_init(void) | ||||||
| 
 | 
 | ||||||
| 	init_uclamp(); | 	init_uclamp(); | ||||||
| 
 | 
 | ||||||
|  | 	preempt_dynamic_init(); | ||||||
|  | 
 | ||||||
| 	scheduler_running = 1; | 	scheduler_running = 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Frederic Weisbecker
						Frederic Weisbecker