linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Laurent Dufour <ldufour@linux.vnet.ibm.com>
To: Cyril Bur <cyrilbur@gmail.com>, linuxppc-dev@ozlabs.org
Cc: mikey@neuling.org, anton@samba.org
Subject: Re: [RFC 3/3] powerpc: tm: Enable transactional memory (TM) lazily for userspace
Date: Thu, 30 Jun 2016 11:46:25 +0200	[thread overview]
Message-ID: <5774EA71.8060607@linux.vnet.ibm.com> (raw)
In-Reply-To: <20160629063436.10003-4-cyrilbur@gmail.com>

On 29/06/2016 08:34, Cyril Bur wrote:
> Currently the MSR TM bit is always set if the hardware is TM capable.
> This adds extra overhead as it means the TM SPRS (TFHAR, TEXASR and
> TFAIR) must be swapped for each process regardless of if they use TM.
> 
> For processes that don't use TM the TM MSR bit can be turned off
> allowing the kernel to avoid the expensive swap of the TM registers.
> 
> A TM unavailable exception will occur if a thread does use TM and the
> kernel will enable MSR_TM and leave it so for some time afterwards.
> 
> Signed-off-by: Cyril Bur <cyrilbur@gmail.com>
> ---
>  arch/powerpc/include/asm/processor.h |  1 +
>  arch/powerpc/kernel/process.c        | 30 ++++++++++++++++++++++--------
>  arch/powerpc/kernel/traps.c          |  8 ++++++++
>  3 files changed, 31 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
> index 5ff1e4c..9d4363c 100644
> --- a/arch/powerpc/include/asm/processor.h
> +++ b/arch/powerpc/include/asm/processor.h
> @@ -257,6 +257,7 @@ struct thread_struct {
>  	int		used_spe;	/* set if process has used spe */
>  #endif /* CONFIG_SPE */
>  #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> +	u8	load_tm;
>  	u64		tm_tfhar;	/* Transaction fail handler addr */
>  	u64		tm_texasr;	/* Transaction exception & summary */
>  	u64		tm_tfiar;	/* Transaction fail instr address reg */
> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
> index 2e903c6..8abecda 100644
> --- a/arch/powerpc/kernel/process.c
> +++ b/arch/powerpc/kernel/process.c
> @@ -870,6 +870,9 @@ void tm_recheckpoint(struct thread_struct *thread,
>  {
>  	unsigned long flags;
>  
> +	if (!(thread->regs->msr & MSR_TM))
> +		return;
> +
>  	/* We really can't be interrupted here as the TEXASR registers can't
>  	 * change and later in the trecheckpoint code, we have a userspace R1.
>  	 * So let's hard disable over this region.
> @@ -905,6 +908,9 @@ static inline void tm_recheckpoint_new_task(struct task_struct *new)
>  	if (!new->thread.regs)
>  		return;
>  
> +	if (!(new->thread.regs->msr & MSR_TM))
> +		return;
> +
>  	if (!MSR_TM_ACTIVE(new->thread.regs->msr)){
>  		tm_restore_sprs(&new->thread);
>  		return;
> @@ -925,11 +931,18 @@ static inline void tm_recheckpoint_new_task(struct task_struct *new)
>  		 new->pid, mfmsr());
>  }
>  
> -static inline void __switch_to_tm(struct task_struct *prev)
> +static inline void __switch_to_tm(struct task_struct *prev, struct task_struct *new)
>  {
>  	if (cpu_has_feature(CPU_FTR_TM)) {
> -		tm_enable();
> -		tm_reclaim_task(prev);
> +		if (prev->thread.regs && (prev->thread.regs->msr & MSR_TM)) {
> +			prev->thread.load_tm++;
> +			tm_enable();
> +			tm_reclaim_task(prev);
> +			if (!MSR_TM_ACTIVE(prev->thread.regs->msr) && prev->thread.load_tm == 0)
> +				prev->thread.regs->msr |= ~MSR_TM;

Hi Cyrill,

I guess the idea is to clear MSR_TM here, so why "or-ing" here ?
I'd rather see :
 +				prev->thread.regs->msr &= ~MSR_TM;

Cheers,
Laurent.

> +		} else if (new && new->thread.regs && (new->thread.regs->msr & MSR_TM)) {
> +			tm_enable();
> +		}
>  	}
>  }
>  
> @@ -965,7 +978,7 @@ void restore_tm_state(struct pt_regs *regs)
>  
>  #else
>  #define tm_recheckpoint_new_task(new)
> -#define __switch_to_tm(prev)
> +#define __switch_to_tm(prev, new)
>  #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
>  
>  static inline void save_sprs(struct thread_struct *t)
> @@ -1095,7 +1108,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
>  	/* Save FPU, Altivec, VSX and SPE state */
>  	giveup_all(prev);
>  
> -	__switch_to_tm(prev);
> +	__switch_to_tm(prev, new);
>  
>  	/*
>  	 * We can't take a PMU exception inside _switch() since there is a
> @@ -1340,8 +1353,11 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
>  	 * 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.
> +	 *
> +	 * Can't pass dst because it isn't ready. Doesn't matter, passing
> +	 * dst is only important for __switch_to()
>  	 */
> -	__switch_to_tm(src);
> +	__switch_to_tm(src, NULL);
>  	tm_recheckpoint_new_task(src);
>  
>  	*dst = *src;
> @@ -1574,8 +1590,6 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
>  	current->thread.used_spe = 0;
>  #endif /* CONFIG_SPE */
>  #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> -	if (cpu_has_feature(CPU_FTR_TM))
> -		regs->msr |= MSR_TM;
>  	current->thread.tm_tfhar = 0;
>  	current->thread.tm_texasr = 0;
>  	current->thread.tm_tfiar = 0;
> diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
> index 29260ee..141b953 100644
> --- a/arch/powerpc/kernel/traps.c
> +++ b/arch/powerpc/kernel/traps.c
> @@ -1366,6 +1366,14 @@ void vsx_unavailable_exception(struct pt_regs *regs)
>  
>  static void tm_unavailable(struct pt_regs *regs)
>  {
> +	if (user_mode(regs)) {
> +		current->thread.load_tm++;
> +		regs->msr |= MSR_TM;
> +		tm_enable();
> +		tm_restore_sprs(&current->thread);
> +		return;
> +	}
> +
>  	pr_emerg("Unrecoverable TM Unavailable Exception "
>  			"%lx at %lx\n", regs->trap, regs->nip);
>  	die("Unrecoverable TM Unavailable Exception", regs, SIGABRT);
> 

      reply	other threads:[~2016-06-30  9:46 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-29  6:34 [RFC 0/3] Enable MSR_TM lazily Cyril Bur
2016-06-29  6:34 ` [RFC 1/3] selftests/powerpc: Add test to check TM ucontext creation Cyril Bur
2016-06-29  6:34 ` [RFC 2/3] powerpc: tm: Add TM Unavailable Exception Cyril Bur
2016-06-29  6:34 ` [RFC 3/3] powerpc: tm: Enable transactional memory (TM) lazily for userspace Cyril Bur
2016-06-30  9:46   ` Laurent Dufour [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5774EA71.8060607@linux.vnet.ibm.com \
    --to=ldufour@linux.vnet.ibm.com \
    --cc=anton@samba.org \
    --cc=cyrilbur@gmail.com \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=mikey@neuling.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).