linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Christophe Leroy <christophe.leroy@csgroup.eu>
To: Nicholas Piggin <npiggin@gmail.com>,
	"linuxppc-dev@lists.ozlabs.org" <linuxppc-dev@lists.ozlabs.org>
Subject: Re: [PATCH v2] powerpc/64s: add pte_needs_flush and huge_pmd_needs_flush
Date: Thu, 1 Sep 2022 11:27:28 +0000	[thread overview]
Message-ID: <d699b8d5-dba1-2239-4b2e-cd810dee7d9f@csgroup.eu> (raw)
In-Reply-To: <20220901110334.1618913-1-npiggin@gmail.com>



Le 01/09/2022 à 13:03, Nicholas Piggin a écrit :
> Allow PTE changes to avoid flushing the TLB when access permissions are
> being relaxed, the dirty bit is being set, and the accessed bit is being
> changed.
> 
> Relaxing access permissions and setting dirty and accessed bits do not
> require a flush because the MMU will re-load the PTE and notice the
> updates (it may also cause a spurious fault).
> 
> Clearing the accessed bit does not require a flush because of the
> imprecise PTE accessed bit accounting that is already performed, as
> documented in ptep_clear_flush_young().
> 
> This reduces TLB flushing for some mprotect(2) calls.
> 
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>

> ---
> Changes in v2:
> - Change VM_BUG_ON to VM_WARN_ON (Christophe)
> - Remove ifndef guard around helper defines (Christophe)
> - Adjust comments slightly.
> 
>   arch/powerpc/include/asm/book3s/64/pgtable.h  |  3 +
>   arch/powerpc/include/asm/book3s/64/tlbflush.h | 56 +++++++++++++++++++
>   arch/powerpc/mm/book3s64/hash_tlb.c           |  1 +
>   arch/powerpc/mm/book3s64/pgtable.c            |  1 +
>   4 files changed, 61 insertions(+)
> 
> diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
> index cb9d5fd39d7f..a5042bb9a30c 100644
> --- a/arch/powerpc/include/asm/book3s/64/pgtable.h
> +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
> @@ -411,6 +411,9 @@ static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
>    * event of it not getting flushed for a long time the delay
>    * shouldn't really matter because there's no real memory
>    * pressure for swapout to react to. ]
> + *
> + * Note: this optimisation also exists in pte_needs_flush() and
> + * huge_pmd_needs_flush().
>    */
>   #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
>   #define ptep_clear_flush_young ptep_test_and_clear_young
> diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush.h b/arch/powerpc/include/asm/book3s/64/tlbflush.h
> index d2e80f178b6d..66b0de0ce601 100644
> --- a/arch/powerpc/include/asm/book3s/64/tlbflush.h
> +++ b/arch/powerpc/include/asm/book3s/64/tlbflush.h
> @@ -143,6 +143,62 @@ static inline void flush_tlb_fix_spurious_fault(struct vm_area_struct *vma,
>   		flush_tlb_page(vma, address);
>   }
>   
> +static inline bool __pte_flags_need_flush(unsigned long oldval,
> +					  unsigned long newval)
> +{
> +	unsigned long delta = oldval ^ newval;
> +
> +	/*
> +	 * The return value of this function doesn't matter for hash,
> +	 * ptep_modify_prot_start() does a pte_update() which does or schedules
> +	 * any necessary hash table update and flush.
> +	 */
> +	if (!radix_enabled())
> +		return true;
> +
> +	/*
> +	 * We do not expect kernel mappings or non-PTEs or not-present PTEs.
> +	 */
> +	VM_WARN_ON_ONCE(oldval & _PAGE_PRIVILEGED);
> +	VM_WARN_ON_ONCE(newval & _PAGE_PRIVILEGED);
> +	VM_WARN_ON_ONCE(!(oldval & _PAGE_PTE));
> +	VM_WARN_ON_ONCE(!(newval & _PAGE_PTE));
> +	VM_WARN_ON_ONCE(!(oldval & _PAGE_PRESENT));
> +	VM_WARN_ON_ONCE(!(newval & _PAGE_PRESENT));
> +
> +	/*
> +	*  Must flush on any change except READ, WRITE, EXEC, DIRTY, ACCESSED.
> +	*
> +	 * In theory, some changed software bits could be tolerated, in
> +	 * practice those should rarely if ever matter.
> +	 */
> +
> +	if (delta & ~(_PAGE_RWX | _PAGE_DIRTY | _PAGE_ACCESSED))
> +		return true;
> +
> +	/*
> +	 * If any of the above was present in old but cleared in new, flush.
> +	 * With the exception of _PAGE_ACCESSED, don't worry about flushing
> +	 * if that was cleared (see the comment in ptep_clear_flush_young()).
> +	 */
> +	if ((delta & ~_PAGE_ACCESSED) & oldval)
> +		return true;
> +
> +	return false;
> +}
> +
> +static inline bool pte_needs_flush(pte_t oldpte, pte_t newpte)
> +{
> +	return __pte_flags_need_flush(pte_val(oldpte), pte_val(newpte));
> +}
> +#define pte_needs_flush pte_needs_flush
> +
> +static inline bool huge_pmd_needs_flush(pmd_t oldpmd, pmd_t newpmd)
> +{
> +	return __pte_flags_need_flush(pmd_val(oldpmd), pmd_val(newpmd));
> +}
> +#define huge_pmd_needs_flush huge_pmd_needs_flush
> +
>   extern bool tlbie_capable;
>   extern bool tlbie_enabled;
>   

  reply	other threads:[~2022-09-01 11:28 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-01 11:03 [PATCH v2] powerpc/64s: add pte_needs_flush and huge_pmd_needs_flush Nicholas Piggin
2022-09-01 11:27 ` Christophe Leroy [this message]
2022-09-23 11:13 ` Michael Ellerman

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=d699b8d5-dba1-2239-4b2e-cd810dee7d9f@csgroup.eu \
    --to=christophe.leroy@csgroup.eu \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=npiggin@gmail.com \
    /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).