All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Neuling <mikey@neuling.org>
To: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>,
	benh@kernel.crashing.org, paulus@samba.org, mpe@ellerman.id.au
Cc: linuxppc-dev@lists.ozlabs.org
Subject: Re: [PATCH 3/4] powerpc/mm/radix: Use different pte update sequence for different POWER9 revs
Date: Tue, 06 Sep 2016 11:12:42 +1000	[thread overview]
Message-ID: <1473124362.6491.39.camel@neuling.org> (raw)
In-Reply-To: <1472031219-18759-3-git-send-email-aneesh.kumar@linux.vnet.ibm.com>

On Wed, 2016-08-24 at 15:03 +0530, Aneesh Kumar K.V wrote:
> POWER9 DD1 requires pte to be marked invalid (V=3D0) before updating
> it with the new value. This makes this distinction for the different
> revisions.
>=20
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>

Acked-by: Michael Neuling <mikey@neuling.org>

> ---
> =C2=A0arch/powerpc/include/asm/book3s/32/pgtable.h |=C2=A0=C2=A03 +-
> =C2=A0arch/powerpc/include/asm/book3s/64/pgtable.h |=C2=A0=C2=A05 +-
> =C2=A0arch/powerpc/include/asm/book3s/64/radix.h=C2=A0=C2=A0=C2=A0| 75 ++=
++++++++++++++++++++------
> =C2=A0arch/powerpc/include/asm/nohash/32/pgtable.h |=C2=A0=C2=A03 +-
> =C2=A0arch/powerpc/include/asm/nohash/64/pgtable.h |=C2=A0=C2=A03 +-
> =C2=A0arch/powerpc/mm/pgtable-book3s64.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0|=C2=A0=C2=A02 +-
> =C2=A0arch/powerpc/mm/pgtable.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0|=C2=A0=C2=A02 +-
> =C2=A07 files changed, 71 insertions(+), 22 deletions(-)
>=20
> diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/=
include/asm/book3s/32/pgtable.h
> index 38b33dcfcc9d..6b8b2d57fdc8 100644
> --- a/arch/powerpc/include/asm/book3s/32/pgtable.h
> +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
> @@ -223,7 +223,8 @@ static inline void huge_ptep_set_wrprotect(struct mm_=
struct *mm,
> =C2=A0}
> =C2=A0
> =C2=A0
> -static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
> +static inline void __ptep_set_access_flags(struct mm_struct *mm,
> +					=C2=A0=C2=A0=C2=A0pte_t *ptep, pte_t entry)
> =C2=A0{
> =C2=A0	unsigned long set =3D pte_val(entry) &
> =C2=A0		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
> diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/=
include/asm/book3s/64/pgtable.h
> index 263bf39ced40..8ec8be9495ba 100644
> --- a/arch/powerpc/include/asm/book3s/64/pgtable.h
> +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
> @@ -565,10 +565,11 @@ static inline bool check_pte_access(unsigned long a=
ccess, unsigned long ptev)
> =C2=A0 * Generic functions with hash/radix callbacks
> =C2=A0 */
> =C2=A0
> -static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
> +static inline void __ptep_set_access_flags(struct mm_struct *mm,
> +					=C2=A0=C2=A0=C2=A0pte_t *ptep, pte_t entry)
> =C2=A0{
> =C2=A0	if (radix_enabled())
> -		return radix__ptep_set_access_flags(ptep, entry);
> +		return radix__ptep_set_access_flags(mm, ptep, entry);
> =C2=A0	return hash__ptep_set_access_flags(ptep, entry);
> =C2=A0}
> =C2=A0
> diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/in=
clude/asm/book3s/64/radix.h
> index a2fe8fbfbd3d..2a46dea8e1b1 100644
> --- a/arch/powerpc/include/asm/book3s/64/radix.h
> +++ b/arch/powerpc/include/asm/book3s/64/radix.h
> @@ -11,6 +11,11 @@
> =C2=A0#include=20
> =C2=A0#endif
> =C2=A0
> +#ifndef __ASSEMBLY__
> +#include=20
> +#include=20
> +#endif
> +
> =C2=A0/* An empty PTE can still have a R or C writeback */
> =C2=A0#define RADIX_PTE_NONE_MASK		(_PAGE_DIRTY | _PAGE_ACCESSED)
> =C2=A0
> @@ -105,11 +110,8 @@
> =C2=A0#define RADIX_PUD_TABLE_SIZE	(sizeof(pud_t) << RADIX_PUD_INDEX_SIZE=
)
> =C2=A0#define RADIX_PGD_TABLE_SIZE	(sizeof(pgd_t) << RADIX_PGD_INDEX_SIZE=
)
> =C2=A0
> -static inline unsigned long radix__pte_update(struct mm_struct *mm,
> -					unsigned long addr,
> -					pte_t *ptep, unsigned long clr,
> -					unsigned long set,
> -					int huge)
> +static inline unsigned long __radix_pte_update(pte_t *ptep, unsigned lon=
g clr,
> +					=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0unsigned long set)
> =C2=A0{
> =C2=A0	pte_t pte;
> =C2=A0	unsigned long old_pte, new_pte;
> @@ -121,9 +123,39 @@ static inline unsigned long radix__pte_update(struct=
 mm_struct *mm,
> =C2=A0
> =C2=A0	} while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
> =C2=A0
> -	/* We already do a sync in cmpxchg, is ptesync needed ?*/
> +	return old_pte;
> +}
> +
> +
> +static inline unsigned long radix__pte_update(struct mm_struct *mm,
> +					unsigned long addr,
> +					pte_t *ptep, unsigned long clr,
> +					unsigned long set,
> +					int huge)
> +{
> +	unsigned long old_pte;
> +
> +	if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
> +
> +		unsigned long new_pte;
> +
> +		old_pte =3D __radix_pte_update(ptep, ~0, 0);
> +		asm volatile("ptesync" : : : "memory");
> +		/*
> +		=C2=A0* new value of pte
> +		=C2=A0*/
> +		new_pte =3D (old_pte | set) & ~clr;
> +
> +		/*
> +		=C2=A0* For now let's do heavy pid flush
> +		=C2=A0* radix__flush_tlb_page_psize(mm, addr, mmu_virtual_psize);
> +		=C2=A0*/
> +		radix__flush_tlb_mm(mm);
> +
> +		__radix_pte_update(ptep, 0, new_pte);
> +	} else
> +		old_pte =3D __radix_pte_update(ptep, clr, set);
> =C2=A0	asm volatile("ptesync" : : : "memory");
> -	/* huge pages use the old page table lock */
> =C2=A0	if (!huge)
> =C2=A0		assert_pte_locked(mm, addr);
> =C2=A0
> @@ -134,20 +166,33 @@ static inline unsigned long radix__pte_update(struc=
t mm_struct *mm,
> =C2=A0 * Set the dirty and/or accessed bits atomically in a linux PTE, th=
is
> =C2=A0 * function doesn't need to invalidate tlb.
> =C2=A0 */
> -static inline void radix__ptep_set_access_flags(pte_t *ptep, pte_t entry=
)
> +static inline void radix__ptep_set_access_flags(struct mm_struct *mm,
> +						pte_t *ptep, pte_t entry)
> =C2=A0{
> -	pte_t pte;
> -	unsigned long old_pte, new_pte;
> +
> =C2=A0	unsigned long set =3D pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESS=
ED |
> =C2=A0					=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0_PAGE_RW | _PAGE_EXEC);
> -	do {
> -		pte =3D READ_ONCE(*ptep);
> -		old_pte =3D pte_val(pte);
> +
> +	if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
> +
> +		unsigned long old_pte, new_pte;
> +
> +		old_pte =3D __radix_pte_update(ptep, ~0, 0);
> +		asm volatile("ptesync" : : : "memory");
> +		/*
> +		=C2=A0* new value of pte
> +		=C2=A0*/
> =C2=A0		new_pte =3D old_pte | set;
> =C2=A0
> -	} while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
> +		/*
> +		=C2=A0* For now let's do heavy pid flush
> +		=C2=A0* radix__flush_tlb_page_psize(mm, addr, mmu_virtual_psize);
> +		=C2=A0*/
> +		radix__flush_tlb_mm(mm);
> =C2=A0
> -	/* We already do a sync in cmpxchg, is ptesync needed ?*/
> +		__radix_pte_update(ptep, 0, new_pte);
> +	} else
> +		__radix_pte_update(ptep, 0, set);
> =C2=A0	asm volatile("ptesync" : : : "memory");
> =C2=A0}
> =C2=A0
> diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/=
include/asm/nohash/32/pgtable.h
> index 780847597514..c219ef7be53b 100644
> --- a/arch/powerpc/include/asm/nohash/32/pgtable.h
> +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
> @@ -267,7 +267,8 @@ static inline void huge_ptep_set_wrprotect(struct mm_=
struct *mm,
> =C2=A0}
> =C2=A0
> =C2=A0
> -static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
> +static inline void __ptep_set_access_flags(struct mm_struct *mm,
> +					=C2=A0=C2=A0=C2=A0pte_t *ptep, pte_t entry)
> =C2=A0{
> =C2=A0	unsigned long set =3D pte_val(entry) &
> =C2=A0		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
> diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/=
include/asm/nohash/64/pgtable.h
> index d4d808cf905e..653a1838469d 100644
> --- a/arch/powerpc/include/asm/nohash/64/pgtable.h
> +++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
> @@ -300,7 +300,8 @@ static inline void pte_clear(struct mm_struct *mm, un=
signed long addr,
> =C2=A0/* Set the dirty and/or accessed bits atomically in a linux PTE, th=
is
> =C2=A0 * function doesn't need to flush the hash entry
> =C2=A0 */
> -static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
> +static inline void __ptep_set_access_flags(struct mm_struct *mm,
> +					=C2=A0=C2=A0=C2=A0pte_t *ptep, pte_t entry)
> =C2=A0{
> =C2=A0	unsigned long bits =3D pte_val(entry) &
> =C2=A0		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
> diff --git a/arch/powerpc/mm/pgtable-book3s64.c b/arch/powerpc/mm/pgtable=
-book3s64.c
> index 34079302cc17..7328886bca4c 100644
> --- a/arch/powerpc/mm/pgtable-book3s64.c
> +++ b/arch/powerpc/mm/pgtable-book3s64.c
> @@ -35,7 +35,7 @@ int pmdp_set_access_flags(struct vm_area_struct *vma, u=
nsigned long address,
> =C2=A0#endif
> =C2=A0	changed =3D !pmd_same(*(pmdp), entry);
> =C2=A0	if (changed) {
> -		__ptep_set_access_flags(pmdp_ptep(pmdp), pmd_pte(entry));
> +		__ptep_set_access_flags(vma->vm_mm, pmdp_ptep(pmdp), pmd_pte(entry));
> =C2=A0		flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
> =C2=A0	}
> =C2=A0	return changed;
> diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
> index 0b6fb244d0a1..911fdfb63ec1 100644
> --- a/arch/powerpc/mm/pgtable.c
> +++ b/arch/powerpc/mm/pgtable.c
> @@ -224,7 +224,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma,=
 unsigned long address,
> =C2=A0	if (changed) {
> =C2=A0		if (!is_vm_hugetlb_page(vma))
> =C2=A0			assert_pte_locked(vma->vm_mm, address);
> -		__ptep_set_access_flags(ptep, entry);
> +		__ptep_set_access_flags(vma->vm_mm, ptep, entry);
> =C2=A0		flush_tlb_page(vma, address);
> =C2=A0	}
> =C2=A0	return changed;

  reply	other threads:[~2016-09-06  1:12 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-24  9:33 [PATCH 1/4] powerpc/book3s: Add a cpu table entry for different POWER9 revs Aneesh Kumar K.V
2016-08-24  9:33 ` [PATCH 2/4] powerpc/mm/radix: Use different RTS encoding " Aneesh Kumar K.V
2016-09-06  1:11   ` Michael Neuling
2016-08-24  9:33 ` [PATCH 3/4] powerpc/mm/radix: Use different pte update sequence " Aneesh Kumar K.V
2016-09-06  1:12   ` Michael Neuling [this message]
2016-08-24  9:33 ` [PATCH 4/4] powerpc/mm: Update the HID bit when switching from radix to hash Aneesh Kumar K.V
2016-09-06  1:18   ` Michael Neuling
2016-09-06  1:10 ` [PATCH 1/4] powerpc/book3s: Add a cpu table entry for different POWER9 revs Michael Neuling
2016-09-13 12:16 ` [1/4] " 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=1473124362.6491.39.camel@neuling.org \
    --to=mikey@neuling.org \
    --cc=aneesh.kumar@linux.vnet.ibm.com \
    --cc=benh@kernel.crashing.org \
    --cc=linuxppc-dev@lists.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.