Message ID | 20240327152332.950956-6-peterx@redhat.com (mailing list archive) |
---|---|
State | Handled Elsewhere |
Headers | show |
Series | mm/gup: Unify hugetlb, part 2 | expand |
Context | Check | Description |
---|---|---|
conchuod/vmtest-fixes-PR | fail | merge-conflict |
Hi Peter (and LoongArch folks), On Wed, Mar 27, 2024 at 11:23:24AM -0400, peterx@redhat.com wrote: > From: Peter Xu <peterx@redhat.com> > > The comment in the code explains the reasons. We took a different approach > comparing to pmd_pfn() by providing a fallback function. > > Another option is to provide some lower level config options (compare to > HUGETLB_PAGE or THP) to identify which layer an arch can support for such > huge mappings. However that can be an overkill. > > Cc: Mike Rapoport (IBM) <rppt@kernel.org> > Cc: Matthew Wilcox <willy@infradead.org> > Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> > Signed-off-by: Peter Xu <peterx@redhat.com> > --- > arch/riscv/include/asm/pgtable.h | 1 + > arch/s390/include/asm/pgtable.h | 1 + > arch/sparc/include/asm/pgtable_64.h | 1 + > arch/x86/include/asm/pgtable.h | 1 + > include/linux/pgtable.h | 10 ++++++++++ > 5 files changed, 14 insertions(+) > > diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h > index 20242402fc11..0ca28cc8e3fa 100644 > --- a/arch/riscv/include/asm/pgtable.h > +++ b/arch/riscv/include/asm/pgtable.h > @@ -646,6 +646,7 @@ static inline unsigned long pmd_pfn(pmd_t pmd) > > #define __pud_to_phys(pud) (__page_val_to_pfn(pud_val(pud)) << PAGE_SHIFT) > > +#define pud_pfn pud_pfn > static inline unsigned long pud_pfn(pud_t pud) > { > return ((__pud_to_phys(pud) & PUD_MASK) >> PAGE_SHIFT); > diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h > index 1a71cb19c089..6cbbe473f680 100644 > --- a/arch/s390/include/asm/pgtable.h > +++ b/arch/s390/include/asm/pgtable.h > @@ -1414,6 +1414,7 @@ static inline unsigned long pud_deref(pud_t pud) > return (unsigned long)__va(pud_val(pud) & origin_mask); > } > > +#define pud_pfn pud_pfn > static inline unsigned long pud_pfn(pud_t pud) > { > return __pa(pud_deref(pud)) >> PAGE_SHIFT; > diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h > index 4d1bafaba942..26efc9bb644a 100644 > --- a/arch/sparc/include/asm/pgtable_64.h > +++ b/arch/sparc/include/asm/pgtable_64.h > @@ -875,6 +875,7 @@ static inline bool pud_leaf(pud_t pud) > return pte_val(pte) & _PAGE_PMD_HUGE; > } > > +#define pud_pfn pud_pfn > static inline unsigned long pud_pfn(pud_t pud) > { > pte_t pte = __pte(pud_val(pud)); > diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h > index cefc7a84f7a4..273f7557218c 100644 > --- a/arch/x86/include/asm/pgtable.h > +++ b/arch/x86/include/asm/pgtable.h > @@ -234,6 +234,7 @@ static inline unsigned long pmd_pfn(pmd_t pmd) > return (pfn & pmd_pfn_mask(pmd)) >> PAGE_SHIFT; > } > > +#define pud_pfn pud_pfn > static inline unsigned long pud_pfn(pud_t pud) > { > phys_addr_t pfn = pud_val(pud); > diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h > index 600e17d03659..75fe309a4e10 100644 > --- a/include/linux/pgtable.h > +++ b/include/linux/pgtable.h > @@ -1817,6 +1817,16 @@ typedef unsigned int pgtbl_mod_mask; > #define pte_leaf_size(x) PAGE_SIZE > #endif > > +/* > + * We always define pmd_pfn for all archs as it's used in lots of generic > + * code. Now it happens too for pud_pfn (and can happen for larger > + * mappings too in the future; we're not there yet). Instead of defining > + * it for all archs (like pmd_pfn), provide a fallback. > + */ > +#ifndef pud_pfn > +#define pud_pfn(x) ({ BUILD_BUG(); 0; }) > +#endif > + > /* > * Some architectures have MMUs that are configurable or selectable at boot > * time. These lead to variable PTRS_PER_x. For statically allocated arrays it > -- > 2.44.0 > This BUILD_BUG() triggers for LoongArch with their defconfig, so it seems like they need to provide an implementation of pud_pfn()? In function 'follow_huge_pud', inlined from 'follow_pud_mask' at mm/gup.c:1075:10, inlined from 'follow_p4d_mask' at mm/gup.c:1105:9, inlined from 'follow_page_mask' at mm/gup.c:1151:10: include/linux/compiler_types.h:460:45: error: call to '__compiletime_assert_382' declared with attribute error: BUILD_BUG failed 460 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) | ^ include/linux/compiler_types.h:441:25: note: in definition of macro '__compiletime_assert' 441 | prefix ## suffix(); \ | ^~~~~~ include/linux/compiler_types.h:460:9: note: in expansion of macro '_compiletime_assert' 460 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) | ^~~~~~~~~~~~~~~~~~~ include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert' 39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) | ^~~~~~~~~~~~~~~~~~ include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG' 59 | #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed") | ^~~~~~~~~~~~~~~~ include/linux/pgtable.h:1887:23: note: in expansion of macro 'BUILD_BUG' 1887 | #define pud_pfn(x) ({ BUILD_BUG(); 0; }) | ^~~~~~~~~ mm/gup.c:679:29: note: in expansion of macro 'pud_pfn' 679 | unsigned long pfn = pud_pfn(pud); | ^~~~~~~ Cheers, Nathan
On Tue, Apr 02, 2024 at 12:05:49PM -0700, Nathan Chancellor wrote: > Hi Peter (and LoongArch folks), > > On Wed, Mar 27, 2024 at 11:23:24AM -0400, peterx@redhat.com wrote: > > From: Peter Xu <peterx@redhat.com> > > > > The comment in the code explains the reasons. We took a different approach > > comparing to pmd_pfn() by providing a fallback function. > > > > Another option is to provide some lower level config options (compare to > > HUGETLB_PAGE or THP) to identify which layer an arch can support for such > > huge mappings. However that can be an overkill. > > > > Cc: Mike Rapoport (IBM) <rppt@kernel.org> > > Cc: Matthew Wilcox <willy@infradead.org> > > Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> > > Signed-off-by: Peter Xu <peterx@redhat.com> > > --- > > arch/riscv/include/asm/pgtable.h | 1 + > > arch/s390/include/asm/pgtable.h | 1 + > > arch/sparc/include/asm/pgtable_64.h | 1 + > > arch/x86/include/asm/pgtable.h | 1 + > > include/linux/pgtable.h | 10 ++++++++++ > > 5 files changed, 14 insertions(+) > > > > diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h > > index 20242402fc11..0ca28cc8e3fa 100644 > > --- a/arch/riscv/include/asm/pgtable.h > > +++ b/arch/riscv/include/asm/pgtable.h > > @@ -646,6 +646,7 @@ static inline unsigned long pmd_pfn(pmd_t pmd) > > > > #define __pud_to_phys(pud) (__page_val_to_pfn(pud_val(pud)) << PAGE_SHIFT) > > > > +#define pud_pfn pud_pfn > > static inline unsigned long pud_pfn(pud_t pud) > > { > > return ((__pud_to_phys(pud) & PUD_MASK) >> PAGE_SHIFT); > > diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h > > index 1a71cb19c089..6cbbe473f680 100644 > > --- a/arch/s390/include/asm/pgtable.h > > +++ b/arch/s390/include/asm/pgtable.h > > @@ -1414,6 +1414,7 @@ static inline unsigned long pud_deref(pud_t pud) > > return (unsigned long)__va(pud_val(pud) & origin_mask); > > } > > > > +#define pud_pfn pud_pfn > > static inline unsigned long pud_pfn(pud_t pud) > > { > > return __pa(pud_deref(pud)) >> PAGE_SHIFT; > > diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h > > index 4d1bafaba942..26efc9bb644a 100644 > > --- a/arch/sparc/include/asm/pgtable_64.h > > +++ b/arch/sparc/include/asm/pgtable_64.h > > @@ -875,6 +875,7 @@ static inline bool pud_leaf(pud_t pud) > > return pte_val(pte) & _PAGE_PMD_HUGE; > > } > > > > +#define pud_pfn pud_pfn > > static inline unsigned long pud_pfn(pud_t pud) > > { > > pte_t pte = __pte(pud_val(pud)); > > diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h > > index cefc7a84f7a4..273f7557218c 100644 > > --- a/arch/x86/include/asm/pgtable.h > > +++ b/arch/x86/include/asm/pgtable.h > > @@ -234,6 +234,7 @@ static inline unsigned long pmd_pfn(pmd_t pmd) > > return (pfn & pmd_pfn_mask(pmd)) >> PAGE_SHIFT; > > } > > > > +#define pud_pfn pud_pfn > > static inline unsigned long pud_pfn(pud_t pud) > > { > > phys_addr_t pfn = pud_val(pud); > > diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h > > index 600e17d03659..75fe309a4e10 100644 > > --- a/include/linux/pgtable.h > > +++ b/include/linux/pgtable.h > > @@ -1817,6 +1817,16 @@ typedef unsigned int pgtbl_mod_mask; > > #define pte_leaf_size(x) PAGE_SIZE > > #endif > > > > +/* > > + * We always define pmd_pfn for all archs as it's used in lots of generic > > + * code. Now it happens too for pud_pfn (and can happen for larger > > + * mappings too in the future; we're not there yet). Instead of defining > > + * it for all archs (like pmd_pfn), provide a fallback. > > + */ > > +#ifndef pud_pfn > > +#define pud_pfn(x) ({ BUILD_BUG(); 0; }) > > +#endif > > + > > /* > > * Some architectures have MMUs that are configurable or selectable at boot > > * time. These lead to variable PTRS_PER_x. For statically allocated arrays it > > -- > > 2.44.0 > > > > This BUILD_BUG() triggers for LoongArch with their defconfig, so it > seems like they need to provide an implementation of pud_pfn()? > > In function 'follow_huge_pud', > inlined from 'follow_pud_mask' at mm/gup.c:1075:10, > inlined from 'follow_p4d_mask' at mm/gup.c:1105:9, > inlined from 'follow_page_mask' at mm/gup.c:1151:10: > include/linux/compiler_types.h:460:45: error: call to '__compiletime_assert_382' declared with attribute error: BUILD_BUG failed > 460 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) > | ^ > include/linux/compiler_types.h:441:25: note: in definition of macro '__compiletime_assert' > 441 | prefix ## suffix(); \ > | ^~~~~~ > include/linux/compiler_types.h:460:9: note: in expansion of macro '_compiletime_assert' > 460 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) > | ^~~~~~~~~~~~~~~~~~~ > include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert' > 39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) > | ^~~~~~~~~~~~~~~~~~ > include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG' > 59 | #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed") > | ^~~~~~~~~~~~~~~~ > include/linux/pgtable.h:1887:23: note: in expansion of macro 'BUILD_BUG' > 1887 | #define pud_pfn(x) ({ BUILD_BUG(); 0; }) > | ^~~~~~~~~ > mm/gup.c:679:29: note: in expansion of macro 'pud_pfn' > 679 | unsigned long pfn = pud_pfn(pud); > | ^~~~~~~ I actually tested this without hitting the issue (even though I didn't mention it in the cover letter..). I re-kicked the build test, it turns out my "make alldefconfig" on loongarch will generate a config with both HUGETLB=n && THP=n, while arch/loongarch/configs/loongson3_defconfig has THP=y (which I assume was the one above build used). I didn't further check how "make alldefconfig" generated the config; a bit surprising that it didn't fetch from there. (and it also surprises me that this BUILD_BUG can trigger.. I used to try triggering it elsewhere but failed..) For loongarch the best thing is not compile in follow_huge_pud(), as it doesn't support pud dax, neither does it support pud hugetlb. However again that may require some more CONFIG_* options to declare the level one arch supports on HUGETLB_PAGE. Here maybe the simplest (and it should also cover all the rest archs on similar issues if ever possible to happen) is we remove the BUILD_BUG() and explain why. It should be safe for loongarch too here in this case to not defined it until properly supported. Thanks, ===8<=== From 585f34aa3d5b12cd2186367b0882d4293f792062 Mon Sep 17 00:00:00 2001 From: Peter Xu <peterx@redhat.com> Date: Tue, 2 Apr 2024 18:31:07 -0400 Subject: [PATCH] fixup! mm/arch: provide pud_pfn() fallback Signed-off-by: Peter Xu <peterx@redhat.com> --- include/linux/pgtable.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h index fa8f92f6e2d7..0f4b2faa1d71 100644 --- a/include/linux/pgtable.h +++ b/include/linux/pgtable.h @@ -1882,9 +1882,13 @@ typedef unsigned int pgtbl_mod_mask; * code. Now it happens too for pud_pfn (and can happen for larger * mappings too in the future; we're not there yet). Instead of defining * it for all archs (like pmd_pfn), provide a fallback. + * + * Note that returning 0 here means any arch that didn't define this can + * get severely wrong when it hits a real pud leaf. It's arch's + * responsibility to properly define it when a huge pud is possible. */ #ifndef pud_pfn -#define pud_pfn(x) ({ BUILD_BUG(); 0; }) +#define pud_pfn(x) 0 #endif /*
On Tue, Apr 02, 2024 at 06:43:56PM -0400, Peter Xu wrote: > I actually tested this without hitting the issue (even though I didn't > mention it in the cover letter..). I re-kicked the build test, it turns > out my "make alldefconfig" on loongarch will generate a config with both > HUGETLB=n && THP=n, while arch/loongarch/configs/loongson3_defconfig has > THP=y (which I assume was the one above build used). I didn't further > check how "make alldefconfig" generated the config; a bit surprising that > it didn't fetch from there. I suspect it is weird compiler variations.. Maybe something is not being inlined. > (and it also surprises me that this BUILD_BUG can trigger.. I used to try > triggering it elsewhere but failed..) As the pud_leaf() == FALSE should result in the BUILD_BUG never being called and the optimizer removing it. Perhaps the issue is that the pud_leaf() is too far from the pud_pfn? Jason
On Tue, Apr 02, 2024 at 07:53:20PM -0300, Jason Gunthorpe wrote: > On Tue, Apr 02, 2024 at 06:43:56PM -0400, Peter Xu wrote: > > > I actually tested this without hitting the issue (even though I didn't > > mention it in the cover letter..). I re-kicked the build test, it turns > > out my "make alldefconfig" on loongarch will generate a config with both > > HUGETLB=n && THP=n, while arch/loongarch/configs/loongson3_defconfig has > > THP=y (which I assume was the one above build used). I didn't further > > check how "make alldefconfig" generated the config; a bit surprising that > > it didn't fetch from there. > > I suspect it is weird compiler variations.. Maybe something is not > being inlined. > > > (and it also surprises me that this BUILD_BUG can trigger.. I used to try > > triggering it elsewhere but failed..) > > As the pud_leaf() == FALSE should result in the BUILD_BUG never being > called and the optimizer removing it. Good point, for some reason loongarch defined pud_leaf() without defining pud_pfn(), which does look strange. #define pud_leaf(pud) ((pud_val(pud) & _PAGE_HUGE) != 0) But I noticed at least MIPS also does it.. Logically I think one arch should define either none of both. > > Perhaps the issue is that the pud_leaf() is too far from the pud_pfn? My understanding is follow_pud_mask() should completely get optimized and follow_huge_pud() will be dropped in the compiler output if pud_leaf()==false. Thanks,
On Tue, Apr 02, 2024 at 07:35:45PM -0400, Peter Xu wrote: > On Tue, Apr 02, 2024 at 07:53:20PM -0300, Jason Gunthorpe wrote: > > On Tue, Apr 02, 2024 at 06:43:56PM -0400, Peter Xu wrote: > > > > > I actually tested this without hitting the issue (even though I didn't > > > mention it in the cover letter..). I re-kicked the build test, it turns > > > out my "make alldefconfig" on loongarch will generate a config with both > > > HUGETLB=n && THP=n, while arch/loongarch/configs/loongson3_defconfig has > > > THP=y (which I assume was the one above build used). I didn't further > > > check how "make alldefconfig" generated the config; a bit surprising that > > > it didn't fetch from there. > > > > I suspect it is weird compiler variations.. Maybe something is not > > being inlined. > > > > > (and it also surprises me that this BUILD_BUG can trigger.. I used to try > > > triggering it elsewhere but failed..) > > > > As the pud_leaf() == FALSE should result in the BUILD_BUG never being > > called and the optimizer removing it. > > Good point, for some reason loongarch defined pud_leaf() without defining > pud_pfn(), which does look strange. > > #define pud_leaf(pud) ((pud_val(pud) & _PAGE_HUGE) != 0) > > But I noticed at least MIPS also does it.. Logically I think one arch > should define either none of both. Wow, this is definately an arch issue. You can't define pud_leaf() and not have a pud_pfn(). It makes no sense at all.. I'd say the BUILD_BUG has done it's job and found an issue, fix it by not defining pud_leaf? I don't see any calls to pud_leaf in loongarch at least Jason
Le 03/04/2024 à 14:08, Jason Gunthorpe a écrit : > On Tue, Apr 02, 2024 at 07:35:45PM -0400, Peter Xu wrote: >> On Tue, Apr 02, 2024 at 07:53:20PM -0300, Jason Gunthorpe wrote: >>> On Tue, Apr 02, 2024 at 06:43:56PM -0400, Peter Xu wrote: >>> >>>> I actually tested this without hitting the issue (even though I didn't >>>> mention it in the cover letter..). I re-kicked the build test, it turns >>>> out my "make alldefconfig" on loongarch will generate a config with both >>>> HUGETLB=n && THP=n, while arch/loongarch/configs/loongson3_defconfig has >>>> THP=y (which I assume was the one above build used). I didn't further >>>> check how "make alldefconfig" generated the config; a bit surprising that >>>> it didn't fetch from there. >>> >>> I suspect it is weird compiler variations.. Maybe something is not >>> being inlined. >>> >>>> (and it also surprises me that this BUILD_BUG can trigger.. I used to try >>>> triggering it elsewhere but failed..) >>> >>> As the pud_leaf() == FALSE should result in the BUILD_BUG never being >>> called and the optimizer removing it. >> >> Good point, for some reason loongarch defined pud_leaf() without defining >> pud_pfn(), which does look strange. >> >> #define pud_leaf(pud) ((pud_val(pud) & _PAGE_HUGE) != 0) >> >> But I noticed at least MIPS also does it.. Logically I think one arch >> should define either none of both. > > Wow, this is definately an arch issue. You can't define pud_leaf() and > not have a pud_pfn(). It makes no sense at all.. > > I'd say the BUILD_BUG has done it's job and found an issue, fix it by > not defining pud_leaf? I don't see any calls to pud_leaf in loongarch > at least As far as I can see it was added by commit 303be4b33562 ("LoongArch: mm: Add p?d_leaf() definitions"). Not sure it was added for a good reason, and I'm not sure what was added is correct because arch/loongarch/include/asm/pgtable-bits.h has: #define _PAGE_HUGE_SHIFT 6 /* HUGE is a PMD bit */ So I'm not sure it is correct to use that bit for PUD, is it ? Probably pud_leaf() should always return false. Christophe
On Wed, Apr 03, 2024 at 12:26:43PM +0000, Christophe Leroy wrote: > > > Le 03/04/2024 à 14:08, Jason Gunthorpe a écrit : > > On Tue, Apr 02, 2024 at 07:35:45PM -0400, Peter Xu wrote: > >> On Tue, Apr 02, 2024 at 07:53:20PM -0300, Jason Gunthorpe wrote: > >>> On Tue, Apr 02, 2024 at 06:43:56PM -0400, Peter Xu wrote: > >>> > >>>> I actually tested this without hitting the issue (even though I didn't > >>>> mention it in the cover letter..). I re-kicked the build test, it turns > >>>> out my "make alldefconfig" on loongarch will generate a config with both > >>>> HUGETLB=n && THP=n, while arch/loongarch/configs/loongson3_defconfig has > >>>> THP=y (which I assume was the one above build used). I didn't further > >>>> check how "make alldefconfig" generated the config; a bit surprising that > >>>> it didn't fetch from there. > >>> > >>> I suspect it is weird compiler variations.. Maybe something is not > >>> being inlined. > >>> > >>>> (and it also surprises me that this BUILD_BUG can trigger.. I used to try > >>>> triggering it elsewhere but failed..) > >>> > >>> As the pud_leaf() == FALSE should result in the BUILD_BUG never being > >>> called and the optimizer removing it. > >> > >> Good point, for some reason loongarch defined pud_leaf() without defining > >> pud_pfn(), which does look strange. > >> > >> #define pud_leaf(pud) ((pud_val(pud) & _PAGE_HUGE) != 0) > >> > >> But I noticed at least MIPS also does it.. Logically I think one arch > >> should define either none of both. > > > > Wow, this is definately an arch issue. You can't define pud_leaf() and > > not have a pud_pfn(). It makes no sense at all.. > > > > I'd say the BUILD_BUG has done it's job and found an issue, fix it by > > not defining pud_leaf? I don't see any calls to pud_leaf in loongarch > > at least > > As far as I can see it was added by commit 303be4b33562 ("LoongArch: mm: > Add p?d_leaf() definitions"). That commit makes it sounds like the arch supports huge PUD's through the hugepte mechanism - it says a LTP test failed so something populated a huge PUD at least?? So maybe this? #define pud_pfn pte_pfn > Not sure it was added for a good reason, and I'm not sure what was added > is correct because arch/loongarch/include/asm/pgtable-bits.h has: > > #define _PAGE_HUGE_SHIFT 6 /* HUGE is a PMD bit */ > > So I'm not sure it is correct to use that bit for PUD, is it ? Could be, lots of arches repeat the bit layouts in each radix level.. It is essentially why the hugepte trick of pretending every level is a pte works. Jason
Le 03/04/2024 à 15:07, Jason Gunthorpe a écrit : > On Wed, Apr 03, 2024 at 12:26:43PM +0000, Christophe Leroy wrote: >> >> >> Le 03/04/2024 à 14:08, Jason Gunthorpe a écrit : >>> On Tue, Apr 02, 2024 at 07:35:45PM -0400, Peter Xu wrote: >>>> On Tue, Apr 02, 2024 at 07:53:20PM -0300, Jason Gunthorpe wrote: >>>>> On Tue, Apr 02, 2024 at 06:43:56PM -0400, Peter Xu wrote: >>>>> >>>>>> I actually tested this without hitting the issue (even though I didn't >>>>>> mention it in the cover letter..). I re-kicked the build test, it turns >>>>>> out my "make alldefconfig" on loongarch will generate a config with both >>>>>> HUGETLB=n && THP=n, while arch/loongarch/configs/loongson3_defconfig has >>>>>> THP=y (which I assume was the one above build used). I didn't further >>>>>> check how "make alldefconfig" generated the config; a bit surprising that >>>>>> it didn't fetch from there. >>>>> >>>>> I suspect it is weird compiler variations.. Maybe something is not >>>>> being inlined. >>>>> >>>>>> (and it also surprises me that this BUILD_BUG can trigger.. I used to try >>>>>> triggering it elsewhere but failed..) >>>>> >>>>> As the pud_leaf() == FALSE should result in the BUILD_BUG never being >>>>> called and the optimizer removing it. >>>> >>>> Good point, for some reason loongarch defined pud_leaf() without defining >>>> pud_pfn(), which does look strange. >>>> >>>> #define pud_leaf(pud) ((pud_val(pud) & _PAGE_HUGE) != 0) >>>> >>>> But I noticed at least MIPS also does it.. Logically I think one arch >>>> should define either none of both. >>> >>> Wow, this is definately an arch issue. You can't define pud_leaf() and >>> not have a pud_pfn(). It makes no sense at all.. >>> >>> I'd say the BUILD_BUG has done it's job and found an issue, fix it by >>> not defining pud_leaf? I don't see any calls to pud_leaf in loongarch >>> at least >> >> As far as I can see it was added by commit 303be4b33562 ("LoongArch: mm: >> Add p?d_leaf() definitions"). > > That commit makes it sounds like the arch supports huge PUD's through > the hugepte mechanism - it says a LTP test failed so something > populated a huge PUD at least?? Not sure, I more see it just like a copy/paste of commit 501b81046701 ("mips: mm: add p?d_leaf() definitions"). The commit message says that the test failed because pmd_leaf() is missing, it says nothing about PUD. When looking where _PAGE_HUGE is used in loongarch, I have the impression that it is exclusively used at PMD level. > > So maybe this? > > #define pud_pfn pte_pfn > >> Not sure it was added for a good reason, and I'm not sure what was added >> is correct because arch/loongarch/include/asm/pgtable-bits.h has: >> >> #define _PAGE_HUGE_SHIFT 6 /* HUGE is a PMD bit */ >> >> So I'm not sure it is correct to use that bit for PUD, is it ? > > Could be, lots of arches repeat the bit layouts in each radix > level.. It is essentially why the hugepte trick of pretending every > level is a pte works. > > Jason
On Wed, Apr 03, 2024 at 01:17:06PM +0000, Christophe Leroy wrote: > > That commit makes it sounds like the arch supports huge PUD's through > > the hugepte mechanism - it says a LTP test failed so something > > populated a huge PUD at least?? > > Not sure, I more see it just like a copy/paste of commit 501b81046701 > ("mips: mm: add p?d_leaf() definitions"). > > The commit message says that the test failed because pmd_leaf() is > missing, it says nothing about PUD. AH fair enough, it is probably a C&P then Jason
On Wed, Apr 03, 2024 at 09:08:41AM -0300, Jason Gunthorpe wrote: > On Tue, Apr 02, 2024 at 07:35:45PM -0400, Peter Xu wrote: > > On Tue, Apr 02, 2024 at 07:53:20PM -0300, Jason Gunthorpe wrote: > > > On Tue, Apr 02, 2024 at 06:43:56PM -0400, Peter Xu wrote: > > > > > > > I actually tested this without hitting the issue (even though I didn't > > > > mention it in the cover letter..). I re-kicked the build test, it turns > > > > out my "make alldefconfig" on loongarch will generate a config with both > > > > HUGETLB=n && THP=n, while arch/loongarch/configs/loongson3_defconfig has > > > > THP=y (which I assume was the one above build used). I didn't further > > > > check how "make alldefconfig" generated the config; a bit surprising that > > > > it didn't fetch from there. > > > > > > I suspect it is weird compiler variations.. Maybe something is not > > > being inlined. > > > > > > > (and it also surprises me that this BUILD_BUG can trigger.. I used to try > > > > triggering it elsewhere but failed..) > > > > > > As the pud_leaf() == FALSE should result in the BUILD_BUG never being > > > called and the optimizer removing it. > > > > Good point, for some reason loongarch defined pud_leaf() without defining > > pud_pfn(), which does look strange. > > > > #define pud_leaf(pud) ((pud_val(pud) & _PAGE_HUGE) != 0) > > > > But I noticed at least MIPS also does it.. Logically I think one arch > > should define either none of both. > > Wow, this is definately an arch issue. You can't define pud_leaf() and > not have a pud_pfn(). It makes no sense at all.. > > I'd say the BUILD_BUG has done it's job and found an issue, fix it by > not defining pud_leaf? I don't see any calls to pud_leaf in loongarch > at least Yes, that sounds better too to me, however it means we may also risk other archs that can fail another defconfig build.. and I worry I bring trouble to multiple such cases. Fundamentally it's indeed my patch that broke those builds, so I still sent the change and leave that for arch developers to decide the best for the archs. I think if wanted, we can add that BUILD_BUG() back when we're sure no arch will break with it. So such changes from arch can still be proposed alongside of removal of BUILD_BUG() (and I'd guess some other arch will start to notice such build issue soon if existed.. so it still more or less has similar effect of a reminder..). Thanks,
On Wed, Apr 03, 2024 at 02:25:20PM -0400, Peter Xu wrote: > > I'd say the BUILD_BUG has done it's job and found an issue, fix it by > > not defining pud_leaf? I don't see any calls to pud_leaf in loongarch > > at least > > Yes, that sounds better too to me, however it means we may also risk other > archs that can fail another defconfig build.. and I worry I bring trouble > to multiple such cases. Fundamentally it's indeed my patch that broke > those builds, so I still sent the change and leave that for arch developers > to decide the best for the archs. But your change causes silent data corruption if the code path is run.. I think we are overall better to wade through the compile time bugs from linux-next. Honestly if there were alot then I'd think there would be more complaints already. Maybe it should just be a seperate step from this series. Jason
On Thu, Apr 04, 2024 at 08:24:04AM -0300, Jason Gunthorpe wrote: > On Wed, Apr 03, 2024 at 02:25:20PM -0400, Peter Xu wrote: > > > > I'd say the BUILD_BUG has done it's job and found an issue, fix it by > > > not defining pud_leaf? I don't see any calls to pud_leaf in loongarch > > > at least > > > > Yes, that sounds better too to me, however it means we may also risk other > > archs that can fail another defconfig build.. and I worry I bring trouble > > to multiple such cases. Fundamentally it's indeed my patch that broke > > those builds, so I still sent the change and leave that for arch developers > > to decide the best for the archs. > > But your change causes silent data corruption if the code path is > run.. I think we are overall better to wade through the compile time > bugs from linux-next. Honestly if there were alot then I'd think there > would be more complaints already. > > Maybe it should just be a seperate step from this series. Right, that'll be imho better to be done separate, as I think we'd better consolidate the code. One thing I don't worry is the warning would cause anything real to fail; I don't yet expect any arch that will not define pud_pfn when it needs it.. so it can mean all of the build errors may not cause real benefits as of now. But I agree with you we'd better have it. I'll take a todo and I'll try to add it back after all these fallouts. With my cross build chains now it shouldn't be hard, just take some time to revisit each arch. Thanks,
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index 20242402fc11..0ca28cc8e3fa 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -646,6 +646,7 @@ static inline unsigned long pmd_pfn(pmd_t pmd) #define __pud_to_phys(pud) (__page_val_to_pfn(pud_val(pud)) << PAGE_SHIFT) +#define pud_pfn pud_pfn static inline unsigned long pud_pfn(pud_t pud) { return ((__pud_to_phys(pud) & PUD_MASK) >> PAGE_SHIFT); diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 1a71cb19c089..6cbbe473f680 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -1414,6 +1414,7 @@ static inline unsigned long pud_deref(pud_t pud) return (unsigned long)__va(pud_val(pud) & origin_mask); } +#define pud_pfn pud_pfn static inline unsigned long pud_pfn(pud_t pud) { return __pa(pud_deref(pud)) >> PAGE_SHIFT; diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 4d1bafaba942..26efc9bb644a 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h @@ -875,6 +875,7 @@ static inline bool pud_leaf(pud_t pud) return pte_val(pte) & _PAGE_PMD_HUGE; } +#define pud_pfn pud_pfn static inline unsigned long pud_pfn(pud_t pud) { pte_t pte = __pte(pud_val(pud)); diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index cefc7a84f7a4..273f7557218c 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -234,6 +234,7 @@ static inline unsigned long pmd_pfn(pmd_t pmd) return (pfn & pmd_pfn_mask(pmd)) >> PAGE_SHIFT; } +#define pud_pfn pud_pfn static inline unsigned long pud_pfn(pud_t pud) { phys_addr_t pfn = pud_val(pud); diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h index 600e17d03659..75fe309a4e10 100644 --- a/include/linux/pgtable.h +++ b/include/linux/pgtable.h @@ -1817,6 +1817,16 @@ typedef unsigned int pgtbl_mod_mask; #define pte_leaf_size(x) PAGE_SIZE #endif +/* + * We always define pmd_pfn for all archs as it's used in lots of generic + * code. Now it happens too for pud_pfn (and can happen for larger + * mappings too in the future; we're not there yet). Instead of defining + * it for all archs (like pmd_pfn), provide a fallback. + */ +#ifndef pud_pfn +#define pud_pfn(x) ({ BUILD_BUG(); 0; }) +#endif + /* * Some architectures have MMUs that are configurable or selectable at boot * time. These lead to variable PTRS_PER_x. For statically allocated arrays it