diff options
Diffstat (limited to 'debian/patches-rt/0243-arch-arm64-Add-lazy-preempt-support.patch')
-rw-r--r-- | debian/patches-rt/0243-arch-arm64-Add-lazy-preempt-support.patch | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/debian/patches-rt/0243-arch-arm64-Add-lazy-preempt-support.patch b/debian/patches-rt/0243-arch-arm64-Add-lazy-preempt-support.patch new file mode 100644 index 000000000..385d63933 --- /dev/null +++ b/debian/patches-rt/0243-arch-arm64-Add-lazy-preempt-support.patch @@ -0,0 +1,129 @@ +From: Anders Roxell <anders.roxell@linaro.org> +Date: Thu, 14 May 2015 17:52:17 +0200 +Subject: [PATCH 243/342] arch/arm64: Add lazy preempt support +Origin: https://git.kernel.org/cgit/linux/kernel/git/rt/linux-stable-rt.git/commit?id=d78ec4a3e861e9c07b84fa323cfd72f647808a23 + +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 + + arch/arm64/include/asm/thread_info.h | 6 +++++- + arch/arm64/kernel/asm-offsets.c | 1 + + arch/arm64/kernel/entry.S | 12 +++++++++--- + arch/arm64/kernel/signal.c | 2 +- + 5 files changed, 17 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig +index a101f5d2fbed..84f53dc1a75b 100644 +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -141,6 +141,7 @@ config ARM64 + select HAVE_PERF_EVENTS + select HAVE_PERF_REGS + select HAVE_PERF_USER_STACK_DUMP ++ select HAVE_PREEMPT_LAZY + select HAVE_REGS_AND_STACK_ACCESS_API + select HAVE_RCU_TABLE_FREE + select HAVE_RSEQ +diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h +index 69ac5262cccd..39e921817f28 100644 +--- a/arch/arm64/include/asm/thread_info.h ++++ b/arch/arm64/include/asm/thread_info.h +@@ -43,6 +43,7 @@ struct thread_info { + u64 ttbr0; /* saved TTBR0_EL1 */ + #endif + int preempt_count; /* 0 => preemptable, <0 => bug */ ++ int preempt_lazy_count; /* 0 => preemptable, <0 => bug */ + }; + + #define thread_saved_pc(tsk) \ +@@ -76,6 +77,7 @@ void arch_release_task_struct(struct task_struct *tsk); + #define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not current's */ + #define TIF_UPROBE 4 /* uprobe breakpoint or singlestep */ + #define TIF_FSCHECK 5 /* Check FS is USER_DS on return */ ++#define TIF_NEED_RESCHED_LAZY 6 + #define TIF_NOHZ 7 + #define TIF_SYSCALL_TRACE 8 + #define TIF_SYSCALL_AUDIT 9 +@@ -94,6 +96,7 @@ void arch_release_task_struct(struct task_struct *tsk); + #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) +@@ -107,8 +110,9 @@ void arch_release_task_struct(struct task_struct *tsk); + + #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ + _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \ +- _TIF_UPROBE | _TIF_FSCHECK) ++ _TIF_UPROBE | _TIF_FSCHECK | _TIF_NEED_RESCHED_LAZY) + ++#define _TIF_NEED_RESCHED_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY) + #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ + _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \ + _TIF_NOHZ) +diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c +index 92fba851ce53..844c71bc865b 100644 +--- a/arch/arm64/kernel/asm-offsets.c ++++ b/arch/arm64/kernel/asm-offsets.c +@@ -41,6 +41,7 @@ int main(void) + BLANK(); + 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)); +diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S +index 85433a84783b..201f412b556e 100644 +--- a/arch/arm64/kernel/entry.S ++++ b/arch/arm64/kernel/entry.S +@@ -634,11 +634,16 @@ ENDPROC(el1_sync) + + #ifdef CONFIG_PREEMPT + ldr w24, [tsk, #TSK_TI_PREEMPT] // get preempt count +- cbnz w24, 1f // preempt count != 0 ++ cbnz w24, 2f // preempt count != 0 + ldr x0, [tsk, #TSK_TI_FLAGS] // get flags +- tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling? +- bl el1_preempt ++ tbnz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling? ++ ++ ldr w24, [tsk, #TSK_TI_PREEMPT_LAZY] // get preempt lazy count ++ 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 +@@ -652,6 +657,7 @@ ENDPROC(el1_irq) + 1: bl preempt_schedule_irq // irq en/disable is done inside + ldr x0, [tsk, #TSK_TI_FLAGS] // get new tasks TI_FLAGS + tbnz x0, #TIF_NEED_RESCHED, 1b // needs rescheduling? ++ tbnz x0, #TIF_NEED_RESCHED_LAZY, 1b // needs rescheduling? + ret x24 + #endif + +diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c +index ca565853dea6..3f321daa7702 100644 +--- a/arch/arm64/kernel/signal.c ++++ b/arch/arm64/kernel/signal.c +@@ -919,7 +919,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, + /* Check valid user FS if needed */ + addr_limit_user_check(); + +- if (thread_flags & _TIF_NEED_RESCHED) { ++ if (thread_flags & _TIF_NEED_RESCHED_MASK) { + /* Unmask Debug and SError for the next task */ + local_daif_restore(DAIF_PROCCTX_NOIRQ); + |