linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] Fix build failure with v5.8-rc1
@ 2020-06-15 12:57 Christophe Leroy
  2020-06-15 12:57 ` [PATCH 1/3] mm/gup: Use huge_ptep_get() in gup_hugepte() Christophe Leroy
                   ` (5 more replies)
  0 siblings, 6 replies; 16+ messages in thread
From: Christophe Leroy @ 2020-06-15 12:57 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Will Deacon, Andrew Morton, Peter Zijlstra (Intel)
  Cc: linux-kernel, linuxppc-dev, linux-mm

Commit 2ab3a0a02905 ("READ_ONCE: Enforce atomicity for
{READ,WRITE}_ONCE() memory accesses") leads to following build
failure on powerpc 8xx.

To fix it, this small series introduces a new helper named ptep_get()
to replace the direct access with READ_ONCE(). This new helper
can be overriden by architectures.


  CC      mm/gup.o
In file included from ./include/linux/kernel.h:11:0,
                 from mm/gup.c:2:
In function 'gup_hugepte.constprop',
    inlined from 'gup_huge_pd.isra.79' at mm/gup.c:2465:8:
./include/linux/compiler.h:392:38: error: call to '__compiletime_assert_222' declared with attribute error: Unsupported access size for {READ,WRITE}_ONCE().
  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                                      ^
./include/linux/compiler.h:373:4: note: in definition of macro '__compiletime_assert'
    prefix ## suffix();    \
    ^
./include/linux/compiler.h:392:2: note: in expansion of macro '_compiletime_assert'
  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
  ^
./include/linux/compiler.h:405:2: note: in expansion of macro 'compiletime_assert'
  compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
  ^
./include/linux/compiler.h:291:2: note: in expansion of macro 'compiletime_assert_rwonce_type'
  compiletime_assert_rwonce_type(x);    \
  ^
mm/gup.c:2428:8: note: in expansion of macro 'READ_ONCE'
  pte = READ_ONCE(*ptep);
        ^
In function 'gup_get_pte',
    inlined from 'gup_pte_range' at mm/gup.c:2228:9,
    inlined from 'gup_pmd_range' at mm/gup.c:2613:15,
    inlined from 'gup_pud_range' at mm/gup.c:2641:15,
    inlined from 'gup_p4d_range' at mm/gup.c:2666:15,
    inlined from 'gup_pgd_range' at mm/gup.c:2694:15,
    inlined from 'internal_get_user_pages_fast' at mm/gup.c:2795:3:
./include/linux/compiler.h:392:38: error: call to '__compiletime_assert_219' declared with attribute error: Unsupported access size for {READ,WRITE}_ONCE().
  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                                      ^
./include/linux/compiler.h:373:4: note: in definition of macro '__compiletime_assert'
    prefix ## suffix();    \
    ^
./include/linux/compiler.h:392:2: note: in expansion of macro '_compiletime_assert'
  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
  ^
./include/linux/compiler.h:405:2: note: in expansion of macro 'compiletime_assert'
  compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
  ^
./include/linux/compiler.h:291:2: note: in expansion of macro 'compiletime_assert_rwonce_type'
  compiletime_assert_rwonce_type(x);    \
  ^
mm/gup.c:2199:9: note: in expansion of macro 'READ_ONCE'
  return READ_ONCE(*ptep);
         ^
make[2]: *** [mm/gup.o] Error 1

Christophe Leroy (3):
  mm/gup: Use huge_ptep_get() in gup_hugepte()
  mm: Allow arches to provide ptep_get()
  powerpc/8xx: Provide ptep_get() with 16k pages

 arch/powerpc/include/asm/nohash/32/pgtable.h | 10 ++++++++++
 include/asm-generic/hugetlb.h                |  2 +-
 include/linux/pgtable.h                      |  7 +++++++
 mm/gup.c                                     |  4 ++--
 4 files changed, 20 insertions(+), 3 deletions(-)

-- 
2.25.0



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/3] mm/gup: Use huge_ptep_get() in gup_hugepte()
  2020-06-15 12:57 [PATCH 0/3] Fix build failure with v5.8-rc1 Christophe Leroy
