diff options
| -rw-r--r-- | arch/arm64/Kconfig | 1 | ||||
| -rw-r--r-- | arch/arm64/include/asm/preempt.h | 19 | ||||
| -rw-r--r-- | arch/arm64/kernel/entry-common.c | 10 | 
3 files changed, 27 insertions, 3 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 6978140edfa4..7d0f0cdd5e0e 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -192,6 +192,7 @@ config ARM64  	select HAVE_PERF_EVENTS  	select HAVE_PERF_REGS  	select HAVE_PERF_USER_STACK_DUMP +	select HAVE_PREEMPT_DYNAMIC_KEY  	select HAVE_REGS_AND_STACK_ACCESS_API  	select HAVE_POSIX_CPU_TIMERS_TASK_WORK  	select HAVE_FUNCTION_ARG_ACCESS_API diff --git a/arch/arm64/include/asm/preempt.h b/arch/arm64/include/asm/preempt.h index e83f0982b99c..0159b625cc7f 100644 --- a/arch/arm64/include/asm/preempt.h +++ b/arch/arm64/include/asm/preempt.h @@ -2,6 +2,7 @@  #ifndef __ASM_PREEMPT_H  #define __ASM_PREEMPT_H +#include <linux/jump_label.h>  #include <linux/thread_info.h>  #define PREEMPT_NEED_RESCHED	BIT(32) @@ -80,10 +81,24 @@ static inline bool should_resched(int preempt_offset)  }  #ifdef CONFIG_PREEMPTION +  void preempt_schedule(void); -#define __preempt_schedule() preempt_schedule()  void preempt_schedule_notrace(void); -#define __preempt_schedule_notrace() preempt_schedule_notrace() + +#ifdef CONFIG_PREEMPT_DYNAMIC + +DECLARE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched); +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/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c index 2c639b6b676d..675352ec1368 100644 --- a/arch/arm64/kernel/entry-common.c +++ b/arch/arm64/kernel/entry-common.c @@ -220,9 +220,17 @@ static void noinstr arm64_exit_el1_dbg(struct pt_regs *regs)  		lockdep_hardirqs_on(CALLER_ADDR0);  } +#ifdef CONFIG_PREEMPT_DYNAMIC +DEFINE_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 +  static void __sched arm64_preempt_schedule_irq(void)  { -	if (!IS_ENABLED(CONFIG_PREEMPTION)) +	if (!need_irq_preemption())  		return;  	/*  | 
