summaryrefslogtreecommitdiff
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c21
1 files changed, 8 insertions, 13 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 227d58dc3de6..d49c254174da 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1035,6 +1035,7 @@ static inline bool page_expected_state(struct page *page,
#ifdef CONFIG_MEMCG
page->memcg_data |
#endif
+ page_pool_page_is_pp(page) |
(page->flags.f & check_flags)))
return false;
@@ -1061,6 +1062,8 @@ static const char *page_bad_reason(struct page *page, unsigned long flags)
if (unlikely(page->memcg_data))
bad_reason = "page still charged to cgroup";
#endif
+ if (unlikely(page_pool_page_is_pp(page)))
+ bad_reason = "page_pool leak";
return bad_reason;
}
@@ -1377,17 +1380,9 @@ __always_inline bool __free_pages_prepare(struct page *page,
mod_mthp_stat(order, MTHP_STAT_NR_ANON, -1);
folio->mapping = NULL;
}
- if (unlikely(page_has_type(page))) {
- /* networking expects to clear its page type before releasing */
- if (is_check_pages_enabled()) {
- if (unlikely(PageNetpp(page))) {
- bad_page(page, "page_pool leak");
- return false;
- }
- }
+ if (unlikely(page_has_type(page)))
/* Reset the page_type (which overlays _mapcount) */
page->page_type = UINT_MAX;
- }
if (is_check_pages_enabled()) {
if (free_page_is_bad(page))
@@ -1808,9 +1803,9 @@ static inline bool should_skip_init(gfp_t flags)
inline void post_alloc_hook(struct page *page, unsigned int order,
gfp_t gfp_flags)
{
+ const bool zero_tags = gfp_flags & __GFP_ZEROTAGS;
bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags) &&
!should_skip_init(gfp_flags);
- bool zero_tags = init && (gfp_flags & __GFP_ZEROTAGS);
int i;
set_page_private(page, 0);
@@ -1832,11 +1827,11 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
*/
/*
- * If memory tags should be zeroed
- * (which happens only when memory should be initialized as well).
+ * Clearing tags can efficiently clear the memory for us as well, if
+ * required.
*/
if (zero_tags)
- init = !tag_clear_highpages(page, 1 << order);
+ init = tag_clear_highpages(page, 1 << order, /* clear_pages= */init);
if (!should_skip_kasan_unpoison(gfp_flags) &&
kasan_unpoison_pages(page, order, init)) {