2021-09-14 10:34:23

by Frederic Weisbecker

[permalink] [raw]
Subject: [PATCH v3] 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 <[email protected]>
---
kernel/Kconfig.preempt | 32 +++++++++++++++++++++++---------
kernel/sched/core.c | 29 ++++++++++++++++++++++++++---
2 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
index 5876e30c5740..60f1bfc3c7b2 100644
--- a/kernel/Kconfig.preempt
+++ b/kernel/Kconfig.preempt
@@ -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
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 1bba4128a3e6..af2ca7ea7dda 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6586,12 +6586,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)
{
@@ -6664,7 +6665,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
@@ -9464,6 +9485,8 @@ void __init sched_init(void)

init_uclamp();

+ preempt_dynamic_init();
+
scheduler_running = 1;
}

--
2.25.1


2021-09-14 14:12:09

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH v3] sched: Provide Kconfig support for default dynamic preempt mode

On Tue, Sep 14, 2021 at 12:31:34PM +0200, Frederic Weisbecker wrote:
> 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 <[email protected]>

Thanks!

2021-09-16 12:00:30

by tip-bot2 for Jacob Pan

[permalink] [raw]
Subject: [tip: sched/core] sched: Provide Kconfig support for default dynamic preempt mode

The following commit has been merged into the sched/core branch of tip:

Commit-ID: 5fa8f86b5819f07ee8601244e26ffa5a622f2bf4
Gitweb: https://git.kernel.org/tip/5fa8f86b5819f07ee8601244e26ffa5a622f2bf4
Author: Frederic Weisbecker <[email protected]>
AuthorDate: Tue, 14 Sep 2021 12:31:34 +02:00
Committer: Peter Zijlstra <[email protected]>
CommitterDate: Wed, 15 Sep 2021 17:49:01 +02:00

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 <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
---
kernel/Kconfig.preempt | 32 +++++++++++++++++++++++---------
kernel/sched/core.c | 29 ++++++++++++++++++++++++++---
2 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
index bd7c414..aa9f78e 100644
--- a/kernel/Kconfig.preempt
+++ b/kernel/Kconfig.preempt
@@ -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
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 85e212d..b36b5d7 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6354,12 +6354,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)
{
@@ -6432,7 +6433,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
@@ -9236,6 +9257,8 @@ void __init sched_init(void)

init_uclamp();

+ preempt_dynamic_init();
+
scheduler_running = 1;
}

2021-09-18 02:31:37

by tip-bot2 for Jacob Pan

[permalink] [raw]
Subject: [tip: sched/core] sched: Provide Kconfig support for default dynamic preempt mode

The following commit has been merged into the sched/core branch of tip:

Commit-ID: 682dc167b47ba4dba5d129fb528762343d659f83
Gitweb: https://git.kernel.org/tip/682dc167b47ba4dba5d129fb528762343d659f83
Author: Frederic Weisbecker <[email protected]>
AuthorDate: Tue, 14 Sep 2021 12:31:34 +02:00
Committer: Peter Zijlstra <[email protected]>
CommitterDate: Fri, 17 Sep 2021 20:32:27 +02:00

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 <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
---
kernel/Kconfig.preempt | 32 +++++++++++++++++++++++---------
kernel/sched/core.c | 29 ++++++++++++++++++++++++++---
2 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
index bd7c414..aa9f78e 100644
--- a/kernel/Kconfig.preempt
+++ b/kernel/Kconfig.preempt
@@ -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
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 85e212d..b36b5d7 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6354,12 +6354,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)
{
@@ -6432,7 +6433,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
@@ -9236,6 +9257,8 @@ void __init sched_init(void)

init_uclamp();

+ preempt_dynamic_init();
+
scheduler_running = 1;
}

2021-10-05 14:15:09

by tip-bot2 for Jacob Pan

[permalink] [raw]
Subject: [tip: sched/core] sched: Provide Kconfig support for default dynamic preempt mode

The following commit has been merged into the sched/core branch of tip:

