[tip: sched/core] sched: dynamic: Make PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY

tip-bot2 for Mark Rutland posted 1 patch 3 weeks, 3 days ago
kernel/Kconfig.preempt |  1 +-
kernel/sched/core.c    | 63 +----------------------------------------
2 files changed, 4 insertions(+), 60 deletions(-)
[tip: sched/core] sched: dynamic: Make PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY
Posted by tip-bot2 for Mark Rutland 3 weeks, 3 days ago
The following commit has been merged into the sched/core branch of tip:

Commit-ID:     d3d16750693b540299cd105968174556012aba09
Gitweb:        https://git.kernel.org/tip/d3d16750693b540299cd105968174556012aba09
Author:        Mark Rutland <mark.rutland@arm.com>
AuthorDate:    Mon, 03 Aug 2026 20:17:26 +01:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 02 Sep 2026 09:37:22 +02:00

sched: dynamic: Make PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY

On architectures which select ARCH_HAS_PREEMPT_LAZY, it has not been
possible to select the NONE and VOLUNTARY preemption models since
commit:

  7dadeaa6e851 ("sched: Further restrict the preemption modes")

... which was merged in v7.0.

All architectures which currently support PREEMPT_DYNAMIC select
ARCH_HAS_PREEMPT_LAZY:

  [mark@lakrids:~/src/linux]% git describe HEAD
  v7.2-rc1-1-g871a4586ea2e1
  [mark@lakrids:~/src/linux]% git grep 'select HAVE_PREEMPT_DYNAMIC_' -- arch
  arch/arm64/Kconfig:     select HAVE_PREEMPT_DYNAMIC_KEY
  arch/loongarch/Kconfig: select HAVE_PREEMPT_DYNAMIC_KEY
  arch/powerpc/Kconfig:   select HAVE_PREEMPT_DYNAMIC_KEY
  arch/riscv/Kconfig:     select HAVE_PREEMPT_DYNAMIC_KEY
  arch/s390/Kconfig:      select HAVE_PREEMPT_DYNAMIC_KEY
  arch/x86/Kconfig:       select HAVE_PREEMPT_DYNAMIC_CALL
  [mark@lakrids:~/src/linux]% git grep 'select ARCH_HAS_PREEMPT_LAZY' -- arch
  arch/arm64/Kconfig:     select ARCH_HAS_PREEMPT_LAZY
  arch/loongarch/Kconfig: select ARCH_HAS_PREEMPT_LAZY
  arch/powerpc/Kconfig:   select ARCH_HAS_PREEMPT_LAZY
  arch/riscv/Kconfig:     select ARCH_HAS_PREEMPT_LAZY
  arch/s390/Kconfig:      select ARCH_HAS_PREEMPT_LAZY
  arch/x86/Kconfig:       select ARCH_HAS_PREEMPT_LAZY

... and hence in practice PREEMPT_DYNAMIC no longer supports the NONE or
VOLUNTARY preemption models.

Make this official: have PREEMPT_DYNAMIC depend on
ARCH_HAS_PREEMPT_LAZY, and remove the trivially unreachable code.
Further simplifications will be made in subsequent patches.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Reviewed-by: Jinjie Ruan <ruanjinjie@huawei.com>
Tested-by: Mete Durlu <meted@linux.ibm.com>
Tested-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Tested-by: Jinjie Ruan <ruanjinjie@huawei.com>
Link: https://patch.msgid.link/20260803191731.3244294-2-mark.rutland@arm.com
---
 kernel/Kconfig.preempt |  1 +-
 kernel/sched/core.c    | 63 +----------------------------------------
 2 files changed, 4 insertions(+), 60 deletions(-)

diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
index f294dad..68f3218 100644
--- a/kernel/Kconfig.preempt
+++ b/kernel/Kconfig.preempt
@@ -133,6 +133,7 @@ config PREEMPTION
 config PREEMPT_DYNAMIC
 	bool "Preemption behaviour defined on boot"
 	depends on HAVE_PREEMPT_DYNAMIC
+	depends on ARCH_HAS_PREEMPT_LAZY
 	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 9841043..84e7685 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7931,20 +7931,10 @@ EXPORT_SYMBOL(__cond_resched_rwlock_write);
  *
  *
  * NONE:
- *   cond_resched               <- __cond_resched
- *   might_resched              <- RET0
- *   preempt_schedule           <- NOP
- *   preempt_schedule_notrace   <- NOP
- *   irqentry_exit_cond_resched <- NOP
- *   dynamic_preempt_lazy       <- false
+ *   (unselectable)
  *
  * VOLUNTARY:
- *   cond_resched               <- __cond_resched
- *   might_resched              <- __cond_resched
- *   preempt_schedule           <- NOP
- *   preempt_schedule_notrace   <- NOP
- *   irqentry_exit_cond_resched <- NOP
- *   dynamic_preempt_lazy       <- false
+ *   (unselectable)
  *
  * FULL:
  *   cond_resched               <- RET0
@@ -7975,21 +7965,11 @@ int preempt_dynamic_mode = preempt_dynamic_undefined;
 
 int sched_dynamic_mode(const char *str)
 {
-# if !(defined(CONFIG_PREEMPT_RT) || defined(CONFIG_ARCH_HAS_PREEMPT_LAZY))
-	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;
 
-# ifdef CONFIG_ARCH_HAS_PREEMPT_LAZY
 	if (!strcmp(str, "lazy"))
 		return preempt_dynamic_lazy;
-# endif
 
 	return -EINVAL;
 }
@@ -8011,40 +7991,7 @@ static DEFINE_MUTEX(sched_dynamic_mutex);
 
 static void __sched_dynamic_update(int mode)
 {
-	/*
-	 * Avoid {NONE,VOLUNTARY} -> FULL transitions from ever ending up in
-	 * the ZERO state, which is invalid.
-	 */
-	preempt_dynamic_enable(cond_resched);
-	preempt_dynamic_enable(might_resched);
-	preempt_dynamic_enable(preempt_schedule);
-	preempt_dynamic_enable(preempt_schedule_notrace);
-	preempt_dynamic_enable(irqentry_exit_cond_resched);
-	preempt_dynamic_key_disable(preempt_lazy);
-
 	switch (mode) {
-	case preempt_dynamic_none:
-		preempt_dynamic_enable(cond_resched);
-		preempt_dynamic_disable(might_resched);
-		preempt_dynamic_disable(preempt_schedule);
-		preempt_dynamic_disable(preempt_schedule_notrace);
-		preempt_dynamic_disable(irqentry_exit_cond_resched);
-		preempt_dynamic_key_disable(preempt_lazy);
-		if (mode != preempt_dynamic_mode)
-			pr_info("Dynamic Preempt: none\n");
-		break;
-
-	case preempt_dynamic_voluntary:
-		preempt_dynamic_enable(cond_resched);
-		preempt_dynamic_enable(might_resched);
-		preempt_dynamic_disable(preempt_schedule);
-		preempt_dynamic_disable(preempt_schedule_notrace);
-		preempt_dynamic_disable(irqentry_exit_cond_resched);
-		preempt_dynamic_key_disable(preempt_lazy);
-		if (mode != preempt_dynamic_mode)
-			pr_info("Dynamic Preempt: voluntary\n");
-		break;
-
 	case preempt_dynamic_full:
 		preempt_dynamic_disable(cond_resched);
 		preempt_dynamic_disable(might_resched);
@@ -8094,11 +8041,7 @@ __setup("preempt=", setup_preempt_mode);
 static void __init preempt_dynamic_init(void)
 {
 	if (preempt_dynamic_mode == preempt_dynamic_undefined) {
-		if (IS_ENABLED(CONFIG_PREEMPT_NONE)) {
-			sched_dynamic_update(preempt_dynamic_none);
-		} else if (IS_ENABLED(CONFIG_PREEMPT_VOLUNTARY)) {
-			sched_dynamic_update(preempt_dynamic_voluntary);
-		} else if (IS_ENABLED(CONFIG_PREEMPT_LAZY)) {
+		if (IS_ENABLED(CONFIG_PREEMPT_LAZY)) {
 			sched_dynamic_update(preempt_dynamic_lazy);
 		} else {
 			/* Default static call setting, nothing to do */