All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mm/debug_vm_pgtable: Ensure THP availability via has_transparent_hugepage()
@ 2021-05-18  8:13 Anshuman Khandual
  2021-05-18  8:50 ` Christophe Leroy
  0 siblings, 1 reply; 3+ messages in thread
From: Anshuman Khandual @ 2021-05-18  8:13 UTC (permalink / raw)
  To: linux-mm, akpm
  Cc: Anshuman Khandual, Aneesh Kumar K . V, Christophe Leroy, linux-kernel

On certain platforms, THP support could not just be validated via the build
option CONFIG_TRANSPARENT_HUGEPAGE. Instead has_transparent_hugepage() also
needs to be called upon to verify THP runtime support. Otherwise the debug
test might just run into unusable THP helpers like in the case of a 4K hash
config on powerpc platform [1]. This just moves all pfn_pmd() and pfn_pud()
after THP runtime validation with has_transparent_hugepage() which prevents
the mentioned problem.

[1] https://bugzilla.kernel.org/show_bug.cgi?id=213069

Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-mm@kvack.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
This applies on v5.13-rc2 after the following patches.

[1] https://lore.kernel.org/linux-mm/20210419071820.750217-1-liushixin2@huawei.com/
[2] https://lore.kernel.org/linux-mm/20210419071820.750217-2-liushixin2@huawei.com/

 mm/debug_vm_pgtable.c | 58 +++++++++++++++++++++++++++++++++++--------
 1 file changed, 48 insertions(+), 10 deletions(-)

diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c
index e2f35db8ba69..6ff92c8b0a00 100644
--- a/mm/debug_vm_pgtable.c
+++ b/mm/debug_vm_pgtable.c
@@ -146,13 +146,14 @@ static void __init pte_savedwrite_tests(unsigned long pfn, pgprot_t prot)
 static void __init pmd_basic_tests(unsigned long pfn, int idx)
 {
 	pgprot_t prot = protection_map[idx];
-	pmd_t pmd = pfn_pmd(pfn, prot);
 	unsigned long val = idx, *ptr = &val;
+	pmd_t pmd;
 
 	if (!has_transparent_hugepage())
 		return;
 
 	pr_debug("Validating PMD basic (%pGv)\n", ptr);
+	pmd = pfn_pmd(pfn, prot);
 
 	/*
 	 * This test needs to be executed after the given page table entry
@@ -232,9 +233,14 @@ static void __init pmd_advanced_tests(struct mm_struct *mm,
 
 static void __init pmd_leaf_tests(unsigned long pfn, pgprot_t prot)
 {
-	pmd_t pmd = pfn_pmd(pfn, prot);
+	pmd_t pmd;
+
+	if (!has_transparent_hugepage())
+		return;
 
 	pr_debug("Validating PMD leaf\n");
+	pmd = pfn_pmd(pfn, prot);
+
 	/*
 	 * PMD based THP is a leaf entry.
 	 */
@@ -244,12 +250,16 @@ static void __init pmd_leaf_tests(unsigned long pfn, pgprot_t prot)
 
 static void __init pmd_savedwrite_tests(unsigned long pfn, pgprot_t prot)
 {
-	pmd_t pmd = pfn_pmd(pfn, prot);
+	pmd_t pmd;
 
 	if (!IS_ENABLED(CONFIG_NUMA_BALANCING))
 		return;
 
+	if (!has_transparent_hugepage())
+		return;
+
 	pr_debug("Validating PMD saved write\n");
+	pmd = pfn_pmd(pfn, prot);
 	WARN_ON(!pmd_savedwrite(pmd_mk_savedwrite(pmd_clear_savedwrite(pmd))));
 	WARN_ON(pmd_savedwrite(pmd_clear_savedwrite(pmd_mk_savedwrite(pmd))));
 }
@@ -258,13 +268,14 @@ static void __init pmd_savedwrite_tests(unsigned long pfn, pgprot_t prot)
 static void __init pud_basic_tests(struct mm_struct *mm, unsigned long pfn, int idx)
 {
 	pgprot_t prot = protection_map[idx];
-	pud_t pud = pfn_pud(pfn, prot);
 	unsigned long val = idx, *ptr = &val;
+	pud_t pud;
 
 	if (!has_transparent_hugepage())
 		return;
 
 	pr_debug("Validating PUD basic (%pGv)\n", ptr);
+	pud = pfn_pud(pfn, prot);
 
 	/*
 	 * This test needs to be executed after the given page table entry
@@ -348,9 +359,13 @@ static void __init pud_advanced_tests(struct mm_struct *mm,
 
 static void __init pud_leaf_tests(unsigned long pfn, pgprot_t prot)
 {
-	pud_t pud = pfn_pud(pfn, prot);
+	pud_t pud;
+
+	if (!has_transparent_hugepage())
+		return;
 
 	pr_debug("Validating PUD leaf\n");
+	pud = pfn_pud(pfn, prot);
 	/*
 	 * PUD based THP is a leaf entry.
 	 */
@@ -642,12 +657,16 @@ static void __init pte_protnone_tests(unsigned long pfn, pgprot_t prot)
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 static void __init pmd_protnone_tests(unsigned long pfn, pgprot_t prot)
 {
-	pmd_t pmd = pmd_mkhuge(pfn_pmd(pfn, prot));
+	pmd_t pmd;
 
 	if (!IS_ENABLED(CONFIG_NUMA_BALANCING))
 		return;
 
+	if (!has_transparent_hugepage())
+		return;
+
 	pr_debug("Validating PMD protnone\n");
+	pmd = pmd_mkhuge(pfn_pmd(pfn, prot));
 	WARN_ON(!pmd_protnone(pmd));
 	WARN_ON(!pmd_present(pmd));
 }
@@ -667,18 +686,26 @@ static void __init pte_devmap_tests(unsigned long pfn, pgprot_t prot)
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 static void __init pmd_devmap_tests(unsigned long pfn, pgprot_t prot)
 {
-	pmd_t pmd = pfn_pmd(pfn, prot);
+	pmd_t pmd;
+
+	if (!has_transparent_hugepage())
+		return;
 
 	pr_debug("Validating PMD devmap\n");
+	pmd = pfn_pmd(pfn, prot);
 	WARN_ON(!pmd_devmap(pmd_mkdevmap(pmd)));
 }
 
 #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
 static void __init pud_devmap_tests(unsigned long pfn, pgprot_t prot)
 {
-	pud_t pud = pfn_pud(pfn, prot);
+	pud_t pud;
+
+	if (!has_transparent_hugepage())
+		return;
 
 	pr_debug("Validating PUD devmap\n");
+	pud = pfn_pud(pfn, prot);
 	WARN_ON(!pud_devmap(pud_mkdevmap(pud)));
 }
 #else  /* !CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD */
@@ -721,25 +748,33 @@ static void __init pte_swap_soft_dirty_tests(unsigned long pfn, pgprot_t prot)
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 static void __init pmd_soft_dirty_tests(unsigned long pfn, pgprot_t prot)
 {
-	pmd_t pmd = pfn_pmd(pfn, prot);
+	pmd_t pmd;
 
 	if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY))
 		return;
 
+	if (!has_transparent_hugepage())
+		return;
+
 	pr_debug("Validating PMD soft dirty\n");
+	pmd = pfn_pmd(pfn, prot);
 	WARN_ON(!pmd_soft_dirty(pmd_mksoft_dirty(pmd)));
 	WARN_ON(pmd_soft_dirty(pmd_clear_soft_dirty(pmd)));
 }
 
 static void __init pmd_swap_soft_dirty_tests(unsigned long pfn, pgprot_t prot)
 {
-	pmd_t pmd = pfn_pmd(pfn, prot);
+	pmd_t pmd;
 
 	if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) ||
 		!IS_ENABLED(CONFIG_ARCH_ENABLE_THP_MIGRATION))
 		return;
 
+	if (!has_transparent_hugepage())
+		return;
+
 	pr_debug("Validating PMD swap soft dirty\n");
+	pmd = pfn_pmd(pfn, prot);
 	WARN_ON(!pmd_swp_soft_dirty(pmd_swp_mksoft_dirty(pmd)));
 	WARN_ON(pmd_swp_soft_dirty(pmd_swp_clear_soft_dirty(pmd)));
 }
@@ -768,6 +803,9 @@ static void __init pmd_swap_tests(unsigned long pfn, pgprot_t prot)
 	swp_entry_t swp;
 	pmd_t pmd;
 
+	if (!has_transparent_hugepage())
+		return;
+
 	pr_debug("Validating PMD swap\n");
 	pmd = pfn_pmd(pfn, prot);
 	swp = __pmd_to_swp_entry(pmd);
-- 
2.20.1


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

* Re: [PATCH] mm/debug_vm_pgtable: Ensure THP availability via has_transparent_hugepage()
  2021-05-18  8:13 [PATCH] mm/debug_vm_pgtable: Ensure THP availability via has_transparent_hugepage() Anshuman Khandual
@ 2021-05-18  8:50 ` Christophe Leroy
  2021-05-18 10:07   ` Anshuman Khandual
  0 siblings, 1 reply; 3+ messages in thread
From: Christophe Leroy @ 2021-05-18  8:50 UTC (permalink / raw)
  To: Anshuman Khandual, linux-mm, akpm; +Cc: Aneesh Kumar K . V, linux-kernel



Le 18/05/2021 à 10:13, Anshuman Khandual a écrit :
> On certain platforms, THP support could not just be validated via the build
> option CONFIG_TRANSPARENT_HUGEPAGE. Instead has_transparent_hugepage() also
> needs to be called upon to verify THP runtime support. Otherwise the debug
> test might just run into unusable THP helpers like in the case of a 4K hash

s/might/will/

> config on powerpc platform [1]. This just moves all pfn_pmd() and pfn_pud()
> after THP runtime validation with has_transparent_hugepage() which prevents
> the mentioned problem.
> 
> [1] https://bugzilla.kernel.org/show_bug.cgi?id=213069
> 
> Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
> Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: linux-mm@kvack.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>

There should be a Fixes:  tag

> ---
> This applies on v5.13-rc2 after the following patches.
> 
> [1] https://lore.kernel.org/linux-mm/20210419071820.750217-1-liushixin2@huawei.com/
> [2] https://lore.kernel.org/linux-mm/20210419071820.750217-2-liushixin2@huawei.com/

I can't see any fixes: tag in those patches, and their subject line even targets them to -next. Are 
they meant to go to 5.13 and stable ?

If not, how do you coordinate between your patch that must go in 5.13 and in stable, and those two 
patches ? Shouldn't your patch go first and those other patches be rebased on top ?

> 
>   mm/debug_vm_pgtable.c | 58 +++++++++++++++++++++++++++++++++++--------
>   1 file changed, 48 insertions(+), 10 deletions(-)
> 
> diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c
> index e2f35db8ba69..6ff92c8b0a00 100644
> --- a/mm/debug_vm_pgtable.c
> +++ b/mm/debug_vm_pgtable.c
> @@ -146,13 +146,14 @@ static void __init pte_savedwrite_tests(unsigned long pfn, pgprot_t prot)
>   static void __init pmd_basic_tests(unsigned long pfn, int idx)
>   {
>   	pgprot_t prot = protection_map[idx];
> -	pmd_t pmd = pfn_pmd(pfn, prot);
>   	unsigned long val = idx, *ptr = &val;
> +	pmd_t pmd;
>   
>   	if (!has_transparent_hugepage())
>   		return;
>   
>   	pr_debug("Validating PMD basic (%pGv)\n", ptr);
> +	pmd = pfn_pmd(pfn, prot);
>   
>   	/*
>   	 * This test needs to be executed after the given page table entry
> @@ -232,9 +233,14 @@ static void __init pmd_advanced_tests(struct mm_struct *mm,
>   
>   static void __init pmd_leaf_tests(unsigned long pfn, pgprot_t prot)
>   {
> -	pmd_t pmd = pfn_pmd(pfn, prot);
> +	pmd_t pmd;
> +
> +	if (!has_transparent_hugepage())
> +		return;
>   
>   	pr_debug("Validating PMD leaf\n");
> +	pmd = pfn_pmd(pfn, prot);
> +
>   	/*
>   	 * PMD based THP is a leaf entry.
>   	 */
> @@ -244,12 +250,16 @@ static void __init pmd_leaf_tests(unsigned long pfn, pgprot_t prot)
>   
>   static void __init pmd_savedwrite_tests(unsigned long pfn, pgprot_t prot)
>   {
> -	pmd_t pmd = pfn_pmd(pfn, prot);
> +	pmd_t pmd;
>   
>   	if (!IS_ENABLED(CONFIG_NUMA_BALANCING))
>   		return;
>   
> +	if (!has_transparent_hugepage())
> +		return;
> +
>   	pr_debug("Validating PMD saved write\n");
> +	pmd = pfn_pmd(pfn, prot);
>   	WARN_ON(!pmd_savedwrite(pmd_mk_savedwrite(pmd_clear_savedwrite(pmd))));
>   	WARN_ON(pmd_savedwrite(pmd_clear_savedwrite(pmd_mk_savedwrite(pmd))));
>   }
> @@ -258,13 +268,14 @@ static void __init pmd_savedwrite_tests(unsigned long pfn, pgprot_t prot)
>   static void __init pud_basic_tests(struct mm_struct *mm, unsigned long pfn, int idx)
>   {
>   	pgprot_t prot = protection_map[idx];
> -	pud_t pud = pfn_pud(pfn, prot);
>   	unsigned long val = idx, *ptr = &val;
> +	pud_t pud;
>   
>   	if (!has_transparent_hugepage())
>   		return;
>   
>   	pr_debug("Validating PUD basic (%pGv)\n", ptr);
> +	pud = pfn_pud(pfn, prot);
>   
>   	/*
>   	 * This test needs to be executed after the given page table entry
> @@ -348,9 +359,13 @@ static void __init pud_advanced_tests(struct mm_struct *mm,
>   
>   static void __init pud_leaf_tests(unsigned long pfn, pgprot_t prot)
>   {
> -	pud_t pud = pfn_pud(pfn, prot);
> +	pud_t pud;
> +
> +	if (!has_transparent_hugepage())
> +		return;
>   
>   	pr_debug("Validating PUD leaf\n");
> +	pud = pfn_pud(pfn, prot);
>   	/*
>   	 * PUD based THP is a leaf entry.
>   	 */
> @@ -642,12 +657,16 @@ static void __init pte_protnone_tests(unsigned long pfn, pgprot_t prot)
>   #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>   static void __init pmd_protnone_tests(unsigned long pfn, pgprot_t prot)
>   {
> -	pmd_t pmd = pmd_mkhuge(pfn_pmd(pfn, prot));
> +	pmd_t pmd;
>   
>   	if (!IS_ENABLED(CONFIG_NUMA_BALANCING))
>   		return;
>   
> +	if (!has_transparent_hugepage())
> +		return;
> +
>   	pr_debug("Validating PMD protnone\n");
> +	pmd = pmd_mkhuge(pfn_pmd(pfn, prot));
>   	WARN_ON(!pmd_protnone(pmd));
>   	WARN_ON(!pmd_present(pmd));
>   }
> @@ -667,18 +686,26 @@ static void __init pte_devmap_tests(unsigned long pfn, pgprot_t prot)
>   #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>   static void __init pmd_devmap_tests(unsigned long pfn, pgprot_t prot)
>   {
> -	pmd_t pmd = pfn_pmd(pfn, prot);
> +	pmd_t pmd;
> +
> +	if (!has_transparent_hugepage())
> +		return;
>   
>   	pr_debug("Validating PMD devmap\n");
> +	pmd = pfn_pmd(pfn, prot);
>   	WARN_ON(!pmd_devmap(pmd_mkdevmap(pmd)));
>   }
>   
>   #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
>   static void __init pud_devmap_tests(unsigned long pfn, pgprot_t prot)
>   {
> -	pud_t pud = pfn_pud(pfn, prot);
> +	pud_t pud;
> +
> +	if (!has_transparent_hugepage())
> +		return;
>   
>   	pr_debug("Validating PUD devmap\n");
> +	pud = pfn_pud(pfn, prot);
>   	WARN_ON(!pud_devmap(pud_mkdevmap(pud)));
>   }
>   #else  /* !CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD */
> @@ -721,25 +748,33 @@ static void __init pte_swap_soft_dirty_tests(unsigned long pfn, pgprot_t prot)
>   #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>   static void __init pmd_soft_dirty_tests(unsigned long pfn, pgprot_t prot)
>   {
> -	pmd_t pmd = pfn_pmd(pfn, prot);
> +	pmd_t pmd;
>   
>   	if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY))
>   		return;
>   
> +	if (!has_transparent_hugepage())
> +		return;
> +
>   	pr_debug("Validating PMD soft dirty\n");
> +	pmd = pfn_pmd(pfn, prot);
>   	WARN_ON(!pmd_soft_dirty(pmd_mksoft_dirty(pmd)));
>   	WARN_ON(pmd_soft_dirty(pmd_clear_soft_dirty(pmd)));
>   }
>   
>   static void __init pmd_swap_soft_dirty_tests(unsigned long pfn, pgprot_t prot)
>   {
> -	pmd_t pmd = pfn_pmd(pfn, prot);
> +	pmd_t pmd;
>   
>   	if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) ||
>   		!IS_ENABLED(CONFIG_ARCH_ENABLE_THP_MIGRATION))
>   		return;
>   
> +	if (!has_transparent_hugepage())
> +		return;
> +
>   	pr_debug("Validating PMD swap soft dirty\n");
> +	pmd = pfn_pmd(pfn, prot);
>   	WARN_ON(!pmd_swp_soft_dirty(pmd_swp_mksoft_dirty(pmd)));
>   	WARN_ON(pmd_swp_soft_dirty(pmd_swp_clear_soft_dirty(pmd)));
>   }
> @@ -768,6 +803,9 @@ static void __init pmd_swap_tests(unsigned long pfn, pgprot_t prot)
>   	swp_entry_t swp;
>   	pmd_t pmd;
>   
> +	if (!has_transparent_hugepage())
> +		return;
> +
>   	pr_debug("Validating PMD swap\n");
>   	pmd = pfn_pmd(pfn, prot);
>   	swp = __pmd_to_swp_entry(pmd);
> 

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

* Re: [PATCH] mm/debug_vm_pgtable: Ensure THP availability via has_transparent_hugepage()
  2021-05-18  8:50 ` Christophe Leroy
