* [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; 17+ 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] 17+ 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; 17+ 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 [flat|nested] 17+ 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; 17+ 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 [flat|nested] 17+ 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; 17+ 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 [flat|nested] 17+ 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; 17+ 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 [flat|nested] 17+ 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; 17+ 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 [flat|nested] 17+ 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
2026-07-17 11:35 ` Mark Rutland
5 siblings, 1 reply; 17+ 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 [flat|nested] 17+ 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
2026-07-17 10:59 ` Mark Rutland
0 siblings, 1 reply; 17+ 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] 17+ 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
2026-07-17 11:05 ` Mark Rutland
0 siblings, 1 reply; 17+ 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] 17+ 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
2026-07-17 11:03 ` Mark Rutland
0 siblings, 1 reply; 17+ 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 [flat|nested] 17+ 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; 17+ 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] 17+ messages in thread
* Re: [PATCH 1/5] sched: dynamic: Make PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY
2026-07-06 4:36 ` Shrikanth Hegde
@ 2026-07-17 10:59 ` Mark Rutland
0 siblings, 0 replies; 17+ messages in thread
From: Mark Rutland @ 2026-07-17 10:59 UTC (permalink / raw)
To: Shrikanth Hegde
Cc: linux-kernel, frederic, jstultz, juri.lelli, mingo, peterz, tglx,
vincent.guittot, vschneid
On Mon, Jul 06, 2026 at 10:06:29AM +0530, Shrikanth Hegde wrote:
> 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
Thanks; fixed locally now.
[...]
> > 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?
I think that's the common case, yes.
I think the existing wording isn't wrong, so I'm going to leave it as-is
for now, given the wording change is logically separate from the other
changes.
[...]
> other than that, it looks good to me.
>
> Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Thanks!
Mark.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/5] sched: dynamic: Simplify {cond,might}_resched()
2026-07-06 4:59 ` Shrikanth Hegde
@ 2026-07-17 11:03 ` Mark Rutland
0 siblings, 0 replies; 17+ messages in thread
From: Mark Rutland @ 2026-07-17 11:03 UTC (permalink / raw)
To: Shrikanth Hegde
Cc: linux-kernel, frederic, jstultz, juri.lelli, mingo, peterz, tglx,
vincent.guittot, vschneid
On Mon, Jul 06, 2026 at 10:29:26AM +0530, Shrikanth Hegde wrote:
> 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?
That sounds reasonable, but please see comments below -- I'm not sure
it's a win overall.
>
> 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);
There's no explicit include of <linux/sched.h> in <linux/kernel.h>, so
this change means later usage of __cond_resched() (via might_resched())
relies on that occurring by coincidence, which is fragile. We could add
an include to handle that, but then we're adding another include to
kernel.h....
I'm not sure whether it's best to move this now, or to just wait until
VOLUNTARY preemption is truly dead, and delete this entirely.
For the moment I'm going to err to the latter.
[...]
> Other than that, rest looks good to me.
>
> Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Thanks!
Mark.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 4/5] sched: dynamic: Simplify irqentry_exit_cond_resched()
2026-07-06 4:42 ` Shrikanth Hegde
@ 2026-07-17 11:05 ` Mark Rutland
2026-07-17 13:49 ` Shrikanth Hegde
0 siblings, 1 reply; 17+ messages in thread
From: Mark Rutland @ 2026-07-17 11:05 UTC (permalink / raw)
To: Shrikanth Hegde
Cc: linux-kernel, Christophe Leroy (CS GROUP),
frederic, jstultz, juri.lelli, mingo, peterz, tglx,
vincent.guittot, vschneid
On Mon, Jul 06, 2026 at 10:12:29AM +0530, Shrikanth Hegde wrote:
> +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/
Thanks for the heads-up!
Sorry, I'd skipped Ccing all the arch folk as I hadn't expected anyone
was likely to be doing similar in the arch code right now. I'll make
sure you're both Cc'd for any subsequent versions.
It looks like the only difference for powerpc is that I leave
need_irq_preemption() lying around. Christophe, if you're happy with
this series, I could pick a patch from you to remove that (e.g. take
your patch and apply it to the end of this series, reduced to removing
need_irq_preemption()).
Any preference?
[...]
> Change per se, looks good to me.
>
> Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Thanks!
Mark.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 0/5] sched: dynamic: Simplify PREEMPT_DYNAMIC
2026-07-06 4:30 ` [PATCH 0/5] sched: dynamic: Simplify PREEMPT_DYNAMIC Shrikanth Hegde
@ 2026-07-17 11:35 ` Mark Rutland
0 siblings, 0 replies; 17+ messages in thread
From: Mark Rutland @ 2026-07-17 11:35 UTC (permalink / raw)
To: Shrikanth Hegde
Cc: linux-kernel, frederic, jstultz, juri.lelli, mingo, peterz, tglx,
vincent.guittot, vschneid
On Mon, Jul 06, 2026 at 10:00:47AM +0530, Shrikanth Hegde wrote:
> 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?
Not reversed! The vmlinux after is bigger (but the bzImage is smaller).
I'm not immediately sure why.
I rebuilt afresh, and I see:
[mark@lakrids:~/src/linux]% ls -l ../vmlinux-*
-rwxr-xr-x 1 mark mark 53844952 Jul 6 15:42 ../vmlinux-after
-rwxr-xr-x 1 mark mark 53842856 Jul 6 15:45 ../vmlinux-before
[mark@lakrids:~/src/linux]% size ../vmlinux-*
text data bss dec hex filename
31064917 8823782 1112412 41001111 271a097 ../vmlinux-after
31066343 8860886 1112548 41039777 27237a1 ../vmlinux-before
[mark@lakrids:~/src/linux]% readelf -S ../vmlinux-*
File: ../vmlinux-after
There are 47 section headers, starting at offset 0x3359018:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS ffffffff81000000 00200000
00000000012a5588 0000000000000000 AX 0 0 4096
[ 2] .rodata PROGBITS ffffffff82400000 01600000
0000000000757ae6 0000000000000000 WA 0 0 4096
[ 3] .pci_fixup PROGBITS ffffffff82b57af0 01d57af0
0000000000003c60 0000000000000000 A 0 0 16
[ 4] .tracedata PROGBITS ffffffff82b5b750 01d5b750
0000000000000078 0000000000000000 A 0 0 1
[ 5] __ksymtab PROGBITS ffffffff82b5b7c8 01d5b7c8
0000000000025fec 0000000000000000 A 0 0 4
[ 6] __kflagstab PROGBITS ffffffff82b817b4 01d817b4
00000000000032a9 0000000000000000 A 0 0 1
[ 7] __ksymtab_strings PROGBITS ffffffff82b84a5d 01d84a5d
00000000000412a9 0000000000000001 AMS 0 0 1
[ 8] __init_rodata PROGBITS ffffffff82bc5d20 01dc5d20
0000000000000030 0000000000000000 A 0 0 32
[ 9] __param PROGBITS ffffffff82bc5d50 01dc5d50
00000000000056e0 0000000000000000 A 0 0 8
[10] __modver PROGBITS ffffffff82bcb430 01dcb430
00000000000003f0 0000000000000000 A 0 0 8
[11] __ex_table PROGBITS ffffffff82bcb820 01dcb820
00000000000046b0 000000000000000c AM 0 0 4
[12] .notes NOTE ffffffff82bcfed0 01dcfed0
0000000000000054 0000000000000000 A 0 0 4
[13] .data PROGBITS ffffffff82c00000 01e00000
00000000002edf80 0000000000000000 WAX 0 0 8192
[14] __bug_table PROGBITS ffffffff82eedf80 020edf80
000000000002f4e0 0000000000000000 WA 0 0 1
[15] .orc_header PROGBITS ffffffff82f1d460 0211d460
0000000000000014 0000000000000000 A 0 0 4
[16] .orc_unwind_ip PROGBITS ffffffff82f1d474 0211d474
0000000000233238 0000000000000000 A 0 0 1
[17] .orc_unwind PROGBITS ffffffff831506ac 023506ac
000000000034cb54 0000000000000000 A 0 0 1
[18] .orc_lookup NOBITS ffffffff8349d200 0269d200
000000000004a95c 0000000000000000 WA 0 0 1
[19] .init.text PROGBITS ffffffff834e8000 026e8000
000000000008e59f 0000000000000000 AX 0 0 16
[20] .altinstr_aux PROGBITS ffffffff8357659f 0277659f
0000000000003a61 0000000000000000 AX 0 0 1
[21] .init.data PROGBITS ffffffff8357a000 0277a000
00000000000b75b0 0000000000000000 WA 0 0 8192
[22] .x86_cpu_dev.init PROGBITS ffffffff836315b0 028315b0
0000000000000028 0000000000000000 A 0 0 8
[23] .retpoline_sites PROGBITS ffffffff836315d8 028315d8
0000000000011084 0000000000000000 A 0 0 1
[24] .return_sites PROGBITS ffffffff83642660 02842660
0000000000048f60 0000000000000000 A 0 0 1
[25] .call_sites PROGBITS ffffffff8368b5c0 0288b5c0
00000000000fb5b4 0000000000000000 A 0 0 1
[26] .ibt_endbr_seal PROGBITS ffffffff83786b78 02986b78
000000000000f160 0000000000000000 A 0 0 1
[27] .altinstructions PROGBITS ffffffff83795cd8 02995cd8
0000000000009fe8 000000000000000e AM 0 0 1
[28] .altinstr_re[...] PROGBITS ffffffff8379fcc0 0299fcc0
0000000000002720 0000000000000000 AX 0 0 1
[29] .apicdrivers PROGBITS ffffffff837a23e0 029a23e0
0000000000000018 0000000000000000 WA 0 0 8
[30] .exit.text PROGBITS ffffffff837a2400 029a2400
0000000000003b8b 0000000000000000 AX 0 0 16
[31] .data..percpu PROGBITS ffffffff837a6000 029a6000
000000000002ae58 0000000000000000 WA 0 0 4096
[32] runtime_shif[...] PROGBITS ffffffff837d0e58 029d0e58
0000000000000014 0000000000000000 A 0 0 1
[33] runtime_ptr_[...] PROGBITS ffffffff837d0e70 029d0e70
0000000000000014 0000000000000000 A 0 0 1
[34] runtime_ptr_[...] PROGBITS ffffffff837d0e88 029d0e88
0000000000000014 0000000000000000 A 0 0 1
[35] runtime_ptr_[...] PROGBITS ffffffff837d0ea0 029d0ea0
0000000000000014 0000000000000000 A 0 0 1
[36] runtime_ptr_[...] PROGBITS ffffffff837d0eb8 029d0eb8
0000000000000010 0000000000000000 A 0 0 1
[37] runtime_ptr_[...] PROGBITS ffffffff837d0ec8 029d0ec8
000000000000000c 0000000000000000 A 0 0 1
[38] runtime_ptr_[...] PROGBITS ffffffff837d0ed8 029d0ed8
0000000000000274 0000000000000000 A 0 0 1
[39] .smp_locks PROGBITS ffffffff837d2000 029d2000
000000000000e000 0000000000000000 A 0 0 4
[40] .data_nosave PROGBITS ffffffff837e0000 029e0000
0000000000001000 0000000000000000 WA 0 0 4
[41] .bss NOBITS ffffffff837e1000 029e1000
0000000000095000 0000000000000000 WA 0 0 4096
[42] .brk NOBITS ffffffff83876000 029e1000
0000000000030000 0000000000000000 WA 0 0 1
[43] .comment PROGBITS 0000000000000000 029e1000
0000000000000027 0000000000000001 MS 0 0 1
[44] .symtab SYMTAB 0000000000000000 029e1028
0000000000550530 0000000000000018 45 157665 8
[45] .strtab STRTAB 0000000000000000 02f31558
000000000042784a 0000000000000000 0 0 1
[46] .shstrtab STRTAB 0000000000000000 03358da2
0000000000000273 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
l (large), p (processor specific)
File: ../vmlinux-before
There are 47 section headers, starting at offset 0x33587e8:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS ffffffff81000000 00200000
00000000012a7770 0000000000000000 AX 0 0 4096
[ 2] .rodata PROGBITS ffffffff82400000 01600000
0000000000760c46 0000000000000000 WA 0 0 4096
[ 3] .pci_fixup PROGBITS ffffffff82b60c50 01d60c50
0000000000003c60 0000000000000000 A 0 0 16
[ 4] .tracedata PROGBITS ffffffff82b648b0 01d648b0
0000000000000078 0000000000000000 A 0 0 1
[ 5] __ksymtab PROGBITS ffffffff82b64928 01d64928
0000000000026028 0000000000000000 A 0 0 4
[ 6] __kflagstab PROGBITS ffffffff82b8a950 01d8a950
00000000000032ae 0000000000000000 A 0 0 1
[ 7] __ksymtab_strings PROGBITS ffffffff82b8dbfe 01d8dbfe
00000000000412e0 0000000000000001 AMS 0 0 1
[ 8] __init_rodata PROGBITS ffffffff82bceee0 01dceee0
0000000000000030 0000000000000000 A 0 0 32
[ 9] __param PROGBITS ffffffff82bcef10 01dcef10
00000000000056e0 0000000000000000 A 0 0 8
[10] __modver PROGBITS ffffffff82bd45f0 01dd45f0
00000000000003f0 0000000000000000 A 0 0 8
[11] __ex_table PROGBITS ffffffff82bd49e0 01dd49e0
00000000000046b0 000000000000000c AM 0 0 4
[12] .notes NOTE ffffffff82bd9090 01dd9090
0000000000000054 0000000000000000 A 0 0 4
[13] .data PROGBITS ffffffff82c00000 01e00000
00000000002edf80 0000000000000000 WAX 0 0 8192
[14] __bug_table PROGBITS ffffffff82eedf80 020edf80
000000000002f470 0000000000000000 WA 0 0 1
[15] .orc_header PROGBITS ffffffff82f1d3f0 0211d3f0
0000000000000014 0000000000000000 A 0 0 4
[16] .orc_unwind_ip PROGBITS ffffffff82f1d404 0211d404
00000000002339d4 0000000000000000 A 0 0 1
[17] .orc_unwind PROGBITS ffffffff83150dd8 02350dd8
000000000034d6be 0000000000000000 A 0 0 1
[18] .orc_lookup NOBITS ffffffff8349e498 0269e496
000000000004a9e4 0000000000000000 WA 0 0 1
[19] .init.text PROGBITS ffffffff834e9000 026e9000
000000000008e53f 0000000000000000 AX 0 0 16
[20] .altinstr_aux PROGBITS ffffffff8357753f 0277753f
0000000000003ac1 0000000000000000 AX 0 0 1
[21] .init.data PROGBITS ffffffff8357c000 0277c000
00000000000b75b0 0000000000000000 WA 0 0 8192
[22] .x86_cpu_dev.init PROGBITS ffffffff836335b0 028335b0
0000000000000028 0000000000000000 A 0 0 8
[23] .retpoline_sites PROGBITS ffffffff836335d8 028335d8
0000000000011064 0000000000000000 A 0 0 1
[24] .return_sites PROGBITS ffffffff83644640 02844640
0000000000048f28 0000000000000000 A 0 0 1
[25] .call_sites PROGBITS ffffffff8368d568 0288d568
00000000000f863c 0000000000000000 A 0 0 1
[26] .ibt_endbr_seal PROGBITS ffffffff83785ba8 02985ba8
000000000000f15c 0000000000000000 A 0 0 1
[27] .altinstructions PROGBITS ffffffff83794d08 02994d08
0000000000009fe8 000000000000000e AM 0 0 1
[28] .altinstr_re[...] PROGBITS ffffffff8379ecf0 0299ecf0
0000000000002720 0000000000000000 AX 0 0 1
[29] .apicdrivers PROGBITS ffffffff837a1410 029a1410
0000000000000018 0000000000000000 WA 0 0 8
[30] .exit.text PROGBITS ffffffff837a1430 029a1430
0000000000003b8b 0000000000000000 AX 0 0 16
[31] .data..percpu PROGBITS ffffffff837a5000 029a5000
000000000002ae58 0000000000000000 WA 0 0 4096
[32] runtime_shif[...] PROGBITS ffffffff837cfe58 029cfe58
0000000000000014 0000000000000000 A 0 0 1
[33] runtime_ptr_[...] PROGBITS ffffffff837cfe70 029cfe70
0000000000000014 0000000000000000 A 0 0 1
[34] runtime_ptr_[...] PROGBITS ffffffff837cfe88 029cfe88
0000000000000014 0000000000000000 A 0 0 1
[35] runtime_ptr_[...] PROGBITS ffffffff837cfea0 029cfea0
0000000000000014 0000000000000000 A 0 0 1
[36] runtime_ptr_[...] PROGBITS ffffffff837cfeb8 029cfeb8
0000000000000010 0000000000000000 A 0 0 1
[37] runtime_ptr_[...] PROGBITS ffffffff837cfec8 029cfec8
000000000000000c 0000000000000000 A 0 0 1
[38] runtime_ptr_[...] PROGBITS ffffffff837cfed8 029cfed8
0000000000000274 0000000000000000 A 0 0 1
[39] .smp_locks PROGBITS ffffffff837d1000 029d1000
000000000000e000 0000000000000000 A 0 0 4
[40] .data_nosave PROGBITS ffffffff837df000 029df000
0000000000001000 0000000000000000 WA 0 0 4
[41] .bss NOBITS ffffffff837e0000 029e0000
0000000000095000 0000000000000000 WA 0 0 4096
[42] .brk NOBITS ffffffff83875000 029e0000
0000000000030000 0000000000000000 WA 0 0 1
[43] .comment PROGBITS 0000000000000000 029e0000
0000000000000027 0000000000000001 MS 0 0 1
[44] .symtab SYMTAB 0000000000000000 029e0028
0000000000550830 0000000000000018 45 157685 8
[45] .strtab STRTAB 0000000000000000 02f30858
0000000000427d16 0000000000000000 0 0 1
[46] .shstrtab STRTAB 0000000000000000 0335856e
0000000000000273 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
l (large), p (processor specific)
> Btw, I ran it on powerpc, builds and boots.
Thanks for testing!
> Bloat-o-meter says,
> Total: Before=32286154, After=32267870, chg -0.06%
Yep, similar on x86_64, v7.21-r1, defconfig:
Total: Before=24064357, After=24052508, chg -0.05%
Similar on arm64 too, but I don't have the numbers to hand.
[...]
> 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.
Sure.
For consistency, I think it makes sense to keep implementations of
preempt_model_none() and preempt_model_voluntary() that just check
CONFIG_PREEMPT_{NONE,VOLUNTARY}, as in your diff below, even if we only
use preempt_model_none() in one place today.
I'll add a patch to the end of the series.
Thanks!
Mark.
>
> ---
>
> 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 [flat|nested] 17+ messages in thread
* Re: [PATCH 4/5] sched: dynamic: Simplify irqentry_exit_cond_resched()
2026-07-17 11:05 ` Mark Rutland
@ 2026-07-17 13:49 ` Shrikanth Hegde
2026-07-17 13:57 ` Mark Rutland
0 siblings, 1 reply; 17+ messages in thread
From: Shrikanth Hegde @ 2026-07-17 13:49 UTC (permalink / raw)
To: Mark Rutland, Christophe Leroy (CS GROUP)
Cc: linux-kernel, frederic, jstultz, juri.lelli, mingo, peterz, tglx,
vincent.guittot, vschneid
Hi Mark,
On 7/17/26 4:35 PM, Mark Rutland wrote:
> On Mon, Jul 06, 2026 at 10:12:29AM +0530, Shrikanth Hegde wrote:
>> +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/
>
> Thanks for the heads-up!
>
> Sorry, I'd skipped Ccing all the arch folk as I hadn't expected anyone
> was likely to be doing similar in the arch code right now. I'll make
> sure you're both Cc'd for any subsequent versions.
>
> It looks like the only difference for powerpc is that I leave
> need_irq_preemption() lying around. Christophe, if you're happy with
> this series, I could pick a patch from you to remove that (e.g. take
> your patch and apply it to the end of this series, reduced to removing
> need_irq_preemption()).
>
> Any preference?
I will go by Christophe preference.
But i see it is in powerpc fixes branch and part of pull request.
https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?h=fixes
So, you might have to rebase on top of it.
>
> [...]
>
>> Change per se, looks good to me.
>>
>> Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
>
> Thanks!
>
> Mark.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 4/5] sched: dynamic: Simplify irqentry_exit_cond_resched()
2026-07-17 13:49 ` Shrikanth Hegde
@ 2026-07-17 13:57 ` Mark Rutland
0 siblings, 0 replies; 17+ messages in thread
From: Mark Rutland @ 2026-07-17 13:57 UTC (permalink / raw)
To: Shrikanth Hegde
Cc: Christophe Leroy (CS GROUP),
linux-kernel, frederic, jstultz, juri.lelli, mingo, peterz, tglx,
vincent.guittot, vschneid
On Fri, Jul 17, 2026 at 07:19:03PM +0530, Shrikanth Hegde wrote:
> On 7/17/26 4:35 PM, Mark Rutland wrote:
> > On Mon, Jul 06, 2026 at 10:12:29AM +0530, Shrikanth Hegde wrote:
> > > 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/
> >
> > Thanks for the heads-up!
> >
> > Sorry, I'd skipped Ccing all the arch folk as I hadn't expected anyone
> > was likely to be doing similar in the arch code right now. I'll make
> > sure you're both Cc'd for any subsequent versions.
> >
> > It looks like the only difference for powerpc is that I leave
> > need_irq_preemption() lying around. Christophe, if you're happy with
> > this series, I could pick a patch from you to remove that (e.g. take
> > your patch and apply it to the end of this series, reduced to removing
> > need_irq_preemption()).
> >
> > Any preference?
>
> I will go by Christophe preference.
>
> But i see it is in powerpc fixes branch and part of pull request.
> https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?h=fixes
>
> So, you might have to rebase on top of it.
Sorry, I didn't spot that. Thanks for the pointer!
I'll wait for that to land and rebase atop, then.
Mark.
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2026-07-17 13:57 UTC | newest]
Thread overview: 17+ 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-17 10:59 ` Mark Rutland
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-17 11:03 ` Mark Rutland
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-17 11:05 ` Mark Rutland
2026-07-17 13:49 ` Shrikanth Hegde
2026-07-17 13:57 ` Mark Rutland
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
2026-07-17 11:35 ` Mark Rutland
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox