Message ID | 1453337749-15506-7-git-send-email-cyrilbur@gmail.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
On Thu, 2016-21-01 at 00:55:46 UTC, Cyril Bur wrote: > This prepares for the decoupling of saving {fpu,altivec,vsx} registers and > marking {fpu,altivec,vsx} as being unused by a thread. > > Currently giveup_{fpu,altivec,vsx}() does both however optimisations to > task switching can be made if these two operations are decoupled. > save_all() will permit the saving of registers to thread structs and leave > threads MSR with bits enabled. > > This patch introduces no functional change. > diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c > index 0955b7c..45e37c0 100644 > --- a/arch/powerpc/kernel/process.c > +++ b/arch/powerpc/kernel/process.c > @@ -349,6 +349,14 @@ void flush_spe_to_thread(struct task_struct *tsk) > preempt_enable(); > } > } > +#else > +/* > + * save_all() is going to test MSR_SPE, rather than pull in all the > + * booke definitions all the time on a books kernel just ensure it exists > + * but acts as a nop. > + */ > + > +#define MSR_SPE 0 > #endif /* CONFIG_SPE */ Building corenet32/64_defconfig this gives me: arch/powerpc/kernel/process.c:392:0: error: "MSR_SPE" redefined [-Werror] #define MSR_SPE 0 ^ In file included from ./arch/powerpc/include/asm/reg.h:18:0, from ./arch/powerpc/include/asm/processor.h:13, from ./arch/powerpc/include/asm/thread_info.h:33, from include/linux/thread_info.h:54, from include/asm-generic/preempt.h:4, from arch/powerpc/include/generated/asm/preempt.h:1, from include/linux/preempt.h:59, from include/linux/spinlock.h:50, from include/linux/seqlock.h:35, from include/linux/time.h:5, from include/uapi/linux/timex.h:56, from include/linux/timex.h:56, from include/linux/sched.h:19, from arch/powerpc/kernel/process.c:18: ./arch/powerpc/include/asm/reg_booke.h:33:0: note: this is the location of the previous definition #define MSR_SPE __MASK(MSR_SPE_LG) ^ cc1: all warnings being treated as errors scripts/Makefile.build:258: recipe for target 'arch/powerpc/kernel/process.o' failed make[1]: *** [arch/powerpc/kernel/process.o] Error 1 make[1]: *** Waiting for unfinished jobs.... Makefile:950: recipe for target 'arch/powerpc/kernel' failed cheers
diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 5b268b6..3690041 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -34,6 +34,7 @@ static inline void disable_kernel_fp(void) msr_check_and_clear(MSR_FP); } #else +static inline void __giveup_fpu(struct task_struct *t) { } static inline void flush_fp_to_thread(struct task_struct *t) { } #endif @@ -46,6 +47,8 @@ static inline void disable_kernel_altivec(void) { msr_check_and_clear(MSR_VEC); } +#else +static inline void __giveup_altivec(struct task_struct *t) { } #endif #ifdef CONFIG_VSX @@ -57,6 +60,8 @@ static inline void disable_kernel_vsx(void) { msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); } +#else +static inline void __giveup_vsx(struct task_struct *t) { } #endif #ifdef CONFIG_SPE @@ -68,6 +73,8 @@ static inline void disable_kernel_spe(void) { msr_check_and_clear(MSR_SPE); } +#else +static inline void __giveup_spe(struct task_struct *t) { } #endif static inline void clear_task_ebb(struct task_struct *t) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 0955b7c..45e37c0 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -349,6 +349,14 @@ void flush_spe_to_thread(struct task_struct *tsk) preempt_enable(); } } +#else +/* + * save_all() is going to test MSR_SPE, rather than pull in all the + * booke definitions all the time on a books kernel just ensure it exists + * but acts as a nop. + */ + +#define MSR_SPE 0 #endif /* CONFIG_SPE */ static unsigned long msr_all_available; @@ -440,12 +448,41 @@ void restore_math(struct pt_regs *regs) regs->msr = msr; } +void save_all(struct task_struct *tsk) +{ + unsigned long usermsr; + + if (!tsk->thread.regs) + return; + + usermsr = tsk->thread.regs->msr; + + if ((usermsr & msr_all_available) == 0) + return; + + msr_check_and_set(msr_all_available); + + if (usermsr & MSR_FP) + __giveup_fpu(tsk); + + if (usermsr & MSR_VEC) + __giveup_altivec(tsk); + + if (usermsr & MSR_VSX) + __giveup_vsx(tsk); + + if (usermsr & MSR_SPE) + __giveup_spe(tsk); + + msr_check_and_clear(msr_all_available); +} + void flush_all_to_thread(struct task_struct *tsk) { if (tsk->thread.regs) { preempt_disable(); BUG_ON(tsk != current); - giveup_all(tsk); + save_all(tsk); #ifdef CONFIG_SPE if (tsk->thread.regs->msr & MSR_SPE)
This prepares for the decoupling of saving {fpu,altivec,vsx} registers and marking {fpu,altivec,vsx} as being unused by a thread. Currently giveup_{fpu,altivec,vsx}() does both however optimisations to task switching can be made if these two operations are decoupled. save_all() will permit the saving of registers to thread structs and leave threads MSR with bits enabled. This patch introduces no functional change. Signed-off-by: Cyril Bur <cyrilbur@gmail.com> --- arch/powerpc/include/asm/switch_to.h | 7 +++++++ arch/powerpc/kernel/process.c | 39 +++++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-)