Skip to content

Commit a8508f3

Browse files
roxellTiejunChina
authored andcommitted
arch/arm64: Add lazy preempt support
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>
1 parent b8bd96e commit a8508f3

File tree

5 files changed

+17
-5
lines changed

5 files changed

+17
-5
lines changed

arch/arm64/Kconfig

+1
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ config ARM64
140140
select HAVE_PERF_EVENTS
141141
select HAVE_PERF_REGS
142142
select HAVE_PERF_USER_STACK_DUMP
143+
select HAVE_PREEMPT_LAZY
143144
select HAVE_REGS_AND_STACK_ACCESS_API
144145
select HAVE_RCU_TABLE_FREE
145146
select HAVE_RSEQ

arch/arm64/include/asm/thread_info.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ struct thread_info {
4343
u64 ttbr0; /* saved TTBR0_EL1 */
4444
#endif
4545
int preempt_count; /* 0 => preemptable, <0 => bug */
46+
int preempt_lazy_count; /* 0 => preemptable, <0 => bug */
4647
};
4748

4849
#define thread_saved_pc(tsk) \
@@ -76,6 +77,7 @@ void arch_release_task_struct(struct task_struct *tsk);
7677
#define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not current's */
7778
#define TIF_UPROBE 4 /* uprobe breakpoint or singlestep */
7879
#define TIF_FSCHECK 5 /* Check FS is USER_DS on return */
80+
#define TIF_NEED_RESCHED_LAZY 6
7981
#define TIF_NOHZ 7
8082
#define TIF_SYSCALL_TRACE 8
8183
#define TIF_SYSCALL_AUDIT 9
@@ -94,6 +96,7 @@ void arch_release_task_struct(struct task_struct *tsk);
9496
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
9597
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
9698
#define _TIF_FOREIGN_FPSTATE (1 << TIF_FOREIGN_FPSTATE)
99+
#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY)
97100
#define _TIF_NOHZ (1 << TIF_NOHZ)
98101
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
99102
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
@@ -106,8 +109,9 @@ void arch_release_task_struct(struct task_struct *tsk);
106109

107110
#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
108111
_TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \
109-
_TIF_UPROBE | _TIF_FSCHECK)
112+
_TIF_UPROBE | _TIF_FSCHECK | _TIF_NEED_RESCHED_LAZY)
110113

114+
#define _TIF_NEED_RESCHED_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY)
111115
#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
112116
_TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
113117
_TIF_NOHZ)

arch/arm64/kernel/asm-offsets.c

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ int main(void)
4141
BLANK();
4242
DEFINE(TSK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags));
4343
DEFINE(TSK_TI_PREEMPT, offsetof(struct task_struct, thread_info.preempt_count));
44+
DEFINE(TSK_TI_PREEMPT_LAZY, offsetof(struct task_struct, thread_info.preempt_lazy_count));
4445
DEFINE(TSK_TI_ADDR_LIMIT, offsetof(struct task_struct, thread_info.addr_limit));
4546
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
4647
DEFINE(TSK_TI_TTBR0, offsetof(struct task_struct, thread_info.ttbr0));

arch/arm64/kernel/entry.S

+9-3
Original file line numberDiff line numberDiff line change
@@ -623,11 +623,16 @@ el1_irq:
623623

624624
#ifdef CONFIG_PREEMPT
625625
ldr w24, [tsk, #TSK_TI_PREEMPT] // get preempt count
626-
cbnz w24, 1f // preempt count != 0
626+
cbnz w24, 2f // preempt count != 0
627627
ldr x0, [tsk, #TSK_TI_FLAGS] // get flags
628-
tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling?
629-
bl el1_preempt
628+
tbnz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling?
629+
630+
ldr w24, [tsk, #TSK_TI_PREEMPT_LAZY] // get preempt lazy count
631+
cbnz w24, 2f // preempt lazy count != 0
632+
tbz x0, #TIF_NEED_RESCHED_LAZY, 2f // needs rescheduling?
630633
1:
634+
bl el1_preempt
635+
2:
631636
#endif
632637
#ifdef CONFIG_TRACE_IRQFLAGS
633638
bl trace_hardirqs_on
@@ -641,6 +646,7 @@ el1_preempt:
641646
1: bl preempt_schedule_irq // irq en/disable is done inside
642647
ldr x0, [tsk, #TSK_TI_FLAGS] // get new tasks TI_FLAGS
643648
tbnz x0, #TIF_NEED_RESCHED, 1b // needs rescheduling?
649+
tbnz x0, #TIF_NEED_RESCHED_LAZY, 1b // needs rescheduling?
644650
ret x24
645651
#endif
646652

arch/arm64/kernel/signal.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -926,7 +926,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
926926
/* Check valid user FS if needed */
927927
addr_limit_user_check();
928928

929-
if (thread_flags & _TIF_NEED_RESCHED) {
929+
if (thread_flags & _TIF_NEED_RESCHED_MASK) {
930930
/* Unmask Debug and SError for the next task */
931931
local_daif_restore(DAIF_PROCCTX_NOIRQ);
932932

0 commit comments

Comments
 (0)