Re: [PATCH 1/5] sched: dynamic: Make PREEMPT_DYNAMIC depend on ARCH_HAS_PREEMPT_LAZY

From: Jinjie Ruan

Date: Mon Jul 27 2026 - 08:39:16 EST




在 2026/7/3 21:33, Mark Rutland 写道:
> 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@xxxxxxx>
> Cc: Frederic Weisbecker <frederic@xxxxxxxxxx>
> Cc: Ingo Molnar <mingo@xxxxxxxxxx>
> Cc: John Stultz <jstultz@xxxxxxxxxx>
> Cc: Juri Lelli <juri.lelli@xxxxxxxxxx>
> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
> Cc: Valentin Schneider <vschneid@xxxxxxxxxx>
> Cc: Vincent Guittot <vincent.guittot@xxxxxxxxxx>
> ---
> 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;
> -

LGTM
Reviewed-by: Jinjie Ruan <ruanjinjie@xxxxxxxxxx>

> 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 */