@ 2020-06-15 12:57 ` Christophe Leroy
  2020-06-17 14:14   ` Michael Ellerman
  2020-06-15 12:57 ` [PATCH 2/3] mm: Allow arches to provide ptep_get() Christophe Leroy
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: Christophe Leroy @ 2020-06-15 12:57 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Will Deacon, Andrew Morton, Peter Zijlstra (Intel)
  Cc: linux-kernel, linuxppc-dev, linux-mm

gup_hugepte() reads hugepage table entries, it can't read
them directly, huge_ptep_get() must be used.

Fixes: 2ab3a0a02905 ("READ_ONCE: Enforce atomicity for {READ,WRITE}_ONCE() memory accesses")
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 mm/gup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/gup.c b/mm/gup.c
index de9e36262ccb..761df4944ef5 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -2425,7 +2425,7 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
 	if (pte_end < end)
 		end = pte_end;
 
-	pte = READ_ONCE(*ptep);
+	pte = huge_ptep_get(ptep);
 
 	if (!pte_access_permitted(pte, flags & FOLL_WRITE))
 		return 0;
-- 
2.25.0



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/3] mm: Allow arches to provide ptep_get()
  2020-06-15 12:57 [PATCH 0/3] Fix build failure with v5.8-rc1 Christophe Leroy
  2020-06-15 12:57 ` [PATCH 1/3] mm/gup: Use huge_ptep_get() in gup_hugepte() Christophe Leroy
@ 2020-06-15 12:57 ` Christophe Leroy
  2020-06-15 12:57 ` [PATCH 3/3] powerpc/8xx: Provide ptep_get() with 16k pages Christophe Leroy
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Christophe Leroy @ 2020-06-15 12:57 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Will Deacon, Andrew Morton, Peter Zijlstra (Intel)
  Cc: linux-kernel, linuxppc-dev, linux-mm

Since commit 2ab3a0a02905 ("READ_ONCE: Enforce atomicity for
{READ,WRITE}_ONCE() memory accesses"), it is not possible anymore
to use READ_ONCE() to access complex page table entries like
the one defined for powerpc 8xx with 16k size pages.

Define a ptep_get() helper that architectures can override instead
of performing a READ_ONCE() on the page table entry pointer.

Fixes: 2ab3a0a02905 ("READ_ONCE: Enforce atomicity for {READ,WRITE}_ONCE() memory accesses")
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 include/asm-generic/hugetlb.h | 2 +-
 include/linux/pgtable.h       | 7 +++++++
 mm/gup.c                      | 2 +-
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/asm-generic/hugetlb.h b/include/asm-generic/hugetlb.h
index 40f85decc2ee..8e1e6244a89d 100644
--- a/include/asm-generic/hugetlb.h
+++ b/include/asm-generic/hugetlb.h
@@ -122,7 +122,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 #ifndef __HAVE_ARCH_HUGE_PTEP_GET
 static inline pte_t huge_ptep_get(pte_t *ptep)
 {
-	return READ_ONCE(*ptep);
+	return ptep_get(ptep);
 }
 #endif
 
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 32b6c52d41b9..56c1e8eb7bb0 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -249,6 +249,13 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
 }
 #endif
 
+#ifndef __HAVE_ARCH_PTEP_GET
+static inline pte_t ptep_get(pte_t *ptep)
+{
+	return READ_ONCE(*ptep);
+}
+#endif
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #ifndef __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
 static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
diff --git a/mm/gup.c b/mm/gup.c
index 761df4944ef5..6f47697f8fb0 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -2196,7 +2196,7 @@ static inline pte_t gup_get_pte(pte_t *ptep)
  */
 static inline pte_t gup_get_pte(pte_t *ptep)
 {
-	return READ_ONCE(*ptep);
+	return ptep_get(ptep);
 }
 #endif /* CONFIG_GUP_GET_PTE_LOW_HIGH */
 
-- 
2.25.0



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/3] powerpc/8xx: Provide ptep_get() with 16k pages
  2020-06-15 12:57 [PATCH 0/3] Fix build failure with v5.8-rc1 Christophe Leroy
  2020-06-15 12:57 ` [PATCH 1/3] mm/gup: Use huge_ptep_get() in gup_hugepte() Christophe Leroy
  2020-06-15 12:57 ` [PATCH 2/3] mm: Allow arches to provide ptep_get() Christophe Leroy
@ 2020-06-15 12:57 ` Christophe Leroy
  2020-06-15 13:22   ` Peter Zijlstra
  2020-06-17 10:57 ` [PATCH 0/3] Fix build failure with v5.8-rc1 Will Deacon
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: Christophe Leroy @ 2020-06-15 12:57 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Will Deacon, Andrew Morton, Peter Zijlstra (Intel)
  Cc: linux-kernel, linuxppc-dev, linux-mm

READ_ONCE() now enforces atomic read, which leads to:

  CC      mm/gup.o
In file included from ./include/linux/kernel.h:11:0,
                 from mm/gup.c:2:
In function 'gup_hugepte.constprop',
    inlined from 'gup_huge_pd.isra.79' at mm/gup.c:2465:8:
./include/linux/compiler.h:392:38: error: call to '__compiletime_assert_222' declared with attribute error: Unsupported access size for {READ,WRITE}_ONCE().
  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                                      ^
./include/linux/compiler.h:373:4: note: in definition of macro '__compiletime_assert'
    prefix ## suffix();    \
    ^
./include/linux/compiler.h:392:2: note: in expansion of macro '_compiletime_assert'
  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
  ^
./include/linux/compiler.h:405:2: note: in expansion of macro 'compiletime_assert'
  compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
  ^
./include/linux/compiler.h:291:2: note: in expansion of macro 'compiletime_assert_rwonce_type'
  compiletime_assert_rwonce_type(x);    \
  ^
mm/gup.c:2428:8: note: in expansion of macro 'READ_ONCE'
  pte = READ_ONCE(*ptep);
        ^
In function 'gup_get_pte',
    inlined from 'gup_pte_range' at mm/gup.c:2228:9,
    inlined from 'gup_pmd_range' at mm/gup.c:2613:15,
    inlined from 'gup_pud_range' at mm/gup.c:2641:15,
    inlined from 'gup_p4d_range' at mm/gup.c:2666:15,
    inlined from 'gup_pgd_range' at mm/gup.c:2694:15,
    inlined from 'internal_get_user_pages_fast' at mm/gup.c:2795:3:
./include/linux/compiler.h:392:38: error: call to '__compiletime_assert_219' declared with attribute error: Unsupported access size for {READ,WRITE}_ONCE().
  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                                      ^
./include/linux/compiler.h:373:4: note: in definition of macro '__compiletime_assert'
    prefix ## suffix();    \
    ^
./include/linux/compiler.h:392:2: note: in expansion of macro '_compiletime_assert'
  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
  ^
./include/linux/compiler.h:405:2: note: in expansion of macro 'compiletime_assert'
  compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
  ^
./include/linux/compiler.h:291:2: note: in expansion of macro 'compiletime_assert_rwonce_type'
  compiletime_assert_rwonce_type(x);    \
  ^
mm/gup.c:2199:9: note: in expansion of macro 'READ_ONCE'
  return READ_ONCE(*ptep);
         ^
make[2]: *** [mm/gup.o] Error 1

Define ptep_get() on 8xx when using 16k pages.

Fixes: 2ab3a0a02905 ("READ_ONCE: Enforce atomicity for {READ,WRITE}_ONCE() memory accesses")
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/include/asm/nohash/32/pgtable.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index b56f14160ae5..77addb599ce7 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -286,6 +286,16 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
 	return __pte(pte_update(mm, addr, ptep, ~0, 0, 0));
 }
 
+#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
+#define __HAVE_ARCH_PTEP_GET
+static inline pte_t ptep_get(pte_t *ptep)
+{
+	pte_t pte = {READ_ONCE(ptep->pte), 0, 0, 0};
+
+	return pte;
+}
+#endif
+
 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
 static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
 				      pte_t *ptep)
-- 
2.25.0



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 3/3] powerpc/8xx: Provide ptep_get() with 16k pages
  2020-06-15 12:57 ` [PATCH 3/3] powerpc/8xx: Provide ptep_get() with 16k pages Christophe Leroy
@ 2020-06-15 13:22   ` Peter Zijlstra
  2020-06-17 14:21     ` Michael Ellerman
  0 siblings, 1 reply; 16+ messages in thread
From: Peter Zijlstra @ 2020-06-15 13:22 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Will Deacon, Andrew Morton, linux-kernel, linuxppc-dev, linux-mm

On Mon, Jun 15, 2020 at 12:57:59PM +0000, Christophe Leroy wrote:
> READ_ONCE() now enforces atomic read, which leads to:


> Fixes: 2ab3a0a02905 ("READ_ONCE: Enforce atomicity for {READ,WRITE}_ONCE() memory accesses")
> Cc: Will Deacon <will@kernel.org>
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
>  arch/powerpc/include/asm/nohash/32/pgtable.h | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
> index b56f14160ae5..77addb599ce7 100644
> --- a/arch/powerpc/include/asm/nohash/32/pgtable.h
> +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
> @@ -286,6 +286,16 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
>  	return __pte(pte_update(mm, addr, ptep, ~0, 0, 0));
>  }
>  
> +#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
> +#define __HAVE_ARCH_PTEP_GET
> +static inline pte_t ptep_get(pte_t *ptep)
> +{
> +	pte_t pte = {READ_ONCE(ptep->pte), 0, 0, 0};
> +
> +	return pte;
> +}
> +#endif

Would it make sense to have a comment with this magic? The casual reader
might wonder WTH just happened when he stumbles on this :-)

Other than that, the series looks good to me, Thanks!

Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 0/3] Fix build failure with v5.8-rc1
  2020-06-15 12:57 [PATCH 0/3] Fix build failure with v5.8-rc1 Christophe Leroy
                   ` (2 preceding siblings ...)
  2020-06-15 12:57 ` [PATCH 3/3] powerpc/8xx: Provide ptep_get() with 16k pages Christophe Leroy
@ 2020-06-17 10:57 ` Will Deacon
  2020-06-17 14:13 ` Michael Ellerman
  2020-06-18 12:37 ` Michael Ellerman
  5 siblings, 0 replies; 16+ messages in thread
From: Will Deacon @ 2020-06-17 10:57 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Andrew Morton, Peter Zijlstra (Intel),
	linux-kernel, linuxppc-dev, linux-mm, arnd

[+Arnd in case he's interested in this series]

On Mon, Jun 15, 2020 at 12:57:55PM +0000, Christophe Leroy wrote:
> Commit 2ab3a0a02905 ("READ_ONCE: Enforce atomicity for
> {READ,WRITE}_ONCE() memory accesses") leads to following build
> failure on powerpc 8xx.
> 
> To fix it, this small series introduces a new helper named ptep_get()
> to replace the direct access with READ_ONCE(). This new helper
> can be overriden by architectures.

Thanks for doing this, and sorry for the breakage. For the series:

Acked-by: Will Deacon <will@kernel.org>

Hopefully we can introduce accessors for the other page-table levels too,
but that can obviously happen incrementally.

Will

> Christophe Leroy (3):
>   mm/gup: Use huge_ptep_get() in gup_hugepte()
>   mm: Allow arches to provide ptep_get()
>   powerpc/8xx: Provide ptep_get() with 16k pages
> 
>  arch/powerpc/include/asm/nohash/32/pgtable.h | 10 ++++++++++
>  include/asm-generic/hugetlb.h                |  2 +-
>  include/linux/pgtable.h                      |  7 +++++++
>  mm/gup.c                                     |  4 ++--
>  4 files changed, 20 insertions(+), 3 deletions(-)
> 
> -- 
> 2.25.0
> 


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 0/3] Fix build failure with v5.8-rc1
  2020-06-15 12:57 [PATCH 0/3] Fix build failure with v5.8-rc1 Christophe Leroy
                   ` (3 preceding siblings ...)
  2020-06-17 10:57 ` [PATCH 0/3] Fix build failure with v5.8-rc1 Will Deacon
@ 2020-06-17 14:13 ` Michael Ellerman
  2020-06-18 12:37 ` Michael Ellerman
  5 siblings, 0 replies; 16+ messages in thread
From: Michael Ellerman @ 2020-06-17 14:13 UTC (permalink / raw)
  To: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras,
	Will Deacon, Andrew Morton, Peter Zijlstra (Intel)
  Cc: linux-kernel, linuxppc-dev, linux-mm

Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> Commit 2ab3a0a02905 ("READ_ONCE: Enforce atomicity for
> {READ,WRITE}_ONCE() memory accesses") leads to following build
> failure on powerpc 8xx.

I've put this in my fixes branch.

cheers


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/3] mm/gup: Use huge_ptep_get() in gup_hugepte()
  2020-06-15 12:57 ` [PATCH 1/3] mm/gup: Use huge_ptep_get() in gup_hugepte() Christophe Leroy
@ 2020-06-17 14:14   ` Michael Ellerman
  0 siblings, 0 replies; 16+ messages in thread
From: Michael Ellerman @ 2020-06-17 14:14 UTC (permalink / raw)
  To: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras,
	Will Deacon, Andrew Morton, Peter Zijlstra (Intel)
  Cc: linux-kernel, linuxppc-dev, linux-mm

Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> gup_hugepte() reads hugepage table entries, it can't read
> them directly, huge_ptep_get() must be used.
>
> Fixes: 2ab3a0a02905 ("READ_ONCE: Enforce atomicity for {READ,WRITE}_ONCE() memory accesses")

I see that commit in older versions of linux-next but not in mainline.

In mainline it seems to be: 9e343b467c70 ("READ_ONCE: Enforce atomicity for {READ,WRITE}_ONCE() memory accesses")

I guess it got rebased somewhere along the way.

I fixed it up when applying, and the other two as well.

cheers

> Cc: Will Deacon <will@kernel.org>
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
>  mm/gup.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/mm/gup.c b/mm/gup.c
> index de9e36262ccb..761df4944ef5 100644
> --- a/mm/gup.c
> +++ b/mm/gup.c
> @@ -2425,7 +2425,7 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
>  	if (pte_end < end)
>  		end = pte_end;
>  
> -	pte = READ_ONCE(*ptep);
> +	pte = huge_ptep_get(ptep);
>  
>  	if (!pte_access_permitted(pte, flags & FOLL_WRITE))
>  		return 0;
> -- 
> 2.25.0


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 3/3] powerpc/8xx: Provide ptep_get() with 16k pages
  2020-06-15 13:22   ` Peter Zijlstra
@ 2020-06-17 14:21     ` Michael Ellerman
  2020-06-17 14:38       ` Peter Zijlstra
  0 siblings, 1 reply; 16+ messages in thread
From: Michael Ellerman @ 2020-06-17 14:21 UTC (permalink / raw)
  To: Peter Zijlstra, Christophe Leroy
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Will Deacon,
	Andrew Morton, linux-kernel, linuxppc-dev, linux-mm