@ 2021-05-18 10:07   ` Anshuman Khandual
  0 siblings, 0 replies; 3+ messages in thread
From: Anshuman Khandual @ 2021-05-18 10:07 UTC (permalink / raw)
  To: Christophe Leroy, linux-mm, akpm; +Cc: Aneesh Kumar K . V, linux-kernel



On 5/18/21 2:20 PM, Christophe Leroy wrote:
> 
> 
> Le 18/05/2021 à 10:13, Anshuman Khandual a écrit :
>> On certain platforms, THP support could not just be validated via the build
>> option CONFIG_TRANSPARENT_HUGEPAGE. Instead has_transparent_hugepage() also
>> needs to be called upon to verify THP runtime support. Otherwise the debug
>> test might just run into unusable THP helpers like in the case of a 4K hash
> 
> s/might/will/

Sure, will replace.

> 
>> config on powerpc platform [1]. This just moves all pfn_pmd() and pfn_pud()
>> after THP runtime validation with has_transparent_hugepage() which prevents
>> the mentioned problem.
>>
>> [1] https://bugzilla.kernel.org/show_bug.cgi?id=213069
>>
>> Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
>> Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
>> Cc: Andrew Morton <akpm@linux-foundation.org>
>> Cc: linux-mm@kvack.org
>> Cc: linux-kernel@vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> 
> There should be a Fixes:  tag

Considering pmd_basic_tests() as the earliest test which is being
impacted here, this actually fixes an earlier fix which tried the
very same thing but was probably not complete. But it also applies
to portions of advanced tests which came later on as well, which
should have taken this problem into account.

Fixes: 787d563b8642 ("mm/debug_vm_pgtable: fix kernel crash by checking for THP support")

> 
>> ---
>> This applies on v5.13-rc2 after the following patches.
>>
>> [1] https://lore.kernel.org/linux-mm/20210419071820.750217-1-liushixin2@huawei.com/
>> [2] https://lore.kernel.org/linux-mm/20210419071820.750217-2-liushixin2@huawei.com/
> 
> I can't see any fixes: tag in those patches, and their subject line even targets them to -next. Are they meant to go to 5.13 and stable ?
> 
> If not, how do you coordinate between your patch that must go in 5.13 and in stable, and those two patches ? Shouldn't your patch go first and those other patches be rebased on top ?

Right, will rebase this patch on v5.13-rc2 directly without those two
patches. Hence this can be merged in v5.13 and backported to stable
if required.

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

end of thread, other threads:[~2021-05-18 10:06 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-18  8:13 [PATCH] mm/debug_vm_pgtable: Ensure THP availability via has_transparent_hugepage() Anshuman Khandual
2021-05-18  8:50 ` Christophe Leroy
2021-05-18 10:07   ` Anshuman Khandual

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.