2016-05-17 22:40:10 +00:00
|
|
|
From: Anders Roxell <anders.roxell@linaro.org>
|
|
|
|
Date: Thu, 14 May 2015 17:52:17 +0200
|
|
|
|
Subject: arch/arm64: Add lazy preempt support
|
2018-01-28 14:46:47 +00:00
|
|
|
Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.14/older/patches-4.14.15-rt11.tar.xz
|
2016-05-17 22:40:10 +00:00
|
|
|
|
|
|
|
arm64 is missing support for PREEMPT_RT. The main feature which is
|
|
|
|
lacking is support for lazy preemption. The arch-specific entry code,
|
|
|
|
thread information structure definitions, and associated data tables
|
|
|
|
have to be extended to provide this support. Then the Kconfig file has
|
|
|
|
to be extended to indicate the support is available, and also to
|
|
|
|
indicate that support for full RT preemption is now available.
|
|
|
|
|
|
|
|
Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
|
|
|
|
---
|
|
|
|
arch/arm64/Kconfig | 1 +
|
2017-11-20 14:16:49 +00:00
|
|
|
arch/arm64/include/asm/thread_info.h | 6 +++++-
|
2016-05-17 22:40:10 +00:00
|
|
|
arch/arm64/kernel/asm-offsets.c | 1 +
|
2016-12-23 20:25:24 +00:00
|
|
|
arch/arm64/kernel/entry.S | 12 +++++++++---
|
|
|
|
arch/arm64/kernel/signal.c | 2 +-
|
2017-11-20 14:16:49 +00:00
|
|
|
5 files changed, 17 insertions(+), 5 deletions(-)
|
2016-05-17 22:40:10 +00:00
|
|
|
|
|
|
|
--- a/arch/arm64/Kconfig
|
|
|
|
+++ b/arch/arm64/Kconfig
|
2017-11-20 14:16:49 +00:00
|
|
|
@@ -103,6 +103,7 @@ config ARM64
|
2016-10-11 18:58:48 +00:00
|
|
|
select HAVE_PERF_EVENTS
|
2016-05-17 22:40:10 +00:00
|
|
|
select HAVE_PERF_REGS
|
|
|
|
select HAVE_PERF_USER_STACK_DUMP
|
|
|
|
+ select HAVE_PREEMPT_LAZY
|
2016-10-11 18:58:48 +00:00
|
|
|
select HAVE_REGS_AND_STACK_ACCESS_API
|
|
|
|
select HAVE_RCU_TABLE_FREE
|
2016-05-17 22:40:10 +00:00
|
|
|
select HAVE_SYSCALL_TRACEPOINTS
|
|
|
|
--- a/arch/arm64/include/asm/thread_info.h
|
|
|
|
+++ b/arch/arm64/include/asm/thread_info.h
|
2017-11-20 14:16:49 +00:00
|
|
|
@@ -43,6 +43,7 @@ struct thread_info {
|
2017-06-18 17:14:20 +00:00
|
|
|
u64 ttbr0; /* saved TTBR0_EL1 */
|
|
|
|
#endif
|
2016-05-17 22:40:10 +00:00
|
|
|
int preempt_count; /* 0 => preemptable, <0 => bug */
|
|
|
|
+ int preempt_lazy_count; /* 0 => preemptable, <0 => bug */
|
|
|
|
};
|
|
|
|
|
2017-06-18 17:14:20 +00:00
|
|
|
#define INIT_THREAD_INFO(tsk) \
|
2017-11-20 14:16:49 +00:00
|
|
|
@@ -82,6 +83,7 @@ void arch_setup_new_exec(void);
|
2016-05-17 22:40:10 +00:00
|
|
|
#define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not current's */
|
2017-06-18 17:14:20 +00:00
|
|
|
#define TIF_UPROBE 4 /* uprobe breakpoint or singlestep */
|
2017-11-20 14:16:49 +00:00
|
|
|
#define TIF_FSCHECK 5 /* Check FS is USER_DS on return */
|
|
|
|
+#define TIF_NEED_RESCHED_LAZY 6
|
2016-05-17 22:40:10 +00:00
|
|
|
#define TIF_NOHZ 7
|
|
|
|
#define TIF_SYSCALL_TRACE 8
|
|
|
|
#define TIF_SYSCALL_AUDIT 9
|
2017-11-20 14:16:49 +00:00
|
|
|
@@ -97,6 +99,7 @@ void arch_setup_new_exec(void);
|
2016-05-17 22:40:10 +00:00
|
|
|
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
|
|
|
|
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
|
|
|
|
#define _TIF_FOREIGN_FPSTATE (1 << TIF_FOREIGN_FPSTATE)
|
|
|
|
+#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY)
|
|
|
|
#define _TIF_NOHZ (1 << TIF_NOHZ)
|
|
|
|
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
|
|
|
|
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
|
2017-11-20 14:16:49 +00:00
|
|
|
@@ -108,8 +111,9 @@ void arch_setup_new_exec(void);
|
2016-10-11 18:58:48 +00:00
|
|
|
|
|
|
|
#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
|
2017-06-18 17:14:20 +00:00
|
|
|
_TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \
|
2017-11-20 14:16:49 +00:00
|
|
|
- _TIF_UPROBE | _TIF_FSCHECK)
|
|
|
|
+ _TIF_UPROBE | _TIF_FSCHECK | _TIF_NEED_RESCHED_LAZY)
|
|
|
|
|
2016-12-23 20:25:24 +00:00
|
|
|
+#define _TIF_NEED_RESCHED_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY)
|
2016-10-11 18:58:48 +00:00
|
|
|
#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
|
|
|
|
_TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
|
2017-06-18 17:14:20 +00:00
|
|
|
_TIF_NOHZ)
|
2016-05-17 22:40:10 +00:00
|
|
|
--- a/arch/arm64/kernel/asm-offsets.c
|
|
|
|
+++ b/arch/arm64/kernel/asm-offsets.c
|
2016-12-23 20:25:24 +00:00
|
|
|
@@ -38,6 +38,7 @@ int main(void)
|
2016-05-17 22:40:10 +00:00
|
|
|
BLANK();
|
2017-06-18 17:14:20 +00:00
|
|
|
DEFINE(TSK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags));
|
|
|
|
DEFINE(TSK_TI_PREEMPT, offsetof(struct task_struct, thread_info.preempt_count));
|
|
|
|
+ DEFINE(TSK_TI_PREEMPT_LAZY, offsetof(struct task_struct, thread_info.preempt_lazy_count));
|
|
|
|
DEFINE(TSK_TI_ADDR_LIMIT, offsetof(struct task_struct, thread_info.addr_limit));
|
|
|
|
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
|
|
|
|
DEFINE(TSK_TI_TTBR0, offsetof(struct task_struct, thread_info.ttbr0));
|
2016-05-17 22:40:10 +00:00
|
|
|
--- a/arch/arm64/kernel/entry.S
|
|
|
|
+++ b/arch/arm64/kernel/entry.S
|
2017-11-20 14:16:49 +00:00
|
|
|
@@ -570,11 +570,16 @@ ENDPROC(el1_sync)
|
2016-05-17 22:40:10 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_PREEMPT
|
2017-06-18 17:14:20 +00:00
|
|
|
ldr w24, [tsk, #TSK_TI_PREEMPT] // get preempt count
|
2016-05-17 22:40:10 +00:00
|
|
|
- cbnz w24, 1f // preempt count != 0
|
|
|
|
+ cbnz w24, 2f // preempt count != 0
|
2017-06-18 17:14:20 +00:00
|
|
|
ldr x0, [tsk, #TSK_TI_FLAGS] // get flags
|
2016-05-17 22:40:10 +00:00
|
|
|
- tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling?
|
|
|
|
- bl el1_preempt
|
|
|
|
+ tbnz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling?
|
|
|
|
+
|
2017-06-18 17:14:20 +00:00
|
|
|
+ ldr w24, [tsk, #TSK_TI_PREEMPT_LAZY] // get preempt lazy count
|
2016-05-17 22:40:10 +00:00
|
|
|
+ cbnz w24, 2f // preempt lazy count != 0
|
|
|
|
+ tbz x0, #TIF_NEED_RESCHED_LAZY, 2f // needs rescheduling?
|
|
|
|
1:
|
|
|
|
+ bl el1_preempt
|
|
|
|
+2:
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
|
|
|
bl trace_hardirqs_on
|
2017-11-20 14:16:49 +00:00
|
|
|
@@ -588,6 +593,7 @@ ENDPROC(el1_irq)
|
2016-05-17 22:40:10 +00:00
|
|
|
1: bl preempt_schedule_irq // irq en/disable is done inside
|
2017-06-18 17:14:20 +00:00
|
|
|
ldr x0, [tsk, #TSK_TI_FLAGS] // get new tasks TI_FLAGS
|
2016-05-17 22:40:10 +00:00
|
|
|
tbnz x0, #TIF_NEED_RESCHED, 1b // needs rescheduling?
|
|
|
|
+ tbnz x0, #TIF_NEED_RESCHED_LAZY, 1b // needs rescheduling?
|
|
|
|
ret x24
|
|
|
|
#endif
|
|
|
|
|
2016-12-23 20:25:24 +00:00
|
|
|
--- a/arch/arm64/kernel/signal.c
|
|
|
|
+++ b/arch/arm64/kernel/signal.c
|
2017-11-20 14:16:49 +00:00
|
|
|
@@ -755,7 +755,7 @@ asmlinkage void do_notify_resume(struct
|
|
|
|
/* Check valid user FS if needed */
|
|
|
|
addr_limit_user_check();
|
|
|
|
|
2016-12-23 20:25:24 +00:00
|
|
|
- if (thread_flags & _TIF_NEED_RESCHED) {
|
|
|
|
+ if (thread_flags & _TIF_NEED_RESCHED_MASK) {
|
|
|
|
schedule();
|
|
|
|
} else {
|
|
|
|
local_irq_enable();
|