Peter Zijlstra <peterz@infradead.org> writes:
> On Mon, Jun 15, 2020 at 12:57:59PM +0000, Christophe Leroy wrote:
>> READ_ONCE() now enforces atomic read, which leads to:
>
>> Fixes: 2ab3a0a02905 ("READ_ONCE: Enforce atomicity for {READ,WRITE}_ONCE() memory accesses")
>> Cc: Will Deacon <will@kernel.org>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>> ---
>>  arch/powerpc/include/asm/nohash/32/pgtable.h | 10 ++++++++++
>>  1 file changed, 10 insertions(+)
>> 
>> diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
>> index b56f14160ae5..77addb599ce7 100644
>> --- a/arch/powerpc/include/asm/nohash/32/pgtable.h
>> +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
>> @@ -286,6 +286,16 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
>>  	return __pte(pte_update(mm, addr, ptep, ~0, 0, 0));
>>  }
>>  
>> +#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
>> +#define __HAVE_ARCH_PTEP_GET
>> +static inline pte_t ptep_get(pte_t *ptep)
>> +{
>> +	pte_t pte = {READ_ONCE(ptep->pte), 0, 0, 0};
>> +
>> +	return pte;
>> +}
>> +#endif
>
> Would it make sense to have a comment with this magic? The casual reader
> might wonder WTH just happened when he stumbles on this :-)

I tried writing a helpful comment but it's too late for my brain to form
sensible sentences.

Christophe can you send a follow-up with a comment explaining it? In
particular the zero entries stand out, it's kind of subtle that those
entries are only populated with the right value when we write to the
page table.

cheers


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 3/3] powerpc/8xx: Provide ptep_get() with 16k pages
  2020-06-17 14:21     ` Michael Ellerman
@ 2020-06-17 14:38       ` Peter Zijlstra
  2020-06-17 14:45         ` Christophe Leroy
  2020-06-18  0:58         ` Michael Ellerman
  0 siblings, 2 replies; 16+ messages in thread
From: Peter Zijlstra @ 2020-06-17 14:38 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras,
	Will Deacon, Andrew Morton, linux-kernel, linuxppc-dev, linux-mm

On Thu, Jun 18, 2020 at 12:21:22AM +1000, Michael Ellerman wrote:
> Peter Zijlstra <peterz@infradead.org> writes:
> > On Mon, Jun 15, 2020 at 12:57:59PM +0000, Christophe Leroy wrote:

> >> +#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
> >> +#define __HAVE_ARCH_PTEP_GET
> >> +static inline pte_t ptep_get(pte_t *ptep)
> >> +{
> >> +	pte_t pte = {READ_ONCE(ptep->pte), 0, 0, 0};
> >> +
> >> +	return pte;
> >> +}
> >> +#endif
> >
> > Would it make sense to have a comment with this magic? The casual reader
> > might wonder WTH just happened when he stumbles on this :-)
> 
> I tried writing a helpful comment but it's too late for my brain to form
> sensible sentences.
> 
> Christophe can you send a follow-up with a comment explaining it? In
> particular the zero entries stand out, it's kind of subtle that those
> entries are only populated with the right value when we write to the
> page table.

static inline pte_t ptep_get(pte_t *ptep)
{
	unsigned long val = READ_ONCE(ptep->pte);
	/* 16K pages have 4 identical value 4K entries */
	pte_t pte = {val, val, val, val);
	return pte;
}

Maybe something like that?


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 3/3] powerpc/8xx: Provide ptep_get() with 16k pages
  2020-06-17 14:38       ` Peter Zijlstra
@ 2020-06-17 14:45         ` Christophe Leroy
  2020-06-18  1:00           ` Michael Ellerman
  2020-06-18  0:58         ` Michael Ellerman
  1 sibling, 1 reply; 16+ messages in thread
From: Christophe Leroy @ 2020-06-17 14:45 UTC (permalink / raw)
  To: Peter Zijlstra, Michael Ellerman
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Will Deacon,
	Andrew Morton, linux-kernel, linuxppc-dev, linux-mm



