All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mahesh Jagannath Salgaonkar <mahesh@linux.vnet.ibm.com>
To: Michael Ellerman <mpe@ellerman.id.au>,
	linuxppc-dev <linuxppc-dev@ozlabs.org>,
	Paul Mackerras <paulus@samba.org>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>
Subject: Re: powerpc/book3s: Fix flush_tlb cpu_spec hook to take a generic argument.
Date: Tue, 02 Dec 2014 14:31:38 +0530	[thread overview]
Message-ID: <547D7FF2.3010901@linux.vnet.ibm.com> (raw)
In-Reply-To: <20141128223838.B21E51401B1@ozlabs.org>

On 11/29/2014 04:08 AM, Michael Ellerman wrote:
> On Tue, 2014-23-09 at 03:53:54 UTC, Mahesh Salgaonkar wrote:
>> From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
>>
>> The flush_tlb hook in cpu_spec was introduced as a generic function hook
>> to invalidate TLBs. But the current implementation of flush_tlb hook
>> takes IS (invalidation selector) as an argument which is architecture
>> dependent. Hence, It is not right to have a generic routine where caller
>> has to pass non-generic argument.
>>
>> This patch fixes this and makes flush_tlb hook as high level API.
>>
>> The old code used to call flush_tlb hook with IS=0 (single page) resulting
>> partial invalidation of TLBs which is not right. This fix now makes
>> sure that whole TLB is invalidated to be able to successfully recover from
>> TLB and ERAT errors.
> 
> Which old code? You mean the MCE code I think. That's a bug fix, so it should
> be a separate patch.

Yes. MCE code. Since this patch re-factors the code that takes IS as
direct argument, having a separate fix patch does not make any sense and
would get overwritten by this patch anyway.

> 
>> diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
>> index daa5af9..ae3e74f 100644
>> --- a/arch/powerpc/include/asm/cputable.h
>> +++ b/arch/powerpc/include/asm/cputable.h
>> @@ -100,7 +100,7 @@ struct cpu_spec {
>>  	/*
>>  	 * Processor specific routine to flush tlbs.
>>  	 */
>> -	void		(*flush_tlb)(unsigned long inval_selector);
>> +	void		(*flush_tlb)(unsigned int action);
>>  
>>  };
>>  
>> diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
>> index d765144..068ac8b 100644
>> --- a/arch/powerpc/include/asm/mmu-hash64.h
>> +++ b/arch/powerpc/include/asm/mmu-hash64.h
>> @@ -112,6 +112,11 @@
>>  #define TLBIEL_INVAL_SET_SHIFT	12
>>  
>>  #define POWER7_TLB_SETS		128	/* # sets in POWER7 TLB */
>> +#define POWER8_TLB_SETS		512	/* # sets in POWER8 TLB */
>> +
>> +/* TLB flush actions. Used as argument to cpu_spec.flush_tlb() hook */
>> +#define FLUSH_TLB_ALL		0	/* invalidate all TLBs */
>> +#define FLUSH_TLB_LPID		1	/* invalidate TLBs for current LPID */
> 
> Now that these are generic actions then they should go in cputable.h with the
> flush hook.

Sure, I will move them.

> 
>> diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S
>> index 4673353..9c9b741 100644
>> --- a/arch/powerpc/kernel/cpu_setup_power.S
>> +++ b/arch/powerpc/kernel/cpu_setup_power.S
>> @@ -137,15 +137,11 @@ __init_HFSCR:
>>  /*
>>   * Clear the TLB using the specified IS form of tlbiel instruction
>>   * (invalidate by congruence class). P7 has 128 CCs., P8 has 512.
>> - *
>> - * r3 = IS field
>>   */
>>  __init_tlb_power7:
>> -	li	r3,0xc00	/* IS field = 0b11 */
>> -_GLOBAL(__flush_tlb_power7)
>>  	li	r6,128
>>  	mtctr	r6
>> -	mr	r7,r3		/* IS field */
>> +	li	r7,0xc00	/* IS field = 0b11 */
>>  	ptesync
>>  2:	tlbiel	r7
>>  	addi	r7,r7,0x1000
> 
> So the current version is:
> 
> _GLOBAL(__flush_tlb_power7)
> 	li	r6,128
> 	mtctr	r6
> 	mr	r7,r3		/* IS field */
> 	ptesync
> 2:	tlbiel	r7
> 	addi	r7,r7,0x1000
> 	bdnz	2b
> 	ptesync
> 1:	blr
> 
> ie. a loop preceeded and followed by ptesync.
> 
> Your new version is:
> 
>> +static void _flush_tlb(uint32_t tlb_set, unsigned long inval_selector)
>> +{
>> +	unsigned long i, rb;
>> +
>> +	rb = inval_selector;
>> +	for (i = 0; i < tlb_set; i++) {
>> +		asm volatile("tlbiel %0" : : "r" (rb));
>> +		rb += 1 << TLBIEL_INVAL_SET_SHIFT;
>> +	}
>> +}
> 
> ie. no ptesyncs at all.
> 
> But there's no mention of that in the changelog. You need to explain why it is
> OK to drop the ptesyncs.

