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(¤t->thread);
> + return;
> + }
> +
> pr_emerg("Unrecoverable TM Unavailable Exception "
> "%lx at %lx\n", regs->trap, regs->nip);
> die("Unrecoverable TM Unavailable Exception", regs, SIGABRT);
>
prev parent 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).