This patch creates a new function called flush_tm_state to flush the existing transactional memory state from the thread. It also creates a function called flush_tmregs_to_thread which will then be used on subsequent patches in this series.
Signed-off-by: Anshuman Khandual <khand...@linux.vnet.ibm.com> --- arch/powerpc/include/asm/switch_to.h | 8 ++++++ arch/powerpc/kernel/process.c | 49 +++++++++++++++++++++++++++++------- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 58abeda..23752a9 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -82,6 +82,14 @@ static inline void flush_spe_to_thread(struct task_struct *t) } #endif +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +extern void flush_tmregs_to_thread(struct task_struct *); +#else +static inline void flush_tmregs_to_thread(struct task_struct *t) +{ +} +#endif + static inline void clear_task_ebb(struct task_struct *t) { #ifdef CONFIG_PPC_BOOK3S_64 diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index aa1df89..c36477b 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -745,6 +745,45 @@ void restore_tm_state(struct pt_regs *regs) #define __switch_to_tm(prev) #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ +/* + * flush_tm_state + * + * Flush TM state out so we can copy it. __switch_to_tm() does this + * flush but it removes the checkpointed state from the current CPU and + * transitions the CPU out of TM mode. Hence we need to call + * tm_recheckpoint_new_task() (on the same task) to restore the + * checkpointed state back and the TM mode. + */ +static void flush_tm_state(struct task_struct *src) +{ + __switch_to_tm(src); + tm_recheckpoint_new_task(src); +} + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +void flush_tmregs_to_thread(struct task_struct *tsk) +{ + /* + * If task is not current, it should have been flushed + * already to it's thread_struct during __switch_to(). + */ + if (tsk != current) + return; + + preempt_disable(); + if (tsk->thread.regs) { + /* + * If we are still current, the TM state need to + * be flushed to thread_struct as it will be still + * present in the current cpu. + */ + if (MSR_TM_ACTIVE(tsk->thread.regs->msr)) + flush_tm_state(tsk); + } + preempt_enable(); +} +#endif + struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *new) { @@ -1079,15 +1118,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) flush_altivec_to_thread(src); flush_vsx_to_thread(src); flush_spe_to_thread(src); - /* - * Flush TM state out so we can copy it. __switch_to_tm() does this - * flush but it removes the checkpointed state from the current CPU and - * transitions the CPU out of TM mode. Hence we need to call - * tm_recheckpoint_new_task() (on the same task) to restore the - * checkpointed state back and the TM mode. - */ - __switch_to_tm(src); - tm_recheckpoint_new_task(src); + flush_tm_state(src); *dst = *src; -- 1.9.3 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev