[PATCH 3/5] sched: Enable PREEMPT_DYNAMIC for PREEMPT_RT

Peter Zijlstra posted 5 patches 1 month, 3 weeks ago
[PATCH 3/5] sched: Enable PREEMPT_DYNAMIC for PREEMPT_RT
Posted by Peter Zijlstra 1 month, 3 weeks ago
In order to enable PREEMPT_DYNAMIC for PREEMPT_RT, remove PREEMPT_RT
from the 'Preemption Model' choice. Strictly speaking PREEMPT_RT is
not a change in how preemption works, but rather it makes a ton more
code preemptible.

Notably, take away NONE and VOLATILE options for PREEMPT_RT, they make
no sense (but are techincally possible).

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 kernel/Kconfig.preempt |   12 +++++++-----
 kernel/sched/core.c    |    2 ++
 kernel/sched/debug.c   |    4 ++--
 3 files changed, 11 insertions(+), 7 deletions(-)

--- a/kernel/Kconfig.preempt
+++ b/kernel/Kconfig.preempt
@@ -20,6 +20,7 @@ choice
 
 config PREEMPT_NONE
 	bool "No Forced Preemption (Server)"
+	depends on !PREEMPT_RT
 	select PREEMPT_NONE_BUILD if !PREEMPT_DYNAMIC
 	help
 	  This is the traditional Linux preemption model, geared towards
@@ -35,6 +36,7 @@ config PREEMPT_NONE
 config PREEMPT_VOLUNTARY
 	bool "Voluntary Kernel Preemption (Desktop)"
 	depends on !ARCH_NO_PREEMPT
+	depends on !PREEMPT_RT
 	select PREEMPT_VOLUNTARY_BUILD if !PREEMPT_DYNAMIC
 	help
 	  This option reduces the latency of the kernel by adding more
@@ -54,7 +56,7 @@ config PREEMPT_VOLUNTARY
 config PREEMPT
 	bool "Preemptible Kernel (Low-Latency Desktop)"
 	depends on !ARCH_NO_PREEMPT
-	select PREEMPT_BUILD
+	select PREEMPT_BUILD if !PREEMPT_DYNAMIC
 	help
 	  This option reduces the latency of the kernel by making
 	  all kernel code (that is not executing in a critical section)
@@ -74,7 +76,7 @@ config PREEMPT_LAZY
 	bool "Scheduler controlled preemption model"
 	depends on !ARCH_NO_PREEMPT
 	depends on ARCH_HAS_PREEMPT_LAZY
-	select PREEMPT_BUILD
+	select PREEMPT_BUILD if !PREEMPT_DYNAMIC
 	help
 	  This option provides a scheduler driven preemption model that
 	  is fundamentally similar to full preemption, but is less
@@ -82,6 +84,8 @@ config PREEMPT_LAZY
 	  reduce lock holder preemption and recover some of the performance
 	  gains seen from using Voluntary preemption.
 
+endchoice
+
 config PREEMPT_RT
 	bool "Fully Preemptible Kernel (Real-Time)"
 	depends on EXPERT && ARCH_SUPPORTS_RT
@@ -99,8 +103,6 @@ config PREEMPT_RT
 	  Select this if you are building a kernel for systems which
 	  require real-time guarantees.
 
-endchoice
-
 config PREEMPT_COUNT
        bool
 
@@ -110,7 +112,7 @@ config PREEMPTION
 
 config PREEMPT_DYNAMIC
 	bool "Preemption behaviour defined on boot"