Commit-ID: c597bfddc9e9e8a63817252b67c3ca0e544ace26
Gitweb: https://git.kernel.org/tip/c597bfddc9e9e8a63817252b67c3ca0e544ace26
Author: Frederic Weisbecker <[email protected]>
AuthorDate: Tue, 14 Sep 2021 12:31:34 +02:00
Committer: Peter Zijlstra <[email protected]>
CommitterDate: Tue, 05 Oct 2021 15:51:56 +02:00

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 <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
---
kernel/Kconfig.preempt | 32 +++++++++++++++++++++++---------
kernel/sched/core.c | 29 ++++++++++++++++++++++++++---
2 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
index 5876e30..60f1bfc 100644
--- a/kernel/Kconfig.preempt
+++ b/kernel/Kconfig.preempt
@@ -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
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index a1741e0..95f4e16 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -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;
}

2021-11-10 11:49:29

by Marco Elver

[permalink] [raw]
Subject: Re: [PATCH v3] sched: Provide Kconfig support for default dynamic preempt mode

On Tue, Sep 14, 2021 at 12:31PM +0200, Frederic Weisbecker wrote:
> 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 <[email protected]>
> ---
> kernel/Kconfig.preempt | 32 +++++++++++++++++++++++---------
> kernel/sched/core.c | 29 ++++++++++++++++++++++++++---
> 2 files changed, 49 insertions(+), 12 deletions(-)
>
> diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
> index 5876e30c5740..60f1bfc3c7b2 100644
> --- a/kernel/Kconfig.preempt
> +++ b/kernel/Kconfig.preempt
> @@ -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

This change landed in mainline, and I only noticed this because I've
been staring at configs too much and the preemption of some test kernels
(syzbot) has changed.

Those are "just" test kernels for now, but I expect this to proliferate
to a significant number of other configs with automated scripts
accepting new default config values or inattentive humans.

My bet is that some major distros will accidentally configure the
defaults and instead of 'full'/'voluntary' preemption will end up with
'none' as the default.

The main problem is that PREEMPT_NONE/PREEMPT_VOLUNATRY/PREEMPT are no
longer user-settable and are only selectable by other config options.
Because the *_BEHAVIOUR configs are new, the default will be
PREEMPT_NONE_BEHAVIOUR.

For example, an old 5.15 config has:

$ grep PREEMPT .config
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
CONFIG_HAVE_PREEMPT_DYNAMIC=y
# CONFIG_PREEMPTIRQ_DELAY_TEST is not set

A new 5.16 config with this patch, after migrating the old config:

$ yes '' | make oldconfig
$ grep PREEMPT .config
CONFIG_PREEMPT_NONE_BEHAVIOUR=y
# CONFIG_PREEMPT_VOLUNTARY_BEHAVIOUR is not set
# CONFIG_PREEMPT_BEHAVIOUR is not set
CONFIG_PREEMPT=y
CONFIG_PREEMPT_COUNT=y
CONFIG_PREEMPTION=y
CONFIG_PREEMPT_DYNAMIC=y
CONFIG_PREEMPT_RCU=y
CONFIG_HAVE_PREEMPT_DYNAMIC=y
CONFIG_DEBUG_PREEMPT=y
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_PREEMPTIRQ_DELAY_TEST is not set

Is there some way to avoid introducing *_BEHAVIOUR and keep the old
user-settable config options?

That would make the transition more seamless and avoid this predictable
issue when 5.16 is released.

Thanks,
-- Marco

2021-11-10 12:22:54

by Valentin Schneider

[permalink] [raw]
Subject: Re: [PATCH v3] sched: Provide Kconfig support for default dynamic preempt mode

On 10/11/21 12:41, Marco Elver wrote:
> Is there some way to avoid introducing *_BEHAVIOUR and keep the old
> user-settable config options?
>
> That would make the transition more seamless and avoid this predictable
> issue when 5.16 is released.
>

We're looking at it, but Kconfig be hard :-)

http://lore.kernel.org/r/[email protected]
http://lore.kernel.org/r/[email protected]

> Thanks,
> -- Marco