You are right. I should put ptesyncs in _flush_tlb(). Will make this
change in v2. Thanks for catching this.

> 
>> +/*
>> + * Generic routine to flush TLB on power7. This routine is used as
>> + * flush_tlb hook in cpu_spec for Power7 processor.
>> + *
>> + * action => FLUSH_TLB_ALL:  Invalidate all TLBs.
>> + *	     FLUSH_TLB_LPID: Invalidate TLB for current LPID.
>> + */
>> +void __flush_tlb_power7(unsigned int action)
>> +{
>> +	switch (action) {
>> +	case FLUSH_TLB_ALL:
>> +		_flush_tlb(POWER7_TLB_SETS, TLBIEL_INVAL_SET);
>> +		break;
>> +	case FLUSH_TLB_LPID:
>> +		_flush_tlb(POWER7_TLB_SETS, TLBIEL_INVAL_SET_LPID);
>> +		break;
>> +	default:
>> +		break;
>> +	}
>> +}
>> +
>> +/*
>> + * Generic routine to flush TLB on power8. This routine is used as
>> + * flush_tlb hook in cpu_spec for power8 processor.
>> + *
>> + * action => FLUSH_TLB_ALL:  Invalidate all TLBs.
>> + *	     FLUSH_TLB_LPID: Invalidate TLB for current LPID.
>> + */
>> +void __flush_tlb_power8(unsigned int action)
>> +{
>> +	switch (action) {
>> +	case FLUSH_TLB_ALL:
>> +		_flush_tlb(POWER8_TLB_SETS, TLBIEL_INVAL_SET);
>> +		break;
>> +	case FLUSH_TLB_LPID:
>> +		_flush_tlb(POWER8_TLB_SETS, TLBIEL_INVAL_SET_LPID);
>> +		break;
>> +	default:
>> +		break;
>> +	}
>> +}
> 
> How about this:
> 
> void flush_tlb_206(unsigned num_sets, unsigned int action)
> {
> 	unsigned long rb;
> 	int i;
> 
> 	switch (action) {
> 	case FLUSH_TLB_ALL:
> 		rb = TLBIEL_INVAL_SET;
> 		break;
> 	case FLUSH_TLB_LPID:
> 		rb = TLBIEL_INVAL_SET_LPID;
> 		break;
> 	default:
> 		BUG();
> 	}
> 
> 	for (i = 0; i < num_sets; i++) {
> 		asm volatile("tlbiel %0" : : "r" (rb));
> 		rb += 1 << TLBIEL_INVAL_SET_SHIFT;
> 	}
> }
> 
> void flush_tlb_power8(unsigned int action)
> {
> 	flush_tlb_206(POWER8_TLB_SETS, action);
> }
> 
> void flush_tlb_power7(unsigned int action)
> {
> 	flush_tlb_206(POWER7_TLB_SETS, action);
> }
> 

Agree. Will roll out v2 with above suggested changes.

Thanks,
-Mahesh.

  reply	other threads:[~2014-12-02  9:01 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-23  3:53 [PATCH] powerpc/book3s: Fix flush_tlb cpu_spec hook to take a generic argument Mahesh J Salgaonkar
2014-10-03  7:36 ` Michael Ellerman
2014-10-03  8:04   ` Benjamin Herrenschmidt
2014-11-28 22:38 ` Michael Ellerman
2014-12-02  9:01   ` Mahesh Jagannath Salgaonkar [this message]
2014-12-04  9:35     ` Michael Ellerman
2014-12-05  4:33       ` Mahesh Jagannath Salgaonkar

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=547D7FF2.3010901@linux.vnet.ibm.com \
    --to=mahesh@linux.vnet.ibm.com \
    --cc=benh@kernel.crashing.org \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=mpe@ellerman.id.au \
    --cc=paulus@samba.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.