-	depends on HAVE_PREEMPT_DYNAMIC && !PREEMPT_RT
+	depends on HAVE_PREEMPT_DYNAMIC
 	select JUMP_LABEL if HAVE_PREEMPT_DYNAMIC_KEY
 	select PREEMPT_BUILD
 	default y if HAVE_PREEMPT_DYNAMIC_CALL
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7406,11 +7406,13 @@ int preempt_dynamic_mode = preempt_dynam
 
 int sched_dynamic_mode(const char *str)
 {
+#ifndef CONFIG_PREEMPT_RT
 	if (!strcmp(str, "none"))
 		return preempt_dynamic_none;
 
 	if (!strcmp(str, "voluntary"))
 		return preempt_dynamic_voluntary;
+#endif
 
 	if (!strcmp(str, "full"))
 		return preempt_dynamic_full;
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -248,9 +248,9 @@ static int sched_dynamic_show(struct seq
 		"none", "voluntary", "full", "lazy",
 	};
 	int j = ARRAY_SIZE(preempt_modes) - !IS_ENABLED(CONFIG_ARCH_HAS_PREEMPT_LAZY);
-	int i;
+	int i = IS_ENABLED(CONFIG_PREEMPT_RT) * 2;
 
-	for (i = 0; i < j; i++) {
+	for (; i < j; i++) {
 		if (preempt_dynamic_mode == i)
 			seq_puts(m, "(");
 		seq_puts(m, preempt_modes[i]);
Re: [PATCH 3/5] sched: Enable PREEMPT_DYNAMIC for PREEMPT_RT
Posted by Christoph Hellwig 1 month, 2 weeks ago
On Mon, Oct 07, 2024 at 09:46:12AM +0200, Peter Zijlstra wrote:
> In order to enable PREEMPT_DYNAMIC for PREEMPT_RT, remove PREEMPT_RT
> from the 'Preemption Model' choice. Strictly speaking PREEMPT_RT is
> not a change in how preemption works, but rather it makes a ton more
> code preemptible.
> 
> Notably, take away NONE and VOLATILE options for PREEMPT_RT, they make
> no sense (but are techincally possible).

Should we take away NONE entirely because it is kinda silly?

Just a bystander here, but the explosion of different preemption models
is a bit silly and not really helpful to users.
Re: [PATCH 3/5] sched: Enable PREEMPT_DYNAMIC for PREEMPT_RT
Posted by Peter Zijlstra 1 month, 2 weeks ago
On Wed, Oct 09, 2024 at 11:52:36PM -0700, Christoph Hellwig wrote:
> On Mon, Oct 07, 2024 at 09:46:12AM +0200, Peter Zijlstra wrote:
> > In order to enable PREEMPT_DYNAMIC for PREEMPT_RT, remove PREEMPT_RT
> > from the 'Preemption Model' choice. Strictly speaking PREEMPT_RT is
> > not a change in how preemption works, but rather it makes a ton more
> > code preemptible.
> > 
> > Notably, take away NONE and VOLATILE options for PREEMPT_RT, they make
> > no sense (but are techincally possible).
> 
> Should we take away NONE entirely because it is kinda silly?
> 
> Just a bystander here, but the explosion of different preemption models
> is a bit silly and not really helpful to users.

The end goal is to get rid of Voluntary and None, but getting there will
require more work. A lot of careful work to be sure. In the end we
should be rid of those two preemption models and the cond_resched() and
much of the random need_resched() hackery they brought.

But we can't do it all at once, so yeah, we need to grow extra crap
before we can take out the old stuff. Nothing new there, but I get your
frustration.
Re: [PATCH 3/5] sched: Enable PREEMPT_DYNAMIC for PREEMPT_RT
Posted by Sebastian Andrzej Siewior 1 month, 2 weeks ago
On 2024-10-07 09:46:12 [+0200], Peter Zijlstra wrote:
> In order to enable PREEMPT_DYNAMIC for PREEMPT_RT, remove PREEMPT_RT
> from the 'Preemption Model' choice. Strictly speaking PREEMPT_RT is
> not a change in how preemption works, but rather it makes a ton more
> code preemptible.
> 
> Notably, take away NONE and VOLATILE options for PREEMPT_RT, they make
> no sense (but are techincally possible).

So this is what we do. Okay. This means we can enable the DYNAMIC mode
on PREEMPT_RT enabled kernels and switch between "full" and the "lazy"
mode(s).
On PREEMPT_RT enabled kernels with PREEMPT_DYNAMIC the UTS_VERSION
string is set to PREEMPT_RT and PREEMPT_DYNAMIC is not exposed. Is this
on purpose or just happened?

Clark was asking for a file to expose whether or not PREEMPT_RT is
enabled and I was pointing him to UTS_VERSION but then suggested that it
might be possible if we expose the current setting of the preemption
model and use this. 
But with this it won't work.
I am not sure if PREEMPT_DYNAMIC is needed to be exposed and if
everybody is happy parsing UTS_VERSION (we used to have a
/sys/kernel/realtime file in the RT queue).

> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Sebastian
Re: [PATCH 3/5] sched: Enable PREEMPT_DYNAMIC for PREEMPT_RT
Posted by Peter Zijlstra 1 month, 2 weeks ago
On Tue, Oct 08, 2024 at 03:24:16PM +0200, Sebastian Andrzej Siewior wrote:
> On 2024-10-07 09:46:12 [+0200], Peter Zijlstra wrote:
> > In order to enable PREEMPT_DYNAMIC for PREEMPT_RT, remove PREEMPT_RT
> > from the 'Preemption Model' choice. Strictly speaking PREEMPT_RT is
> > not a change in how preemption works, but rather it makes a ton more
> > code preemptible.
> > 
> > Notably, take away NONE and VOLATILE options for PREEMPT_RT, they make

As I think Mike already noted, typing is hard and this should of course
have been Voluntary :-)

> > no sense (but are techincally possible).
> 
> So this is what we do. Okay. This means we can enable the DYNAMIC mode
> on PREEMPT_RT enabled kernels and switch between "full" and the "lazy"
> mode(s).

Right.

> On PREEMPT_RT enabled kernels with PREEMPT_DYNAMIC the UTS_VERSION
> string is set to PREEMPT_RT and PREEMPT_DYNAMIC is not exposed. Is this
> on purpose or just happened?

I noticed it, didn't care and promptly forgot about it again :-)

> Clark was asking for a file to expose whether or not PREEMPT_RT is
> enabled and I was pointing him to UTS_VERSION but then suggested that it
> might be possible if we expose the current setting of the preemption
> model and use this. 
> But with this it won't work.
> I am not sure if PREEMPT_DYNAMIC is needed to be exposed and if
> everybody is happy parsing UTS_VERSION (we used to have a
> /sys/kernel/realtime file in the RT queue).

Yeah, IDK. This is all just pick a colour :-)
[tip: sched/core] sched: Enable PREEMPT_DYNAMIC for PREEMPT_RT
Posted by tip-bot2 for Peter Zijlstra 3 weeks ago
The following commit has been merged into the sched/core branch of tip:

Commit-ID:     35772d627b55cc7fb4f33bae57c564a25b3121a9
Gitweb:        https://git.kernel.org/tip/35772d627b55cc7fb4f33bae57c564a25b3121a9
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Fri, 04 Oct 2024 14:46:56 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 05 Nov 2024 12:55:38 +01:00

sched: Enable PREEMPT_DYNAMIC for PREEMPT_RT

In order to enable PREEMPT_DYNAMIC for PREEMPT_RT, remove PREEMPT_RT
from the 'Preemption Model' choice. Strictly speaking PREEMPT_RT is
not a change in how preemption works, but rather it makes a ton more
code preemptible.

Notably, take away NONE and VOLUNTARY options for PREEMPT_RT, they make
no sense (but are techincally possible).

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://lkml.kernel.org/r/20241007075055.441622332@infradead.org
---
 kernel/Kconfig.preempt | 12 +++++++-----
 kernel/sched/core.c    |  2 ++
 kernel/sched/debug.c   |  4 ++--
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
index 09f06d8..7c1b29a 100644
--- a/kernel/Kconfig.preempt
+++ b/kernel/Kconfig.preempt
@@ -20,6 +20,7 @@ choice
 
 config PREEMPT_NONE
 	bool "No Forced Preemption (Server)"
+	depends on !PREEMPT_RT
 	select PREEMPT_NONE_BUILD if !PREEMPT_DYNAMIC
 	help
 	  This is the traditional Linux preemption model, geared towards
@@ -35,6 +36,7 @@ config PREEMPT_NONE
 config PREEMPT_VOLUNTARY
 	bool "Voluntary Kernel Preemption (Desktop)"
 	depends on !ARCH_NO_PREEMPT
+	depends on !PREEMPT_RT
 	select PREEMPT_VOLUNTARY_BUILD if !PREEMPT_DYNAMIC
 	help
 	  This option reduces the latency of the kernel by adding more
@@ -54,7 +56,7 @@ config PREEMPT_VOLUNTARY
 config PREEMPT
 	bool "Preemptible Kernel (Low-Latency Desktop)"
 	depends on !ARCH_NO_PREEMPT
-	select PREEMPT_BUILD
+	select PREEMPT_BUILD if !PREEMPT_DYNAMIC
 	help
 	  This option reduces the latency of the kernel by making
 	  all kernel code (that is not executing in a critical section)
@@ -74,7 +76,7 @@ config PREEMPT_LAZY
 	bool "Scheduler controlled preemption model"
 	depends on !ARCH_NO_PREEMPT
 	depends on ARCH_HAS_PREEMPT_LAZY
-	select PREEMPT_BUILD
+	select PREEMPT_BUILD if !PREEMPT_DYNAMIC
 	help
 	  This option provides a scheduler driven preemption model that
 	  is fundamentally similar to full preemption, but is less
@@ -82,6 +84,8 @@ config PREEMPT_LAZY
 	  reduce lock holder preemption and recover some of the performance
 	  gains seen from using Voluntary preemption.
 
+endchoice
+
 config PREEMPT_RT
 	bool "Fully Preemptible Kernel (Real-Time)"
 	depends on EXPERT && ARCH_SUPPORTS_RT
@@ -99,8 +103,6 @@ config PREEMPT_RT
 	  Select this if you are building a kernel for systems which
 	  require real-time guarantees.
 
-endchoice
-
 config PREEMPT_COUNT
        bool
 
@@ -110,7 +112,7 @@ config PREEMPTION
 
 config PREEMPT_DYNAMIC
 	bool "Preemption behaviour defined on boot"
-	depends on HAVE_PREEMPT_DYNAMIC && !PREEMPT_RT
+	depends on HAVE_PREEMPT_DYNAMIC
 	select JUMP_LABEL if HAVE_PREEMPT_DYNAMIC_KEY
 	select PREEMPT_BUILD
 	default y if HAVE_PREEMPT_DYNAMIC_CALL
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index df6a34d..5c47d70 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7450,11 +7450,13 @@ int preempt_dynamic_mode = preempt_dynamic_undefined;
 
 int sched_dynamic_mode(const char *str)
 {
+#ifndef CONFIG_PREEMPT_RT
 	if (!strcmp(str, "none"))
 		return preempt_dynamic_none;
 
 	if (!strcmp(str, "voluntary"))
 		return preempt_dynamic_voluntary;
+#endif
 
 	if (!strcmp(str, "full"))
 		return preempt_dynamic_full;
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 44a49f9..a48b2a7 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -248,9 +248,9 @@ static int sched_dynamic_show(struct seq_file *m, void *v)
 		"none", "voluntary", "full", "lazy",
 	};
 	int j = ARRAY_SIZE(preempt_modes) - !IS_ENABLED(CONFIG_ARCH_HAS_PREEMPT_LAZY);
-	int i;
+	int i = IS_ENABLED(CONFIG_PREEMPT_RT) * 2;
 
-	for (i = 0; i < j; i++) {
+	for (; i < j; i++) {
 		if (preempt_dynamic_mode == i)
 			seq_puts(m, "(");
 		seq_puts(m, preempt_modes[i]);