From 8fcd7e2ad0689bf9147382bd72255cd31e406bbd Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 1 Nov 2012 10:14:11 +0100 Subject: powerpc-preempt-lazy-support.patch Signed-off-by: Thomas Gleixner --- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/thread_info.h | 12 ++++++--- arch/powerpc/kernel/asm-offsets.c | 1 + arch/powerpc/kernel/entry_32.S | 17 ++++++++---- arch/powerpc/kernel/entry_64.S | 48 ++++++++++++++++++++-------------- 5 files changed, 51 insertions(+), 28 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 4b930b361ee0..95e5d5c0e6ce 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -133,6 +133,7 @@ config PPC select GENERIC_CLOCKEVENTS select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER + select HAVE_PREEMPT_LAZY select HAVE_MOD_ARCH_SPECIFIC select MODULES_USE_ELF_RELA select CLONE_BACKWARDS diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index ba7b1973866e..f50711f4c7cd 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h @@ -43,6 +43,8 @@ struct thread_info { int cpu; /* cpu we're on */ int preempt_count; /* 0 => preemptable, <0 => BUG */ + int preempt_lazy_count; /* 0 => preemptable, + <0 => BUG */ struct restart_block restart_block; unsigned long local_flags; /* private flags for thread */ @@ -90,8 +92,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ #define TIF_SIGPENDING 1 /* signal pending */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ -#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling - TIF_NEED_RESCHED */ +#define TIF_NEED_RESCHED_LAZY 3 /* lazy rescheduling necessary */ #define TIF_32BIT 4 /* 32 bit binary */ #define TIF_PERFMON_WORK 5 /* work for pfm_handle_work() */ #define TIF_PERFMON_CTXSW 6 /* perfmon needs ctxsw calls */ @@ -107,6 +108,8 @@ static inline struct thread_info *current_thread_info(void) #define TIF_EMULATE_STACK_STORE 16 /* Is an instruction emulation for stack store? */ #define TIF_MEMDIE 17 /* is terminating due to OOM killer */ +#define TIF_POLLING_NRFLAG 18 /* true if poll_idle() is polling + TIF_NEED_RESCHED */ /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1< @@ -239,12 +239,12 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) RFI b . /* prevent speculative execution */ -syscall_error: +syscall_error: oris r5,r5,0x1000 /* Set SO bit in CR */ neg r3,r3 std r5,_CCR(r1) b .Lsyscall_error_cont - + /* Traced system call support */ syscall_dotrace: bl .save_nvgprs @@ -270,7 +270,7 @@ syscall_dotrace: syscall_enosys: li r3,-ENOSYS b syscall_exit - + syscall_exit_work: #ifdef CONFIG_PPC_BOOK3S mtmsrd r10,1 /* Restore RI */ @@ -333,7 +333,7 @@ _GLOBAL(save_nvgprs) std r0,_TRAP(r1) blr - + /* * The sigsuspend and rt_sigsuspend system calls can call do_signal * and thus put the process into the stopped state where we might @@ -406,7 +406,7 @@ DSCR_DEFAULT: * the fork code also. * * The code which creates the new task context is in 'copy_thread' - * in arch/powerpc/kernel/process.c + * in arch/powerpc/kernel/process.c */ .align 7 _GLOBAL(_switch) @@ -653,7 +653,7 @@ _GLOBAL(ret_from_except_lite) andi. r0,r4,_TIF_USER_WORK_MASK beq restore - andi. r0,r4,_TIF_NEED_RESCHED + andi. r0,r4,_TIF_NEED_RESCHED_MASK beq 1f bl .restore_interrupts SCHEDULE_USER @@ -703,10 +703,18 @@ resume_kernel: #ifdef CONFIG_PREEMPT /* Check if we need to preempt */ + lwz r8,TI_PREEMPT(r9) + cmpwi 0,r8,0 /* if non-zero, just restore regs and return */ + bne restore andi. r0,r4,_TIF_NEED_RESCHED + bne+ check_count + + andi. r0,r4,_TIF_NEED_RESCHED_LAZY beq+ restore + lwz r8,TI_PREEMPT_LAZY(r9) + /* Check that preempt_count() == 0 and interrupts are enabled */ - lwz r8,TI_PREEMPT(r9) +check_count: cmpwi cr1,r8,0 ld r0,SOFTE(r1) cmpdi r0,0 @@ -723,7 +731,7 @@ resume_kernel: /* Re-test flags and eventually loop */ CURRENT_THREAD_INFO(r9, r1) ld r4,TI_FLAGS(r9) - andi. r0,r4,_TIF_NEED_RESCHED + andi. r0,r4,_TIF_NEED_RESCHED_MASK bne 1b /* @@ -890,7 +898,7 @@ restore_check_irq_replay: bl .__check_irq_replay cmpwi cr0,r3,0 beq restore_no_replay - + /* * We need to re-emit an interrupt. We do so by re-using our * existing exception frame. We first change the trap value, @@ -932,7 +940,7 @@ restore_check_irq_replay: b .ret_from_except #endif /* CONFIG_PPC_DOORBELL */ 1: b .ret_from_except /* What else to do here ? */ - + unrecov_restore: addi r3,r1,STACK_FRAME_OVERHEAD bl .unrecoverable_exception @@ -944,7 +952,7 @@ unrecov_restore: * called with the MMU off. * * In addition, we need to be in 32b mode, at least for now. - * + * * Note: r3 is an input parameter to rtas, so don't trash it... */ _GLOBAL(enter_rtas) @@ -978,7 +986,7 @@ _GLOBAL(enter_rtas) li r0,0 mtcr r0 -#ifdef CONFIG_BUG +#ifdef CONFIG_BUG /* There is no way it is acceptable to get here with interrupts enabled, * check it with the asm equivalent of WARN_ON */ @@ -986,7 +994,7 @@ _GLOBAL(enter_rtas) 1: tdnei r0,0 EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,BUGFLAG_WARNING #endif - + /* Hard-disable interrupts */ mfmsr r6 rldicl r7,r6,48,1 @@ -1000,7 +1008,7 @@ _GLOBAL(enter_rtas) std r1,PACAR1(r13) std r6,PACASAVEDMSR(r13) - /* Setup our real return addr */ + /* Setup our real return addr */ LOAD_REG_ADDR(r4,.rtas_return_loc) clrldi r4,r4,2 /* convert to realmode address */ mtlr r4 @@ -1008,7 +1016,7 @@ _GLOBAL(enter_rtas) li r0,0 ori r0,r0,MSR_EE|MSR_SE|MSR_BE|MSR_RI andc r0,r6,r0 - + li r9,1 rldicr r9,r9,MSR_SF_LG,(63-MSR_SF_LG) ori r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP|MSR_RI @@ -1019,7 +1027,7 @@ _GLOBAL(enter_rtas) LOAD_REG_ADDR(r4, rtas) ld r5,RTASENTRY(r4) /* get the rtas->entry value */ ld r4,RTASBASE(r4) /* get the rtas->base value */ - + mtspr SPRN_SRR0,r5 mtspr SPRN_SRR1,r6 rfid @@ -1037,9 +1045,9 @@ _STATIC(rtas_return_loc) mfmsr r6 li r0,MSR_RI andc r6,r6,r0 - sync + sync mtmsrd r6 - + ld r1,PACAR1(r4) /* Restore our SP */ ld r4,PACASAVEDMSR(r4) /* Restore our MSR */ @@ -1137,7 +1145,7 @@ _GLOBAL(enter_prom) REST_10GPRS(22, r1) ld r4,_CCR(r1) mtcr r4 - + addi r1,r1,PROM_FRAME_SIZE ld r0,16(r1) mtlr r0 -- cgit v1.2.3