The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH 0/5] sched: dynamic: Simplify PREEMPT_DYNAMIC
@ 2026-07-03 13:33 Mark Rutland
  2026-07-03 13:33 ` [PATCH 1/5] sched: dynamic: Make PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY Mark Rutland
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Mark Rutland @ 2026-07-03 13:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: frederic, jstultz, juri.lelli, mark.rutland, mingo, peterz, tglx,
	vincent.guittot, vschneid

All architectures which currently suppoort PREEMPT_DYNAMIC select
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 v7.0 due to commit:

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

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

This series makes the de-facto situation official by making
PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY, and removing all the
redundant code.

For x86_64 v7.2-rc1 defconfig built with GCC 10.2.1, this makes the
bzImage 28K smaller, mostly due to removing NOPs that will never be
patched to {cond,might}_resched() at runtime:

  [mark@lakrids:~/src/linux]% ls -al vmlinux-*
  -rwxr-xr-x 1 mark mark 53844952 Jul  3 14:09 vmlinux-after
  -rwxr-xr-x 1 mark mark 53842856 Jul  3 14:09 vmlinux-before
  [mark@lakrids:~/src/linux]% ls -al bzImage-*
  -rw-r--r-- 1 mark mark 14771200 Jul  3 14:09 bzImage-after
  -rw-r--r-- 1 mark mark 14799872 Jul  3 14:08 bzImage-before

Mark.

Mark Rutland (5):
  sched: dynamic: Make PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY
  sched: dynamic: Simplify {cond,might}_resched()
  sched: dynamic: Simplify preempt_schedule{,_notrace}()
  sched: dynamic: Simplify irqentry_exit_cond_resched()
  sched: dynamic: Remove HAVE_PREEMPT_DYNAMIC_{CALL,KEY}

 arch/Kconfig                       |  38 -------
 arch/arm64/Kconfig                 |   1 -
 arch/arm64/include/asm/preempt.h   |  10 --
 arch/loongarch/Kconfig             |   1 -
 arch/powerpc/Kconfig               |   1 -
 arch/powerpc/include/asm/preempt.h |   7 --
 arch/riscv/Kconfig                 |   1 -
 arch/s390/Kconfig                  |   1 -
 arch/s390/include/asm/preempt.h    |  11 --
 arch/x86/Kconfig                   |   1 -
 arch/x86/include/asm/preempt.h     |  28 -----
 include/asm-generic/preempt.h      |  10 --
 include/linux/irq-entry-common.h   |  17 +--
 include/linux/kernel.h             |  20 ----
 include/linux/sched.h              |  31 +----
 kernel/Kconfig.preempt             |   9 +-
 kernel/entry/common.c              |  17 +--
 kernel/sched/core.c                | 176 +----------------------------
 18 files changed, 13 insertions(+), 367 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/5] sched: dynamic: Make PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY
  2026-07-03 13:33 [PATCH 0/5] sched: dynamic: Simplify PREEMPT_DYNAMIC Mark Rutland
@ 2026-07-03 13:33 ` Mark Rutland
  2026-07-06  4:36   ` Shrikanth Hegde
  2026-07-03 13:33 ` [PATCH 2/5] sched: dynamic: Simplify {cond,might}_resched() Mark Rutland
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Mark Rutland @ 2026-07-03 13:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: frederic, jstultz, juri.lelli, mark.rutland, mingo, peterz, tglx,
	vincent.guittot, vschneid

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 suppoort 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>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: John Stultz <jstultz@google.com>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
---
 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 88c594c6d7fcd..fb49424003b2b 100644
--- a/kernel/Kconfig.preempt
+++ b/kernel/Kconfig.preempt
@@ -129,6 +129,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 96226707c2f61..2db78826a484b 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7870,20 +7870,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
@@ -7914,21 +7904,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;
 }
@@ -7950,40 +7930,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);
@@ -8033,11 +7980,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 */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/5] sched: dynamic: Simplify {cond,might}_resched()
  2026-07-03 13:33 [PATCH 0/5] sched: dynamic: Simplify PREEMPT_DYNAMIC Mark Rutland
  2026-07-03 13:33 ` [PATCH 1/5] sched: dynamic: Make PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY Mark Rutland
@ 2026-07-03 13:33 ` Mark Rutland
  2026-07-06  4:59   ` Shrikanth Hegde
  2026-07-03 13:33 ` [PATCH 3/5] sched: dynamic: Simplify preempt_schedule{,_notrace}() Mark Rutland
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Mark Rutland @ 2026-07-03 13:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: frederic, jstultz, juri.lelli, mark.rutland, mingo, peterz, tglx,
	vincent.guittot, vschneid

PREEMPT_DYNAMIC is now limited to the FULL and LAZY preemption models.
In either model, both cond_resched() and might_resched() are always
disabled and do nothing.

Remove the unnecessary code for these when PREEMPT_DYNAMIC is selected.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: John Stultz <jstultz@google.com>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
---
 include/linux/kernel.h | 20 -------------------
 include/linux/sched.h  | 31 +++--------------------------
 kernel/sched/core.c    | 44 +-----------------------------------------
 3 files changed, 4 insertions(+), 91 deletions(-)

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index e5570a16cbb1a..533ee1e6e1cb7 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -43,30 +43,10 @@ struct completion;
 struct user;
 
 #ifdef CONFIG_PREEMPT_VOLUNTARY_BUILD
-
 extern int __cond_resched(void);
 # define might_resched() __cond_resched()
-
-#elif defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
-
-extern int __cond_resched(void);
-
-DECLARE_STATIC_CALL(might_resched, __cond_resched);
-
-static __always_inline void might_resched(void)
-{
-	static_call_mod(might_resched)();
-}
-
-#elif defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
-
-extern int dynamic_might_resched(void);
-# define might_resched() dynamic_might_resched()
-
 #else
-
 # define might_resched() do { } while (0)
-
 #endif /* CONFIG_PREEMPT_* */
 
 #ifdef CONFIG_DEBUG_ATOMIC_SLEEP
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 373bcc0598d10..1a44c5261c2dd 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2119,44 +2119,19 @@ static inline void set_need_resched_current(void)
  * value indicates whether a reschedule was done in fact.
  * cond_resched_lock() will drop the spinlock before scheduling,
  */
-#if !defined(CONFIG_PREEMPTION) || defined(CONFIG_PREEMPT_DYNAMIC)
+#if !defined(CONFIG_PREEMPTION)
 extern int __cond_resched(void);
 
-#if defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
-
-DECLARE_STATIC_CALL(cond_resched, __cond_resched);
-
-static __always_inline int _cond_resched(void)
-{
-	return static_call_mod(cond_resched)();
-}
-
-#elif defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
-
-extern int dynamic_cond_resched(void);
-
-static __always_inline int _cond_resched(void)
-{
-	return dynamic_cond_resched();
-}
-
-#else /* !CONFIG_PREEMPTION */
-
 static inline int _cond_resched(void)
 {
 	return __cond_resched();
 }
-
-#endif /* PREEMPT_DYNAMIC && CONFIG_HAVE_PREEMPT_DYNAMIC_CALL */
-
-#else /* CONFIG_PREEMPTION && !CONFIG_PREEMPT_DYNAMIC */
-
+#else
 static inline int _cond_resched(void)
 {
 	return 0;
 }
-
-#endif /* !CONFIG_PREEMPTION || CONFIG_PREEMPT_DYNAMIC */
+#endif
 
 #define cond_resched() ({			\
 	__might_resched(__FILE__, __LINE__, 0);	\
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 2db78826a484b..84ec93694d718 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7733,7 +7733,7 @@ void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task)
 }
 #endif /* CONFIG_RT_MUTEXES */
 