Le 17/06/2020 à 16:38, Peter Zijlstra a écrit :
> On Thu, Jun 18, 2020 at 12:21:22AM +1000, Michael Ellerman wrote:
>> Peter Zijlstra <peterz@infradead.org> writes:
>>> On Mon, Jun 15, 2020 at 12:57:59PM +0000, Christophe Leroy wrote:
> 
>>>> +#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
>>>> +#define __HAVE_ARCH_PTEP_GET
>>>> +static inline pte_t ptep_get(pte_t *ptep)
>>>> +{
>>>> +	pte_t pte = {READ_ONCE(ptep->pte), 0, 0, 0};
>>>> +
>>>> +	return pte;
>>>> +}
>>>> +#endif
>>>
>>> Would it make sense to have a comment with this magic? The casual reader
>>> might wonder WTH just happened when he stumbles on this :-)
>>
>> I tried writing a helpful comment but it's too late for my brain to form
>> sensible sentences.
>>
>> Christophe can you send a follow-up with a comment explaining it? In
>> particular the zero entries stand out, it's kind of subtle that those
>> entries are only populated with the right value when we write to the
>> page table.
> 
> static inline pte_t ptep_get(pte_t *ptep)
> {
> 	unsigned long val = READ_ONCE(ptep->pte);
> 	/* 16K pages have 4 identical value 4K entries */
> 	pte_t pte = {val, val, val, val);
> 	return pte;
> }
> 
> Maybe something like that?
> 

This should work as well. Indeed nobody cares about what's in the other 
three. They are only there to ensure that ptep++ increases the ptep 
pointer by 16 bytes. Only the HW require 4 identical values, that's 
taken care of in set_pte_at() and pte_update().
So we should use the most efficient. Thinking once more, maybe what you 
propose is the most efficient as there is no need to load another 
register with value 0 in order to write it in the stack.

Christophe


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 3/3] powerpc/8xx: Provide ptep_get() with 16k pages
  2020-06-17 14:38       ` Peter Zijlstra
  2020-06-17 14:45         ` Christophe Leroy
@ 2020-06-18  0:58         ` Michael Ellerman
  2020-06-18 14:21           ` Christophe Leroy
  1 sibling, 1 reply; 16+ messages in thread
From: Michael Ellerman @ 2020-06-18  0:58 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras,
	Will Deacon, Andrew Morton, linux-kernel, linuxppc-dev, linux-mm

Peter Zijlstra <peterz@infradead.org> writes:
> On Thu, Jun 18, 2020 at 12:21:22AM +1000, Michael Ellerman wrote:
>> Peter Zijlstra <peterz@infradead.org> writes:
>> > On Mon, Jun 15, 2020 at 12:57:59PM +0000, Christophe Leroy wrote:
>
>> >> +#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
>> >> +#define __HAVE_ARCH_PTEP_GET
>> >> +static inline pte_t ptep_get(pte_t *ptep)
>> >> +{
>> >> +	pte_t pte = {READ_ONCE(ptep->pte), 0, 0, 0};
>> >> +
>> >> +	return pte;
>> >> +}
>> >> +#endif
>> >
>> > Would it make sense to have a comment with this magic? The casual reader
>> > might wonder WTH just happened when he stumbles on this :-)
>> 
>> I tried writing a helpful comment but it's too late for my brain to form
>> sensible sentences.
>> 
>> Christophe can you send a follow-up with a comment explaining it? In
>> particular the zero entries stand out, it's kind of subtle that those
>> entries are only populated with the right value when we write to the
>> page table.
>
> static inline pte_t ptep_get(pte_t *ptep)
> {
> 	unsigned long val = READ_ONCE(ptep->pte);
> 	/* 16K pages have 4 identical value 4K entries */
> 	pte_t pte = {val, val, val, val);
> 	return pte;
> }
>
> Maybe something like that?

I think val wants to be pte_basic_t, but otherwise yeah I like that much
better.

cheers


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 3/3] powerpc/8xx: Provide ptep_get() with 16k pages
  2020-06-17 14:45         ` Christophe Leroy
@ 2020-06-18  1:00           ` Michael Ellerman
  2020-06-18 14:19             ` Christophe Leroy
  0 siblings, 1 reply; 16+ messages in thread
From: Michael Ellerman @ 2020-06-18  1:00 UTC (permalink / raw)
  To: Christophe Leroy, Peter Zijlstra
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Will Deacon,
	Andrew Morton, linux-kernel, linuxppc-dev, linux-mm

Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> Le 17/06/2020 à 16:38, Peter Zijlstra a écrit :
>> On Thu, Jun 18, 2020 at 12:21:22AM +1000, Michael Ellerman wrote:
>>> Peter Zijlstra <peterz@infradead.org> writes:
>>>> On Mon, Jun 15, 2020 at 12:57:59PM +0000, Christophe Leroy wrote:
>> 
>>>>> +#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
>>>>> +#define __HAVE_ARCH_PTEP_GET
>>>>> +static inline pte_t ptep_get(pte_t *ptep)
>>>>> +{
>>>>> +	pte_t pte = {READ_ONCE(ptep->pte), 0, 0, 0};
>>>>> +
>>>>> +	return pte;
>>>>> +}
>>>>> +#endif
>>>>
>>>> Would it make sense to have a comment with this magic? The casual reader
>>>> might wonder WTH just happened when he stumbles on this :-)
>>>
>>> I tried writing a helpful comment but it's too late for my brain to form
>>> sensible sentences.
>>>
>>> Christophe can you send a follow-up with a comment explaining it? In
>>> particular the zero entries stand out, it's kind of subtle that those
>>> entries are only populated with the right value when we write to the
>>> page table.
>> 
>> static inline pte_t ptep_get(pte_t *ptep)
>> {
>> 	unsigned long val = READ_ONCE(ptep->pte);
>> 	/* 16K pages have 4 identical value 4K entries */
>> 	pte_t pte = {val, val, val, val);
>> 	return pte;
>> }
>> 
>> Maybe something like that?
>
> This should work as well. Indeed nobody cares about what's in the other 
> three. They are only there to ensure that ptep++ increases the ptep 
> pointer by 16 bytes. Only the HW require 4 identical values, that's 
> taken care of in set_pte_at() and pte_update().

Right, but it seems less error-prone to have the in-memory
representation match what we have in the page table (well that's
in-memory too but you know what I mean).

> So we should use the most efficient. Thinking once more, maybe what you 
> propose is the most efficient as there is no need to load another 
> register with value 0 in order to write it in the stack.

On 64-bit I'd say it makes zero difference, the only thing that's going
to matter is the load from ptep->pte. I don't know whether that's true
on the 8xx cores though.

cheers


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 0/3] Fix build failure with v5.8-rc1
  2020-06-15 12:57 [PATCH 0/3] Fix build failure with v5.8-rc1 Christophe Leroy
                   ` (4 preceding siblings ...)
  2020-06-17 14:13 ` Michael Ellerman
@ 2020-06-18 12:37 ` Michael Ellerman
  5 siblings, 0 replies; 16+ messages in thread
From: Michael Ellerman @ 2020-06-18 12:37 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Christophe Leroy,
	Michael Ellerman, Peter Zijlstra (Intel),
	Will Deacon, Andrew Morton
  Cc: linuxppc-dev, linux-kernel, linux-mm

On Mon, 15 Jun 2020 12:57:55 +0000 (UTC), Christophe Leroy wrote:
> Commit 2ab3a0a02905 ("READ_ONCE: Enforce atomicity for
> {READ,WRITE}_ONCE() memory accesses") leads to following build
> failure on powerpc 8xx.
> 
> To fix it, this small series introduces a new helper named ptep_get()
> to replace the direct access with READ_ONCE(). This new helper
> can be overriden by architectures.
> 
> [...]

Applied to powerpc/fixes.

[1/3] mm/gup: Use huge_ptep_get() in gup_hugepte()
      https://git.kernel.org/powerpc/c/01a80ec6495f9e43f61b3231f3b283ca050a800e
[2/3] mm: Allow arches to provide ptep_get()
      https://git.kernel.org/powerpc/c/f7583fd6bdcc4d0b43f68fb81ebfae9669ee9338
[3/3] powerpc/8xx: Provide ptep_get() with 16k pages
      https://git.kernel.org/powerpc/c/b55129f97aeefd265314e12d98935330e011a14a

cheers


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 3/3] powerpc/8xx: Provide ptep_get() with 16k pages
  2020-06-18  1:00           ` Michael Ellerman
@ 2020-06-18 14:19             ` Christophe Leroy
  0 siblings, 0 replies; 16+ messages in thread
From: Christophe Leroy @ 2020-06-18 14:19 UTC (permalink / raw)
  To: Michael Ellerman, Peter Zijlstra
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Will Deacon,
	Andrew Morton, linux-kernel, linuxppc-dev, linux-mm



Le 18/06/2020 à 03:00, Michael Ellerman a écrit :
> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>> Le 17/06/2020 à 16:38, Peter Zijlstra a écrit :
>>> On Thu, Jun 18, 2020 at 12:21:22AM +1000, Michael Ellerman wrote:
>>>> Peter Zijlstra <peterz@infradead.org> writes:
>>>>> On Mon, Jun 15, 2020 at 12:57:59PM +0000, Christophe Leroy wrote:
>>>
>>>>>> +#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
>>>>>> +#define __HAVE_ARCH_PTEP_GET
>>>>>> +static inline pte_t ptep_get(pte_t *ptep)
>>>>>> +{
>>>>>> +	pte_t pte = {READ_ONCE(ptep->pte), 0, 0, 0};
>>>>>> +
>>>>>> +	return pte;
>>>>>> +}
>>>>>> +#endif
>>>>>
>>>>> Would it make sense to have a comment with this magic? The casual reader
>>>>> might wonder WTH just happened when he stumbles on this :-)
>>>>
>>>> I tried writing a helpful comment but it's too late for my brain to form
>>>> sensible sentences.
>>>>
>>>> Christophe can you send a follow-up with a comment explaining it? In
>>>> particular the zero entries stand out, it's kind of subtle that those
>>>> entries are only populated with the right value when we write to the
>>>> page table.
>>>
>>> static inline pte_t ptep_get(pte_t *ptep)
>>> {
>>> 	unsigned long val = READ_ONCE(ptep->pte);
>>> 	/* 16K pages have 4 identical value 4K entries */
>>> 	pte_t pte = {val, val, val, val);
>>> 	return pte;
>>> }
>>>
>>> Maybe something like that?
>>
>> This should work as well. Indeed nobody cares about what's in the other
>> three. They are only there to ensure that ptep++ increases the ptep
>> pointer by 16 bytes. Only the HW require 4 identical values, that's
>> taken care of in set_pte_at() and pte_update().
> 
> Right, but it seems less error-prone to have the in-memory
> representation match what we have in the page table (well that's
> in-memory too but you know what I mean).
> 
>> So we should use the most efficient. Thinking once more, maybe what you
>> propose is the most efficient as there is no need to load another
>> register with value 0 in order to write it in the stack.
> 
> On 64-bit I'd say it makes zero difference, the only thing that's going
> to matter is the load from ptep->pte. I don't know whether that's true
> on the 8xx cores though.

