Skip to content

Commit

Permalink
sched: Provide Kconfig support for default dynamic preempt mode
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Frederic Weisbecker authored and Peter Zijlstra committed Oct 5, 2021
1 parent 32ed980 commit c597bfd
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 12 deletions.
32 changes: 23 additions & 9 deletions kernel/Kconfig.preempt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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

Expand All @@ -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
Expand Down
29 changes: 26 additions & 3 deletions kernel/sched/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -9398,6 +9419,8 @@ void __init sched_init(void)

init_uclamp();

preempt_dynamic_init();

scheduler_running = 1;
}

Expand Down

0 comments on commit c597bfd

Please sign in to comment.