-#if !defined(CONFIG_PREEMPTION) || defined(CONFIG_PREEMPT_DYNAMIC)
+#if !defined(CONFIG_PREEMPTION)
 int __sched __cond_resched(void)
 {
 	if (should_resched(0) && !irqs_disabled()) {
@@ -7761,38 +7761,6 @@ int __sched __cond_resched(void)
 EXPORT_SYMBOL(__cond_resched);
 #endif
 
-#ifdef CONFIG_PREEMPT_DYNAMIC
-# ifdef CONFIG_HAVE_PREEMPT_DYNAMIC_CALL
-#  define cond_resched_dynamic_enabled	__cond_resched
-#  define cond_resched_dynamic_disabled	((void *)&__static_call_return0)
-DEFINE_STATIC_CALL_RET0(cond_resched, __cond_resched);
-EXPORT_STATIC_CALL_TRAMP(cond_resched);
-
-#  define might_resched_dynamic_enabled	__cond_resched
-#  define might_resched_dynamic_disabled ((void *)&__static_call_return0)
-DEFINE_STATIC_CALL_RET0(might_resched, __cond_resched);
-EXPORT_STATIC_CALL_TRAMP(might_resched);
-# elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
-static DEFINE_STATIC_KEY_FALSE(sk_dynamic_cond_resched);
-int __sched dynamic_cond_resched(void)
-{
-	if (!static_branch_unlikely(&sk_dynamic_cond_resched))
-		return 0;
-	return __cond_resched();
-}
-EXPORT_SYMBOL(dynamic_cond_resched);
-
-static DEFINE_STATIC_KEY_FALSE(sk_dynamic_might_resched);
-int __sched dynamic_might_resched(void)
-{
-	if (!static_branch_unlikely(&sk_dynamic_might_resched))
-		return 0;
-	return __cond_resched();
-}
-EXPORT_SYMBOL(dynamic_might_resched);
-# endif
-#endif /* CONFIG_PREEMPT_DYNAMIC */
-
 /*
  * __cond_resched_lock() - if a reschedule is pending, drop the given lock,
  * call schedule, and on return reacquire the lock.
@@ -7862,8 +7830,6 @@ EXPORT_SYMBOL(__cond_resched_rwlock_write);
 # endif
 
 /*
- * SC:cond_resched
- * SC:might_resched
  * SC:preempt_schedule
  * SC:preempt_schedule_notrace
  * SC:irqentry_exit_cond_resched
@@ -7876,16 +7842,12 @@ EXPORT_SYMBOL(__cond_resched_rwlock_write);
  *   (unselectable)
  *
  * FULL:
- *   cond_resched               <- RET0
- *   might_resched              <- RET0
  *   preempt_schedule           <- preempt_schedule
  *   preempt_schedule_notrace   <- preempt_schedule_notrace
  *   irqentry_exit_cond_resched <- irqentry_exit_cond_resched
  *   dynamic_preempt_lazy       <- false
  *
  * LAZY:
- *   cond_resched               <- RET0
- *   might_resched              <- RET0
  *   preempt_schedule           <- preempt_schedule
  *   preempt_schedule_notrace   <- preempt_schedule_notrace
  *   irqentry_exit_cond_resched <- irqentry_exit_cond_resched
@@ -7932,8 +7894,6 @@ static void __sched_dynamic_update(int mode)
 {
 	switch (mode) {
 	case preempt_dynamic_full:
-		preempt_dynamic_disable(cond_resched);
-		preempt_dynamic_disable(might_resched);
 		preempt_dynamic_enable(preempt_schedule);
 		preempt_dynamic_enable(preempt_schedule_notrace);
 		preempt_dynamic_enable(irqentry_exit_cond_resched);
@@ -7943,8 +7903,6 @@ static void __sched_dynamic_update(int mode)
 		break;
 
 	case preempt_dynamic_lazy:
-		preempt_dynamic_disable(cond_resched);
-		preempt_dynamic_disable(might_resched);
 		preempt_dynamic_enable(preempt_schedule);
 		preempt_dynamic_enable(preempt_schedule_notrace);
 		preempt_dynamic_enable(irqentry_exit_cond_resched);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/5] sched: dynamic: Simplify preempt_schedule{,_notrace}()
  2026-07-03 13:33 [PATCH 0/5] sched: dynamic: Simplify PREEMPT_DYNAMIC Mark Rutland
  2026-07-03 13:33 ` [PATCH 1/5] sched: dynamic: Make PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY Mark Rutland
  2026-07-03 13:33 ` [PATCH 2/5] sched: dynamic: Simplify {cond,might}_resched() Mark Rutland
@ 2026-07-03 13:33 ` Mark Rutland
  2026-07-06  5:19   ` Shrikanth Hegde
  2026-07-03 13:33 ` [PATCH 4/5] sched: dynamic: Simplify irqentry_exit_cond_resched() Mark Rutland
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Mark Rutland @ 2026-07-03 13:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: frederic, jstultz, juri.lelli, mark.rutland, mingo, peterz, tglx,
	vincent.guittot, vschneid

PREEMPT_DYNAMIC is now limited to the FULL and LAZY preemption models.
In either model, both preempt_schedule() and preempt_schedule_notrace()
are always called and never disabled.

Remove the unnecessary code for these when PREEMPT_DYNAMIC is selected.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: John Stultz <jstultz@google.com>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
---
 arch/arm64/include/asm/preempt.h | 10 ------
 arch/s390/include/asm/preempt.h  | 11 -------
 arch/x86/include/asm/preempt.h   | 28 -----------------
 include/asm-generic/preempt.h    | 10 ------
 kernel/sched/core.c              | 52 --------------------------------
 5 files changed, 111 deletions(-)

diff --git a/arch/arm64/include/asm/preempt.h b/arch/arm64/include/asm/preempt.h
index 932ea4b620428..506dab34dddb2 100644
--- a/arch/arm64/include/asm/preempt.h
+++ b/arch/arm64/include/asm/preempt.h
@@ -84,19 +84,9 @@ static inline bool should_resched(int preempt_offset)
 void preempt_schedule(void);
 void preempt_schedule_notrace(void);
 
-#ifdef CONFIG_PREEMPT_DYNAMIC
-
-void dynamic_preempt_schedule(void);
-#define __preempt_schedule()		dynamic_preempt_schedule()
-void dynamic_preempt_schedule_notrace(void);
-#define __preempt_schedule_notrace()	dynamic_preempt_schedule_notrace()
-
-#else /* CONFIG_PREEMPT_DYNAMIC */
-
 #define __preempt_schedule()		preempt_schedule()
 #define __preempt_schedule_notrace()	preempt_schedule_notrace()
 
-#endif /* CONFIG_PREEMPT_DYNAMIC */
 #endif /* CONFIG_PREEMPTION */
 
 #endif /* __ASM_PREEMPT_H */
diff --git a/arch/s390/include/asm/preempt.h b/arch/s390/include/asm/preempt.h
index 6e5821bb047e2..797efcbfe394a 100644
--- a/arch/s390/include/asm/preempt.h
+++ b/arch/s390/include/asm/preempt.h
@@ -148,20 +148,9 @@ static __always_inline bool should_resched(int preempt_offset)
 void preempt_schedule(void);
 void preempt_schedule_notrace(void);
 
-#ifdef CONFIG_PREEMPT_DYNAMIC
-
-void dynamic_preempt_schedule(void);
-void dynamic_preempt_schedule_notrace(void);
-#define __preempt_schedule()		dynamic_preempt_schedule()
-#define __preempt_schedule_notrace()	dynamic_preempt_schedule_notrace()
-
-#else /* CONFIG_PREEMPT_DYNAMIC */
-
 #define __preempt_schedule()		preempt_schedule()
 #define __preempt_schedule_notrace()	preempt_schedule_notrace()
 
-#endif /* CONFIG_PREEMPT_DYNAMIC */
-
 #endif /* CONFIG_PREEMPTION */
 
 #endif /* __ASM_PREEMPT_H */
diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h
index 578441db09f0b..14002c2abff44 100644
--- a/arch/x86/include/asm/preempt.h
+++ b/arch/x86/include/asm/preempt.h
@@ -109,43 +109,15 @@ static __always_inline bool should_resched(int preempt_offset)
 extern asmlinkage void preempt_schedule(void);
 extern asmlinkage void preempt_schedule_thunk(void);
 
-#define preempt_schedule_dynamic_enabled	preempt_schedule_thunk
-#define preempt_schedule_dynamic_disabled	NULL
-
 extern asmlinkage void preempt_schedule_notrace(void);
 extern asmlinkage void preempt_schedule_notrace_thunk(void);
 
-#define preempt_schedule_notrace_dynamic_enabled	preempt_schedule_notrace_thunk
-#define preempt_schedule_notrace_dynamic_disabled	NULL
-
-#ifdef CONFIG_PREEMPT_DYNAMIC
-
-DECLARE_STATIC_CALL(preempt_schedule, preempt_schedule_dynamic_enabled);
-
-#define __preempt_schedule() \
-do { \
-	__STATIC_CALL_MOD_ADDRESSABLE(preempt_schedule); \
-	asm volatile ("call " STATIC_CALL_TRAMP_STR(preempt_schedule) : ASM_CALL_CONSTRAINT); \
-} while (0)
-
-DECLARE_STATIC_CALL(preempt_schedule_notrace, preempt_schedule_notrace_dynamic_enabled);
-
-#define __preempt_schedule_notrace() \
-do { \
-	__STATIC_CALL_MOD_ADDRESSABLE(preempt_schedule_notrace); \
-	asm volatile ("call " STATIC_CALL_TRAMP_STR(preempt_schedule_notrace) : ASM_CALL_CONSTRAINT); \
-} while (0)
-
-#else /* PREEMPT_DYNAMIC */
-
 #define __preempt_schedule() \
 	asm volatile ("call preempt_schedule_thunk" : ASM_CALL_CONSTRAINT);
 
 #define __preempt_schedule_notrace() \
 	asm volatile ("call preempt_schedule_notrace_thunk" : ASM_CALL_CONSTRAINT);
 
-#endif /* PREEMPT_DYNAMIC */
-
 #endif /* PREEMPTION */
 
 #endif /* __ASM_PREEMPT_H */
diff --git a/include/asm-generic/preempt.h b/include/asm-generic/preempt.h
index 51f8f3881523a..26309df2a42f3 100644
--- a/include/asm-generic/preempt.h
+++ b/include/asm-generic/preempt.h
@@ -82,19 +82,9 @@ static __always_inline bool should_resched(int preempt_offset)
 extern asmlinkage void preempt_schedule(void);
 extern asmlinkage void preempt_schedule_notrace(void);
 
-#if defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
-
-void dynamic_preempt_schedule(void);
-void dynamic_preempt_schedule_notrace(void);
-#define __preempt_schedule()		dynamic_preempt_schedule()
-#define __preempt_schedule_notrace()	dynamic_preempt_schedule_notrace()
-
-#else /* !CONFIG_PREEMPT_DYNAMIC || !CONFIG_HAVE_PREEMPT_DYNAMIC_KEY*/
-
 #define __preempt_schedule() preempt_schedule()
 #define __preempt_schedule_notrace() preempt_schedule_notrace()
 
-#endif /* CONFIG_PREEMPT_DYNAMIC && CONFIG_HAVE_PREEMPT_DYNAMIC_KEY*/
 #endif /* CONFIG_PREEMPTION */
 
 #endif /* __ASM_PREEMPT_H */
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 84ec93694d718..f88b9ef70a0dd 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7439,27 +7439,6 @@ asmlinkage __visible void __sched notrace preempt_schedule(void)
 NOKPROBE_SYMBOL(preempt_schedule);
 EXPORT_SYMBOL(preempt_schedule);
 
-#ifdef CONFIG_PREEMPT_DYNAMIC
-# ifdef CONFIG_HAVE_PREEMPT_DYNAMIC_CALL
-#  ifndef preempt_schedule_dynamic_enabled
-#   define preempt_schedule_dynamic_enabled	preempt_schedule
-#   define preempt_schedule_dynamic_disabled	NULL
-#  endif
-DEFINE_STATIC_CALL(preempt_schedule, preempt_schedule_dynamic_enabled);
-EXPORT_STATIC_CALL_TRAMP(preempt_schedule);
-# elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
-static DEFINE_STATIC_KEY_TRUE(sk_dynamic_preempt_schedule);
-void __sched notrace dynamic_preempt_schedule(void)
-{
-	if (!static_branch_unlikely(&sk_dynamic_preempt_schedule))
-		return;
-	preempt_schedule();
-}
-NOKPROBE_SYMBOL(dynamic_preempt_schedule);
-EXPORT_SYMBOL(dynamic_preempt_schedule);
-# endif
-#endif /* CONFIG_PREEMPT_DYNAMIC */
-
 /**
  * preempt_schedule_notrace - preempt_schedule called by tracing
  *
@@ -7512,27 +7491,6 @@ asmlinkage __visible void __sched notrace preempt_schedule_notrace(void)
 }
 EXPORT_SYMBOL_GPL(preempt_schedule_notrace);
 
-#ifdef CONFIG_PREEMPT_DYNAMIC
-# if defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
-#  ifndef preempt_schedule_notrace_dynamic_enabled
-#   define preempt_schedule_notrace_dynamic_enabled	preempt_schedule_notrace
-#   define preempt_schedule_notrace_dynamic_disabled	NULL
-#  endif
-DEFINE_STATIC_CALL(preempt_schedule_notrace, preempt_schedule_notrace_dynamic_enabled);
-EXPORT_STATIC_CALL_TRAMP(preempt_schedule_notrace);
-# elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
-static DEFINE_STATIC_KEY_TRUE(sk_dynamic_preempt_schedule_notrace);
-void __sched notrace dynamic_preempt_schedule_notrace(void)
-{
-	if (!static_branch_unlikely(&sk_dynamic_preempt_schedule_notrace))
-		return;
-	preempt_schedule_notrace();
-}
-NOKPROBE_SYMBOL(dynamic_preempt_schedule_notrace);
-EXPORT_SYMBOL(dynamic_preempt_schedule_notrace);
-# endif
-#endif
-
 #endif /* CONFIG_PREEMPTION */
 
 /*
@@ -7830,8 +7788,6 @@ EXPORT_SYMBOL(__cond_resched_rwlock_write);
 # endif
 
 /*
- * SC:preempt_schedule
- * SC:preempt_schedule_notrace
  * SC:irqentry_exit_cond_resched
  *
  *
@@ -7842,14 +7798,10 @@ EXPORT_SYMBOL(__cond_resched_rwlock_write);
  *   (unselectable)
  *
  * FULL:
- *   preempt_schedule           <- preempt_schedule
- *   preempt_schedule_notrace   <- preempt_schedule_notrace
  *   irqentry_exit_cond_resched <- irqentry_exit_cond_resched
  *   dynamic_preempt_lazy       <- false
  *
  * LAZY:
- *   preempt_schedule           <- preempt_schedule
- *   preempt_schedule_notrace   <- preempt_schedule_notrace
  *   irqentry_exit_cond_resched <- irqentry_exit_cond_resched
  *   dynamic_preempt_lazy       <- true
  */
@@ -7894,8 +7846,6 @@ static void __sched_dynamic_update(int mode)
 {
 	switch (mode) {
 	case preempt_dynamic_full:
-		preempt_dynamic_enable(preempt_schedule);
-		preempt_dynamic_enable(preempt_schedule_notrace);
 		preempt_dynamic_enable(irqentry_exit_cond_resched);
 		preempt_dynamic_key_disable(preempt_lazy);
 		if (mode != preempt_dynamic_mode)
@@ -7903,8 +7853,6 @@ static void __sched_dynamic_update(int mode)
 		break;
 
 	case preempt_dynamic_lazy:
-		preempt_dynamic_enable(preempt_schedule);
-		preempt_dynamic_enable(preempt_schedule_notrace);
 		preempt_dynamic_enable(irqentry_exit_cond_resched);
 		preempt_dynamic_key_enable(preempt_lazy);
 		if (mode != preempt_dynamic_mode)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/5] sched: dynamic: Simplify irqentry_exit_cond_resched()
  2026-07-03 13:33 [PATCH 0/5] sched: dynamic: Simplify PREEMPT_DYNAMIC Mark Rutland
                   ` (2 preceding siblings ...)
  2026-07-03 13:33 ` [PATCH 3/5] sched: dynamic: Simplify preempt_schedule{,_notrace}() Mark Rutland
@ 2026-07-03 13:33 ` Mark Rutland
  2026-07-06  4:42   ` Shrikanth Hegde
  2026-07-03 13:33 ` [PATCH 5/5] sched: dynamic: Remove HAVE_PREEMPT_DYNAMIC_{CALL,KEY} Mark Rutland
  2026-07-06  4:30 ` [PATCH 0/5] sched: dynamic: Simplify PREEMPT_DYNAMIC Shrikanth Hegde
  5 siblings, 1 reply; 11+ messages in thread
From: Mark Rutland @ 2026-07-03 13:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: frederic, jstultz, juri.lelli, mark.rutland, mingo, peterz, tglx,
	vincent.guittot, vschneid

PREEMPT_DYNAMIC is now limited to the FULL and LAZY preemption models.
In either model, irqentry_exit_cond_resched() is always called and never
disabled.

Remove the unnecessary code for this when PREEMPT_DYNAMIC is selected.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: John Stultz <jstultz@google.com>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
---
 arch/powerpc/include/asm/preempt.h |  7 -------
 include/linux/irq-entry-common.h   | 17 +----------------
 kernel/entry/common.c              | 17 ++---------------
 kernel/sched/core.c                |  7 -------
 4 files changed, 3 insertions(+), 45 deletions(-)

diff --git a/arch/powerpc/include/asm/preempt.h b/arch/powerpc/include/asm/preempt.h
index 000e2b9681f30..79fc1f9df88d9 100644
--- a/arch/powerpc/include/asm/preempt.h
+++ b/arch/powerpc/include/asm/preempt.h
@@ -4,13 +4,6 @@
 
 #include <asm-generic/preempt.h>
 
-#if defined(CONFIG_PREEMPT_DYNAMIC)
-#include <linux/jump_label.h>
-DECLARE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
-#define need_irq_preemption() \
-	(static_branch_unlikely(&sk_dynamic_irqentry_exit_cond_resched))
-#else
 #define need_irq_preemption()   (IS_ENABLED(CONFIG_PREEMPTION))
-#endif
 
 #endif /* __ASM_POWERPC_PREEMPT_H */
diff --git a/include/linux/irq-entry-common.h b/include/linux/irq-entry-common.h
index 1fabf0f5ea8e7..de7e10de91d04 100644
--- a/include/linux/irq-entry-common.h
+++ b/include/linux/irq-entry-common.h
@@ -346,22 +346,7 @@ typedef struct irqentry_state {
  *
  * Conditional reschedule with additional sanity checks.
  */
-void raw_irqentry_exit_cond_resched(void);
-
-#ifdef CONFIG_PREEMPT_DYNAMIC
-#if defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
-#define irqentry_exit_cond_resched_dynamic_enabled	raw_irqentry_exit_cond_resched
-#define irqentry_exit_cond_resched_dynamic_disabled	NULL
-DECLARE_STATIC_CALL(irqentry_exit_cond_resched, raw_irqentry_exit_cond_resched);
-#define irqentry_exit_cond_resched()	static_call(irqentry_exit_cond_resched)()
-#elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
-DECLARE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
-void dynamic_irqentry_exit_cond_resched(void);
-#define irqentry_exit_cond_resched()	dynamic_irqentry_exit_cond_resched()
-#endif
-#else /* CONFIG_PREEMPT_DYNAMIC */
-#define irqentry_exit_cond_resched()	raw_irqentry_exit_cond_resched()
-#endif /* CONFIG_PREEMPT_DYNAMIC */
+void irqentry_exit_cond_resched(void);
 
 /**
  * irqentry_enter_from_kernel_mode - Establish state before invoking the irq handler
diff --git a/kernel/entry/common.c b/kernel/entry/common.c
index e3d381fd3d251..e234b04373fea 100644
--- a/kernel/entry/common.c
+++ b/kernel/entry/common.c
@@ -123,7 +123,7 @@ noinstr irqentry_state_t irqentry_enter(struct pt_regs *regs)
 /**
  * arch_irqentry_exit_need_resched - Architecture specific need resched function
  *
- * Invoked from raw_irqentry_exit_cond_resched() to check if resched is needed.
+ * Invoked from irqentry_exit_cond_resched() to check if resched is needed.
  * Defaults return true.
  *
  * The main purpose is to permit arch to avoid preemption of a task from an IRQ.
@@ -134,7 +134,7 @@ static inline bool arch_irqentry_exit_need_resched(void);
 static inline bool arch_irqentry_exit_need_resched(void) { return true; }
 #endif
 
-void raw_irqentry_exit_cond_resched(void)
+void irqentry_exit_cond_resched(void)
 {
 	if (!preempt_count()) {
 		/* Sanity check RCU and thread stack */
@@ -145,19 +145,6 @@ void raw_irqentry_exit_cond_resched(void)
 			preempt_schedule_irq();
 	}
 }
-#ifdef CONFIG_PREEMPT_DYNAMIC
-#if defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
-DEFINE_STATIC_CALL(irqentry_exit_cond_resched, raw_irqentry_exit_cond_resched);
-#elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
-DEFINE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
-void dynamic_irqentry_exit_cond_resched(void)
-{
-	if (!static_branch_unlikely(&sk_dynamic_irqentry_exit_cond_resched))
-		return;
-	raw_irqentry_exit_cond_resched();
-}
-#endif
-#endif
 
 noinstr void irqentry_exit(struct pt_regs *regs, irqentry_state_t state)
 {
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index f88b9ef70a0dd..4f754f4a472f8 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7788,9 +7788,6 @@ EXPORT_SYMBOL(__cond_resched_rwlock_write);
 # endif
 
 /*
- * SC:irqentry_exit_cond_resched
- *
- *
  * NONE:
  *   (unselectable)
  *
@@ -7798,11 +7795,9 @@ EXPORT_SYMBOL(__cond_resched_rwlock_write);
  *   (unselectable)
  *
  * FULL:
- *   irqentry_exit_cond_resched <- irqentry_exit_cond_resched
  *   dynamic_preempt_lazy       <- false
  *
  * LAZY:
- *   irqentry_exit_cond_resched <- irqentry_exit_cond_resched
  *   dynamic_preempt_lazy       <- true
  */
 
@@ -7846,14 +7841,12 @@ static void __sched_dynamic_update(int mode)
 {
 	switch (mode) {
 	case preempt_dynamic_full:
-		preempt_dynamic_enable(irqentry_exit_cond_resched);
 		preempt_dynamic_key_disable(preempt_lazy);
 		if (mode != preempt_dynamic_mode)
 			pr_info("Dynamic Preempt: full\n");
 		break;
 
 	case preempt_dynamic_lazy:
-		preempt_dynamic_enable(irqentry_exit_cond_resched);
 		preempt_dynamic_key_enable(preempt_lazy);
 		if (mode != preempt_dynamic_mode)
 			pr_info("Dynamic Preempt: lazy\n");
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/5] sched: dynamic: Remove HAVE_PREEMPT_DYNAMIC_{CALL,KEY}
  2026-07-03 13:33 [PATCH 0/5] sched: dynamic: Simplify PREEMPT_DYNAMIC Mark Rutland
                   ` (3 preceding siblings ...)
  2026-07-03 13:33 ` [PATCH 4/5] sched: dynamic: Simplify irqentry_exit_cond_resched() Mark Rutland
@ 2026-07-03 13:33 ` Mark Rutland
  2026-07-06  4:30 ` [PATCH 0/5] sched: dynamic: Simplify PREEMPT_DYNAMIC Shrikanth Hegde
  5 siblings, 0 replies; 11+ messages in thread
From: Mark Rutland @ 2026-07-03 13:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: frederic, jstultz, juri.lelli, mark.rutland, mingo, peterz, tglx,
	vincent.guittot, vschneid

PREEMPT_DYNAMIC is now limited to the FULL and LAZY preemption models.
Switching model only changes the behaviour of dynamic_preempt_lazy(),
which uses a static key. There are no other static calls or static keys,
and so there's no need for HAVE_PREEMPT_DYNAMIC_CALL or
HAVE_PREEMPT_DYNAMIC_KEY.

The static key used by dynamic_preempt_lazy() is entirely local to
kernel/sched/core.c, and any architecture which selects
ARCH_HAS_PREEMPT_LAZY implements the necessary support. Remove
PREEMPT_DYNAMIC's dependencies on HAVE_PREEMPT_DYNAMIC_CALL and
HAVE_PREEMPT_DYNAMIC_KEY entirely, leaving the depenency on
ARCH_HAS_PREEMPT_LAZY.

For architectures which previously selected HAVE_PREEMPT_DYNAMIC_KEY,
PREEMPT_DYNAMIC will now be selected by default, matching x86. As the
runtime impact is limited to dynamic_preempt_lazy(), this shouldn't be
as concerning as previously (e.g. where calls to {cond,might}_resched()
stubs could introduce a measurable penalty).

As all of this can work without jump labels, JUMP_LABEL is not selected
explicitly, though it is obviously preferable to have JUMP_LABEL
enabled.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: John Stultz <jstultz@google.com>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
---
 arch/Kconfig           | 38 --------------------------------------
 arch/arm64/Kconfig     |  1 -
 arch/loongarch/Kconfig |  1 -
 arch/powerpc/Kconfig   |  1 -
 arch/riscv/Kconfig     |  1 -
 arch/s390/Kconfig      |  1 -
 arch/x86/Kconfig       |  1 -
 kernel/Kconfig.preempt |  8 ++------
 kernel/sched/core.c    | 10 ----------
 9 files changed, 2 insertions(+), 60 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index fa7507ac8e13e..16e46010922a5 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1696,44 +1696,6 @@ config HAVE_STATIC_CALL_INLINE
 	depends on HAVE_STATIC_CALL
 	select OBJTOOL
 
-config HAVE_PREEMPT_DYNAMIC
-	bool
-
-config HAVE_PREEMPT_DYNAMIC_CALL
-	bool
-	depends on HAVE_STATIC_CALL
-	select HAVE_PREEMPT_DYNAMIC
-	help
-	  An architecture should select this if it can handle the preemption
-	  model being selected at boot time using static calls.
-
-	  Where an architecture selects HAVE_STATIC_CALL_INLINE, any call to a
-	  preemption function will be patched directly.
-
-	  Where an architecture does not select HAVE_STATIC_CALL_INLINE, any
-	  call to a preemption function will go through a trampoline, and the
-	  trampoline will be patched.
-
-	  It is strongly advised to support inline static call to avoid any
-	  overhead.
-
-config HAVE_PREEMPT_DYNAMIC_KEY
-	bool
-	depends on HAVE_ARCH_JUMP_LABEL
-	select HAVE_PREEMPT_DYNAMIC
-	help
-	  An architecture should select this if it can handle the preemption
-	  model being selected at boot time using static keys.
-
-	  Each preemption function will be given an early return based on a
-	  static key. This should have slightly lower overhead than non-inline
-	  static calls, as this effectively inlines each trampoline into the
-	  start of its callee. This may avoid redundant work, and may
-	  integrate better with CFI schemes.
-
-	  This will have greater overhead than using inline static calls as
-	  the call to the preemption function cannot be entirely elided.
-
 config ARCH_WANT_LD_ORPHAN_WARN
 	bool
 	help
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b3afe0688919b..1504bc354b9e5 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -216,7 +216,6 @@ config ARM64
 	select HAVE_PERF_EVENTS_NMI if ARM64_PSEUDO_NMI
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
-	select HAVE_PREEMPT_DYNAMIC_KEY
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_RELIABLE_STACKTRACE
 	select HAVE_POSIX_CPU_TIMERS_TASK_WORK
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index d8d2523250179..1889d808597da 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -170,7 +170,6 @@ config LOONGARCH
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_POSIX_CPU_TIMERS_TASK_WORK
-	select HAVE_PREEMPT_DYNAMIC_KEY
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_RELIABLE_STACKTRACE if UNWINDER_ORC
 	select HAVE_RETHOOK
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index f7ce5fff81f03..940f8fbea55c5 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -280,7 +280,6 @@ config PPC
 	select HAVE_PERF_EVENTS_NMI		if PPC64
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
-	select HAVE_PREEMPT_DYNAMIC_KEY
 	select HAVE_RETHOOK			if KPROBES
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_RELIABLE_STACKTRACE
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 3f0a647218e40..dfdf56f8542aa 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -193,7 +193,6 @@ config RISCV
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_POSIX_CPU_TIMERS_TASK_WORK
-	select HAVE_PREEMPT_DYNAMIC_KEY
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_RETHOOK
 	select HAVE_RSEQ
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 84404e6778d50..ad527859694ab 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -239,7 +239,6 @@ config S390
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_POSIX_CPU_TIMERS_TASK_WORK
-	select HAVE_PREEMPT_DYNAMIC_KEY
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_RELIABLE_STACKTRACE
 	select HAVE_RETHOOK
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bdad90f210e4b..b05ffa8f661b4 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -294,7 +294,6 @@ config X86
 	select HAVE_STACK_VALIDATION		if HAVE_OBJTOOL
 	select HAVE_STATIC_CALL
 	select HAVE_STATIC_CALL_INLINE		if HAVE_OBJTOOL
-	select HAVE_PREEMPT_DYNAMIC_CALL
 	select HAVE_RSEQ
 	select HAVE_RUST			if X86_64
 	select HAVE_SYSCALL_TRACEPOINTS
diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
index fb49424003b2b..87d567680bc74 100644
--- a/kernel/Kconfig.preempt
+++ b/kernel/Kconfig.preempt
@@ -128,11 +128,9 @@ 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
+	default y
 	help
 	  This option allows to define the preemption model on the kernel
 	  command line parameter and thus override the default preemption
@@ -142,9 +140,7 @@ config PREEMPT_DYNAMIC
 	  provide a pre-built kernel binary to reduce the number of kernel
 	  flavors they offer while still offering different usecases.
 
-	  The runtime overhead is negligible with HAVE_STATIC_CALL_INLINE enabled
-	  but if runtime patching is not available for the specific architecture
-	  then the potential overhead should be considered.
+	  The runtime overhead is negligible.
 
 	  Interesting if you want the same pre-built kernel should be used for
 	  both Server and Desktop workloads.
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 4f754f4a472f8..7b815d8ce67d3 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7825,16 +7825,6 @@ int sched_dynamic_mode(const char *str)
 # define preempt_dynamic_key_enable(f)	static_key_enable(&sk_dynamic_##f.key)
 # define preempt_dynamic_key_disable(f)	static_key_disable(&sk_dynamic_##f.key)
 
-# if defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
-#  define preempt_dynamic_enable(f)	static_call_update(f, f##_dynamic_enabled)
-#  define preempt_dynamic_disable(f)	static_call_update(f, f##_dynamic_disabled)
-# elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
-#  define preempt_dynamic_enable(f)	preempt_dynamic_key_enable(f)
-#  define preempt_dynamic_disable(f)	preempt_dynamic_key_disable(f)
-# else
-#  error "Unsupported PREEMPT_DYNAMIC mechanism"
-# endif
-
 static DEFINE_MUTEX(sched_dynamic_mutex);
 
 static void __sched_dynamic_update(int mode)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/5] sched: dynamic: Simplify PREEMPT_DYNAMIC
  2026-07-03 13:33 [PATCH 0/5] sched: dynamic: Simplify PREEMPT_DYNAMIC Mark Rutland
                   ` (4 preceding siblings ...)
  2026-07-03 13:33 ` [PATCH 5/5] sched: dynamic: Remove HAVE_PREEMPT_DYNAMIC_{CALL,KEY} Mark Rutland
@ 2026-07-06  4:30 ` Shrikanth Hegde
  5 siblings, 0 replies; 11+ messages in thread
From: Shrikanth Hegde @ 2026-07-06  4:30 UTC (permalink / raw)
  To: Mark Rutland, linux-kernel
  Cc: frederic, jstultz, juri.lelli, mingo, peterz, tglx,
	vincent.guittot, vschneid

Hi Mark,

On 7/3/26 7:03 PM, Mark Rutland wrote:
> All architectures which currently suppoort PREEMPT_DYNAMIC select
> 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 v7.0 due to commit:
> 
>    7dadeaa6e851 ("sched: Further restrict the preemption modes")
> 
> Hence in practice PREEMPT_DYNAMIC no longer supports the NONE or
> VOLUNTARY preemption models.
> 
> This series makes the de-facto situation official by making
> PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY, and removing all the
> redundant code.

This cleanup looks good indeed. little bit more cleanup can be added,
details of it at the end.

> 
> For x86_64 v7.2-rc1 defconfig built with GCC 10.2.1, this makes the
> bzImage 28K smaller, mostly due to removing NOPs that will never be
> patched to {cond,might}_resched() at runtime:
> 
>    [mark@lakrids:~/src/linux]% ls -al vmlinux-*
>    -rwxr-xr-x 1 mark mark 53844952 Jul  3 14:09 vmlinux-after
>    -rwxr-xr-x 1 mark mark 53842856 Jul  3 14:09 vmlinux-before

Is this reversed? How come vmlinux is more whereas bzImage is less?

>    [mark@lakrids:~/src/linux]% ls -al bzImage-*
>    -rw-r--r-- 1 mark mark 14771200 Jul  3 14:09 bzImage-after
>    -rw-r--r-- 1 mark mark 14799872 Jul  3 14:08 bzImage-before
> 
> Mark.
> 
> Mark Rutland (5):
>    sched: dynamic: Make PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY
>    sched: dynamic: Simplify {cond,might}_resched()
>    sched: dynamic: Simplify preempt_schedule{,_notrace}()
>    sched: dynamic: Simplify irqentry_exit_cond_resched()
>    sched: dynamic: Remove HAVE_PREEMPT_DYNAMIC_{CALL,KEY}
> 
>   arch/Kconfig                       |  38 -------
>   arch/arm64/Kconfig                 |   1 -
>   arch/arm64/include/asm/preempt.h   |  10 --
>   arch/loongarch/Kconfig             |   1 -
>   arch/powerpc/Kconfig               |   1 -
>   arch/powerpc/include/asm/preempt.h |   7 --
>   arch/riscv/Kconfig                 |   1 -
>   arch/s390/Kconfig                  |   1 -
>   arch/s390/include/asm/preempt.h    |  11 --
>   arch/x86/Kconfig                   |   1 -
>   arch/x86/include/asm/preempt.h     |  28 -----
>   include/asm-generic/preempt.h      |  10 --
>   include/linux/irq-entry-common.h   |  17 +--
>   include/linux/kernel.h             |  20 ----
>   include/linux/sched.h              |  31 +----
>   kernel/Kconfig.preempt             |   9 +-
>   kernel/entry/common.c              |  17 +--
>   kernel/sched/core.c                | 176 +----------------------------
>   18 files changed, 13 insertions(+), 367 deletions(-)
> 

Btw, I ran it on powerpc, builds and boots.
Bloat-o-meter says,
Total: Before=32286154, After=32267870, chg -0.06%


In addition,
I think you can also remove accessor methods of none, voluntary.
I see preempt_model_none is used. (Though one may question its usage there).
That wrapper can be outside of #ifdef as preempt dynamic can't choose
none/voluntary.

---

diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index d964f965c8ff..b4dd4fc13cf8 100644
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -469,22 +469,9 @@ DEFINE_LOCK_GUARD_0(preempt, preempt_disable(), preempt_enable())
  DEFINE_LOCK_GUARD_0(preempt_notrace, preempt_disable_notrace(), preempt_enable_notrace())
  
  #ifdef CONFIG_PREEMPT_DYNAMIC
-
-extern bool preempt_model_none(void);
-extern bool preempt_model_voluntary(void);
  extern bool preempt_model_full(void);
  extern bool preempt_model_lazy(void);
-
  #else
-
-static inline bool preempt_model_none(void)
-{
-       return IS_ENABLED(CONFIG_PREEMPT_NONE);
-}
-static inline bool preempt_model_voluntary(void)
-{
-       return IS_ENABLED(CONFIG_PREEMPT_VOLUNTARY);
-}
  static inline bool preempt_model_full(void)
  {
         return IS_ENABLED(CONFIG_PREEMPT);
@@ -494,9 +481,16 @@ static inline bool preempt_model_lazy(void)
  {
         return IS_ENABLED(CONFIG_PREEMPT_LAZY);
  }
-
  #endif
  
+static inline bool preempt_model_none(void)
+{
+       return IS_ENABLED(CONFIG_PREEMPT_NONE);
+}
+static inline bool preempt_model_voluntary(void)
+{
+       return IS_ENABLED(CONFIG_PREEMPT_VOLUNTARY);
+}
  static inline bool preempt_model_rt(void)
  {
         return IS_ENABLED(CONFIG_PREEMPT_RT);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 9eb279eade26..59a8c8e63ca1 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7815,8 +7815,6 @@ EXPORT_SYMBOL(__cond_resched_rwlock_write);
  
  enum {
         preempt_dynamic_undefined = -1,
-       preempt_dynamic_none,
-       preempt_dynamic_voluntary,
         preempt_dynamic_full,
         preempt_dynamic_lazy,
  };
@@ -7901,8 +7899,6 @@ static void __init preempt_dynamic_init(void)
         }                                                               \
         EXPORT_SYMBOL_GPL(preempt_model_##mode)
  
-PREEMPT_MODEL_ACCESSOR(none);
-PREEMPT_MODEL_ACCESSOR(voluntary);
  PREEMPT_MODEL_ACCESSOR(full);
  PREEMPT_MODEL_ACCESSOR(lazy);
  


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/5] sched: dynamic: Make PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY
  2026-07-03 13:33 ` [PATCH 1/5] sched: dynamic: Make PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY Mark Rutland
@ 2026-07-06  4:36   ` Shrikanth Hegde
  0 siblings, 0 replies; 11+ messages in thread
From: Shrikanth Hegde @ 2026-07-06  4:36 UTC (permalink / raw)
  To: Mark Rutland, linux-kernel
  Cc: frederic, jstultz, juri.lelli, mingo, peterz, tglx,
	vincent.guittot, vschneid



On 7/3/26 7:03 PM, Mark Rutland wrote:
> 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 suppoort PREEMPT_DYNAMIC select

s/suppoort/support

> 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>
> Cc: Frederic Weisbecker <frederic@kernel.org>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: John Stultz <jstultz@google.com>
> Cc: Juri Lelli <juri.lelli@redhat.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Valentin Schneider <vschneid@redhat.com>
> Cc: Vincent Guittot <vincent.guittot@linaro.org>
> ---
>   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 88c594c6d7fcd..fb49424003b2b 100644
> --- a/kernel/Kconfig.preempt
> +++ b/kernel/Kconfig.preempt
> @@ -129,6 +129,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


Can we update the help section bit?

"""
           The runtime overhead is negligible.

           Interesting if you want the same pre-built kernel should be used for
           both Server and Desktop workloads.
"""
I think server meant preempt=none and desktop meant preempt=full/lazy there. No?

> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 96226707c2f61..2db78826a484b 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -7870,20 +7870,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
> @@ -7914,21 +7904,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;
>   }
> @@ -7950,40 +7930,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);
> @@ -8033,11 +7980,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 */

other than that, it looks good to me.

Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/5] sched: dynamic: Simplify irqentry_exit_cond_resched()
  2026-07-03 13:33 ` [PATCH 4/5] sched: dynamic: Simplify irqentry_exit_cond_resched() Mark Rutland
@ 2026-07-06  4:42   ` Shrikanth Hegde
  0 siblings, 0 replies; 11+ messages in thread
From: Shrikanth Hegde @ 2026-07-06  4:42 UTC (permalink / raw)
  To: Mark Rutland, linux-kernel, Christophe Leroy (CS GROUP)
  Cc: frederic, jstultz, juri.lelli, mingo, peterz, tglx,
	vincent.guittot, vschneid

+cc Christophe.

On 7/3/26 7:03 PM, Mark Rutland wrote:
> PREEMPT_DYNAMIC is now limited to the FULL and LAZY preemption models.
> In either model, irqentry_exit_cond_resched() is always called and never
> disabled.
> 
> Remove the unnecessary code for this when PREEMPT_DYNAMIC is selected.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Frederic Weisbecker <frederic@kernel.org>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: John Stultz <jstultz@google.com>
> Cc: Juri Lelli <juri.lelli@redhat.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Valentin Schneider <vschneid@redhat.com>
> Cc: Vincent Guittot <vincent.guittot@linaro.org>
> ---
>   arch/powerpc/include/asm/preempt.h |  7 -------
>   include/linux/irq-entry-common.h   | 17 +----------------
>   kernel/entry/common.c              | 17 ++---------------
>   kernel/sched/core.c                |  7 -------
>   4 files changed, 3 insertions(+), 45 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/preempt.h b/arch/powerpc/include/asm/preempt.h
> index 000e2b9681f30..79fc1f9df88d9 100644
> --- a/arch/powerpc/include/asm/preempt.h
> +++ b/arch/powerpc/include/asm/preempt.h
> @@ -4,13 +4,6 @@
>   
>   #include <asm-generic/preempt.h>
>   
> -#if defined(CONFIG_PREEMPT_DYNAMIC)
> -#include <linux/jump_label.h>
> -DECLARE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
> -#define need_irq_preemption() \
> -	(static_branch_unlikely(&sk_dynamic_irqentry_exit_cond_resched))
> -#else
>   #define need_irq_preemption()   (IS_ENABLED(CONFIG_PREEMPTION))
> -#endif
>   

JFYI,
Christophe had sent this patch, I am sure you guys will sort out the
conflicts. (I don't see it merged yet, but likely might)

https://lore.kernel.org/all/2bf10a0afffefb6aca44bf2f864cc17471a80e31.1781870889.git.chleroy@kernel.org/

>   #endif /* __ASM_POWERPC_PREEMPT_H */
> diff --git a/include/linux/irq-entry-common.h b/include/linux/irq-entry-common.h
> index 1fabf0f5ea8e7..de7e10de91d04 100644
> --- a/include/linux/irq-entry-common.h
> +++ b/include/linux/irq-entry-common.h
> @@ -346,22 +346,7 @@ typedef struct irqentry_state {
>    *
>    * Conditional reschedule with additional sanity checks.
>    */
> -void raw_irqentry_exit_cond_resched(void);
> -
> -#ifdef CONFIG_PREEMPT_DYNAMIC
> -#if defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
> -#define irqentry_exit_cond_resched_dynamic_enabled	raw_irqentry_exit_cond_resched
> -#define irqentry_exit_cond_resched_dynamic_disabled	NULL
> -DECLARE_STATIC_CALL(irqentry_exit_cond_resched, raw_irqentry_exit_cond_resched);
> -#define irqentry_exit_cond_resched()	static_call(irqentry_exit_cond_resched)()
> -#elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
> -DECLARE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
> -void dynamic_irqentry_exit_cond_resched(void);
> -#define irqentry_exit_cond_resched()	dynamic_irqentry_exit_cond_resched()
> -#endif
> -#else /* CONFIG_PREEMPT_DYNAMIC */
> -#define irqentry_exit_cond_resched()	raw_irqentry_exit_cond_resched()
> -#endif /* CONFIG_PREEMPT_DYNAMIC */
> +void irqentry_exit_cond_resched(void);
>   
>   /**
>    * irqentry_enter_from_kernel_mode - Establish state before invoking the irq handler
> diff --git a/kernel/entry/common.c b/kernel/entry/common.c
> index e3d381fd3d251..e234b04373fea 100644
> --- a/kernel/entry/common.c
> +++ b/kernel/entry/common.c
> @@ -123,7 +123,7 @@ noinstr irqentry_state_t irqentry_enter(struct pt_regs *regs)
>   /**
>    * arch_irqentry_exit_need_resched - Architecture specific need resched function
>    *
> - * Invoked from raw_irqentry_exit_cond_resched() to check if resched is needed.
> + * Invoked from irqentry_exit_cond_resched() to check if resched is needed.
>    * Defaults return true.
>    *
>    * The main purpose is to permit arch to avoid preemption of a task from an IRQ.
> @@ -134,7 +134,7 @@ static inline bool arch_irqentry_exit_need_resched(void);
>   static inline bool arch_irqentry_exit_need_resched(void) { return true; }
>   #endif
>   
> -void raw_irqentry_exit_cond_resched(void)
> +void irqentry_exit_cond_resched(void)
>   {
>   	if (!preempt_count()) {
>   		/* Sanity check RCU and thread stack */
> @@ -145,19 +145,6 @@ void raw_irqentry_exit_cond_resched(void)
>   			preempt_schedule_irq();
>   	}
>   }
> -#ifdef CONFIG_PREEMPT_DYNAMIC
> -#if defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
> -DEFINE_STATIC_CALL(irqentry_exit_cond_resched, raw_irqentry_exit_cond_resched);
> -#elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
> -DEFINE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
> -void dynamic_irqentry_exit_cond_resched(void)
> -{
> -	if (!static_branch_unlikely(&sk_dynamic_irqentry_exit_cond_resched))
> -		return;
> -	raw_irqentry_exit_cond_resched();
> -}
> -#endif
> -#endif
>   
>   noinstr void irqentry_exit(struct pt_regs *regs, irqentry_state_t state)
>   {
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index f88b9ef70a0dd..4f754f4a472f8 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -7788,9 +7788,6 @@ EXPORT_SYMBOL(__cond_resched_rwlock_write);
>   # endif
>   
>   /*
> - * SC:irqentry_exit_cond_resched
> - *
> - *
>    * NONE:
>    *   (unselectable)
>    *
> @@ -7798,11 +7795,9 @@ EXPORT_SYMBOL(__cond_resched_rwlock_write);
>    *   (unselectable)
>    *
>    * FULL:
> - *   irqentry_exit_cond_resched <- irqentry_exit_cond_resched
>    *   dynamic_preempt_lazy       <- false
>    *
>    * LAZY:
> - *   irqentry_exit_cond_resched <- irqentry_exit_cond_resched
>    *   dynamic_preempt_lazy       <- true
>    */
>   
> @@ -7846,14 +7841,12 @@ static void __sched_dynamic_update(int mode)
>   {
>   	switch (mode) {
>   	case preempt_dynamic_full:
> -		preempt_dynamic_enable(irqentry_exit_cond_resched);
>   		preempt_dynamic_key_disable(preempt_lazy);
>   		if (mode != preempt_dynamic_mode)
>   			pr_info("Dynamic Preempt: full\n");
>   		break;
>   
>   	case preempt_dynamic_lazy:
> -		preempt_dynamic_enable(irqentry_exit_cond_resched);
>   		preempt_dynamic_key_enable(preempt_lazy);
>   		if (mode != preempt_dynamic_mode)
>   			pr_info("Dynamic Preempt: lazy\n");

Change per se, looks good to me.

Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/5] sched: dynamic: Simplify {cond,might}_resched()
  2026-07-03 13:33 ` [PATCH 2/5] sched: dynamic: Simplify {cond,might}_resched() Mark Rutland
@ 2026-07-06  4:59   ` Shrikanth Hegde
  0 siblings, 0 replies; 11+ messages in thread
From: Shrikanth Hegde @ 2026-07-06  4:59 UTC (permalink / raw)
  To: Mark Rutland, linux-kernel
  Cc: frederic, jstultz, juri.lelli, mingo, peterz, tglx,
	vincent.guittot, vschneid



On 7/3/26 7:03 PM, Mark Rutland wrote:
> PREEMPT_DYNAMIC is now limited to the FULL and LAZY preemption models.
> In either model, both cond_resched() and might_resched() are always
> disabled and do nothing.
> 
> Remove the unnecessary code for these when PREEMPT_DYNAMIC is selected.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Frederic Weisbecker <frederic@kernel.org>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: John Stultz <jstultz@google.com>
> Cc: Juri Lelli <juri.lelli@redhat.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Valentin Schneider <vschneid@redhat.com>
> Cc: Vincent Guittot <vincent.guittot@linaro.org>
> ---
>   include/linux/kernel.h | 20 -------------------
>   include/linux/sched.h  | 31 +++--------------------------
>   kernel/sched/core.c    | 44 +-----------------------------------------
>   3 files changed, 4 insertions(+), 91 deletions(-)
> 
> diff --git a/include/linux/kernel.h b/include/linux/kernel.h
> index e5570a16cbb1a..533ee1e6e1cb7 100644
> --- a/include/linux/kernel.h
> +++ b/include/linux/kernel.h
> @@ -43,30 +43,10 @@ struct completion;
>   struct user;
>   
>   #ifdef CONFIG_PREEMPT_VOLUNTARY_BUILD

Would it make sense to move this block under CONFIG_PREEMPT_VOLUNTARY_BUILD
to include/linux/sched.h so they all in one header?

this builds. I meant something like below.
---

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 533ee1e6e1cb..49495eb754d5 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -42,13 +42,6 @@
  struct completion;
  struct user;
  
-#ifdef CONFIG_PREEMPT_VOLUNTARY_BUILD
-extern int __cond_resched(void);
-# define might_resched() __cond_resched()
-#else
-# define might_resched() do { } while (0)
-#endif /* CONFIG_PREEMPT_* */
-
  #ifdef CONFIG_DEBUG_ATOMIC_SLEEP
  extern void __might_resched(const char *file, int line, unsigned int offsets);
  extern void __might_sleep(const char *file, int line);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index db6e757e83c7..ddc9aae96e55 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2112,6 +2112,13 @@ static inline void set_need_resched_current(void)
         set_preempt_need_resched();
  }
  
+#ifdef CONFIG_PREEMPT_VOLUNTARY_BUILD
+extern int __cond_resched(void);
+# define might_resched() __cond_resched()
+#else
+# define might_resched() do { } while (0)
+#endif /* CONFIG_PREEMPT_* */
+
  /*
   * cond_resched() and cond_resched_lock(): latency reduction via
   * explicit rescheduling in places that are safe. The return


> -
>   extern int __cond_resched(void);
>   # define might_resched() __cond_resched()
> -
> -#elif defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
> -
> -extern int __cond_resched(void);
> -
> -DECLARE_STATIC_CALL(might_resched, __cond_resched);
> -
> -static __always_inline void might_resched(void)
> -{
> -	static_call_mod(might_resched)();
> -}
> -
> -#elif defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
> -
> -extern int dynamic_might_resched(void);
> -# define might_resched() dynamic_might_resched()
> -
>   #else
> -
>   # define might_resched() do { } while (0)
> -
>   #endif /* CONFIG_PREEMPT_* */
>   
>   #ifdef CONFIG_DEBUG_ATOMIC_SLEEP


Other than that, rest looks good to me.

Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/5] sched: dynamic: Simplify preempt_schedule{,_notrace}()
  2026-07-03 13:33 ` [PATCH 3/5] sched: dynamic: Simplify preempt_schedule{,_notrace}() Mark Rutland
@ 2026-07-06  5:19   ` Shrikanth Hegde
  0 siblings, 0 replies; 11+ messages in thread
From: Shrikanth Hegde @ 2026-07-06  5:19 UTC (permalink / raw)
  To: Mark Rutland, linux-kernel
  Cc: frederic, jstultz, juri.lelli, mingo, peterz, tglx,
	vincent.guittot, vschneid



On 7/3/26 7:03 PM, Mark Rutland wrote:
> PREEMPT_DYNAMIC is now limited to the FULL and LAZY preemption models.
> In either model, both preempt_schedule() and preempt_schedule_notrace()
> are always called and never disabled.
> 
> Remove the unnecessary code for these when PREEMPT_DYNAMIC is selected.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Frederic Weisbecker <frederic@kernel.org>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: John Stultz <jstultz@google.com>
> Cc: Juri Lelli <juri.lelli@redhat.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Valentin Schneider <vschneid@redhat.com>
> Cc: Vincent Guittot <vincent.guittot@linaro.org>
> ---

Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-07-06  5:19 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-03 13:33 [PATCH 0/5] sched: dynamic: Simplify PREEMPT_DYNAMIC Mark Rutland
2026-07-03 13:33 ` [PATCH 1/5] sched: dynamic: Make PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY Mark Rutland
2026-07-06  4:36   ` Shrikanth Hegde
2026-07-03 13:33 ` [PATCH 2/5] sched: dynamic: Simplify {cond,might}_resched() Mark Rutland
2026-07-06  4:59   ` Shrikanth Hegde
2026-07-03 13:33 ` [PATCH 3/5] sched: dynamic: Simplify preempt_schedule{,_notrace}() Mark Rutland
2026-07-06  5:19   ` Shrikanth Hegde
2026-07-03 13:33 ` [PATCH 4/5] sched: dynamic: Simplify irqentry_exit_cond_resched() Mark Rutland
2026-07-06  4:42   ` Shrikanth Hegde
2026-07-03 13:33 ` [PATCH 5/5] sched: dynamic: Remove HAVE_PREEMPT_DYNAMIC_{CALL,KEY} Mark Rutland
2026-07-06  4:30 ` [PATCH 0/5] sched: dynamic: Simplify PREEMPT_DYNAMIC Shrikanth Hegde

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox