summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0243-arch-arm64-Add-lazy-preempt-support.patch
diff options
context:
space:
mode:
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.patch129
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);
+