include/linux/huge_mm.h | 2 ++ 1 file changed, 2 insertions(+)
Calling is_huge_zero_folio(NULL) should not be legal - it makes no
sense, and a different (theoretical) implementation may dereference
the pointer. But currently, lacking any explicit documentation, this
call is possible.
But if somebody really passes NULL, the function should not return
true - this isn't the huge zero folio after all! However, if the
`huge_zero_folio` hasn't been allocated yet, it's NULL, and
is_huge_zero_folio(NULL) just happens to return true, which is a lie.
This weird side effect prevented me from reproducing a kernel crash
that occurred when the elements of a folio_batch were NULL - since
folios_put_refs() skips huge zero folios, this sometimes causes a
crash, but sometimes does not. For debugging, it is better to reveal
such bugs reliably and not hide them behind random preconditions like
"has the huge zero folio already been created?"
To improve detection of such bugs, David Hildenbrand suggested adding
a VM_WARN_ON_ONCE().
Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
---
v1->v2: using VM_WARN_ON_ONCE() instead of checking huge_zero_folio
v2->v3: use "!" to check NULL; removed the #include
---
include/linux/huge_mm.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 7748489fde1b..96ac47603d97 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -479,6 +479,8 @@ extern unsigned long huge_zero_pfn;
static inline bool is_huge_zero_folio(const struct folio *folio)
{
+ VM_WARN_ON_ONCE(!folio);
+
return READ_ONCE(huge_zero_folio) == folio;
}
--
2.47.2
On 28 Aug 2025, at 4:48, Max Kellermann wrote: > Calling is_huge_zero_folio(NULL) should not be legal - it makes no > sense, and a different (theoretical) implementation may dereference > the pointer. But currently, lacking any explicit documentation, this > call is possible. > > But if somebody really passes NULL, the function should not return > true - this isn't the huge zero folio after all! However, if the > `huge_zero_folio` hasn't been allocated yet, it's NULL, and > is_huge_zero_folio(NULL) just happens to return true, which is a lie. > > This weird side effect prevented me from reproducing a kernel crash > that occurred when the elements of a folio_batch were NULL - since > folios_put_refs() skips huge zero folios, this sometimes causes a > crash, but sometimes does not. For debugging, it is better to reveal > such bugs reliably and not hide them behind random preconditions like > "has the huge zero folio already been created?" > > To improve detection of such bugs, David Hildenbrand suggested adding > a VM_WARN_ON_ONCE(). > > Signed-off-by: Max Kellermann <max.kellermann@ionos.com> > --- > v1->v2: using VM_WARN_ON_ONCE() instead of checking huge_zero_folio > v2->v3: use "!" to check NULL; removed the #include > --- > include/linux/huge_mm.h | 2 ++ > 1 file changed, 2 insertions(+) > LGTM. Reviewed-by: Zi Yan <ziy@nvidia.com> -- Best Regards, Yan, Zi
Please don't send this in reply to previous versions, just send as a separate mail :) (yes email for dev sucks and there's a bunch of weird nuances so totally understandable!) Hopefully Andrew will pick this up regardless. On Thu, Aug 28, 2025 at 10:48:20AM +0200, Max Kellermann wrote: > Calling is_huge_zero_folio(NULL) should not be legal - it makes no > sense, and a different (theoretical) implementation may dereference > the pointer. But currently, lacking any explicit documentation, this > call is possible. > > But if somebody really passes NULL, the function should not return > true - this isn't the huge zero folio after all! However, if the > `huge_zero_folio` hasn't been allocated yet, it's NULL, and > is_huge_zero_folio(NULL) just happens to return true, which is a lie. > > This weird side effect prevented me from reproducing a kernel crash > that occurred when the elements of a folio_batch were NULL - since > folios_put_refs() skips huge zero folios, this sometimes causes a > crash, but sometimes does not. For debugging, it is better to reveal > such bugs reliably and not hide them behind random preconditions like > "has the huge zero folio already been created?" > > To improve detection of such bugs, David Hildenbrand suggested adding > a VM_WARN_ON_ONCE(). > > Signed-off-by: Max Kellermann <max.kellermann@ionos.com> LGTM, so: Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> > --- > v1->v2: using VM_WARN_ON_ONCE() instead of checking huge_zero_folio > v2->v3: use "!" to check NULL; removed the #include Putting the history in is great though thanks! :) > --- > include/linux/huge_mm.h | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h > index 7748489fde1b..96ac47603d97 100644 > --- a/include/linux/huge_mm.h > +++ b/include/linux/huge_mm.h > @@ -479,6 +479,8 @@ extern unsigned long huge_zero_pfn; > > static inline bool is_huge_zero_folio(const struct folio *folio) > { > + VM_WARN_ON_ONCE(!folio); > + > return READ_ONCE(huge_zero_folio) == folio; > } > > -- > 2.47.2 >
© 2016 - 2025 Red Hat, Inc.