On 8xx core, loading a register with value 0 will take one cycle unless 
there is some bubble left by another instruction (like a load from 
memory or a taken branch). But that's in the noise.

Christophe


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 3/3] powerpc/8xx: Provide ptep_get() with 16k pages
  2020-06-18  0:58         ` Michael Ellerman
@ 2020-06-18 14:21           ` Christophe Leroy
  0 siblings, 0 replies; 16+ messages in thread
From: Christophe Leroy @ 2020-06-18 14:21 UTC (permalink / raw)
  To: Michael Ellerman, Peter Zijlstra
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Will Deacon,
	Andrew Morton, linux-kernel, linuxppc-dev, linux-mm



Le 18/06/2020 à 02:58, Michael Ellerman a écrit :
> Peter Zijlstra <peterz@infradead.org> writes:
>> On Thu, Jun 18, 2020 at 12:21:22AM +1000, Michael Ellerman wrote:
>>> Peter Zijlstra <peterz@infradead.org> writes:
>>>> On Mon, Jun 15, 2020 at 12:57:59PM +0000, Christophe Leroy wrote:
>>
>>>>> +#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
>>>>> +#define __HAVE_ARCH_PTEP_GET
>>>>> +static inline pte_t ptep_get(pte_t *ptep)
>>>>> +{
>>>>> +	pte_t pte = {READ_ONCE(ptep->pte), 0, 0, 0};
>>>>> +
>>>>> +	return pte;
>>>>> +}
>>>>> +#endif
>>>>
>>>> Would it make sense to have a comment with this magic? The casual reader
>>>> might wonder WTH just happened when he stumbles on this :-)
>>>
>>> I tried writing a helpful comment but it's too late for my brain to form
>>> sensible sentences.
>>>
>>> Christophe can you send a follow-up with a comment explaining it? In
>>> particular the zero entries stand out, it's kind of subtle that those
>>> entries are only populated with the right value when we write to the
>>> page table.
>>
>> static inline pte_t ptep_get(pte_t *ptep)
>> {
>> 	unsigned long val = READ_ONCE(ptep->pte);
>> 	/* 16K pages have 4 identical value 4K entries */
>> 	pte_t pte = {val, val, val, val);
>> 	return pte;
>> }
>>
>> Maybe something like that?
> 
> I think val wants to be pte_basic_t, but otherwise yeah I like that much
> better.
> 

I sent a patch for that.

I'll also send one to fix mm/debug_vm_pgtable.c which also uses 
READ_ONCE() to access page table entries.

Christophe


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2020-06-18 14:23 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-15 12:57 [PATCH 0/3] Fix build failure with v5.8-rc1 Christophe Leroy
2020-06-15 12:57 ` [PATCH 1/3] mm/gup: Use huge_ptep_get() in gup_hugepte() Christophe Leroy
2020-06-17 14:14   ` Michael Ellerman
2020-06-15 12:57 ` [PATCH 2/3] mm: Allow arches to provide ptep_get() Christophe Leroy
2020-06-15 12:57 ` [PATCH 3/3] powerpc/8xx: Provide ptep_get() with 16k pages Christophe Leroy
2020-06-15 13:22   ` Peter Zijlstra
2020-06-17 14:21     ` Michael Ellerman
2020-06-17 14:38       ` Peter Zijlstra
2020-06-17 14:45         ` Christophe Leroy
2020-06-18  1:00           ` Michael Ellerman
2020-06-18 14:19             ` Christophe Leroy
2020-06-18  0:58         ` Michael Ellerman
2020-06-18 14:21           ` Christophe Leroy
2020-06-17 10:57 ` [PATCH 0/3] Fix build failure with v5.8-rc1 Will Deacon
2020-06-17 14:13 ` Michael Ellerman
2020-06-18 12:37 ` Michael Ellerman

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).