As mentioned in commit c07aea3ef4d4 ("mm: add a signature in struct page"): "The page->signature field is aliased to page->lru.next and page->compound_head."
And as the comment in page_is_pfmemalloc(): "lru.next has bit 1 set if the page is allocated from the pfmemalloc reserves. Callers may simply overwrite it if they do not need to preserve that information."
The page->signature is or’ed with PP_SIGNATURE when a page is allocated in page pool, see __page_pool_alloc_pages_slow(), and page->signature is checked directly with PP_SIGNATURE in page_pool_return_skb_page(), which might cause resoure leaking problem for a page from page pool if bit 1 of lru.next is set for a pfmemalloc page.
As bit 0 is page->compound_head, So mask both bit 0 and 1 before the checking in page_pool_return_skb_page().
Fixes: 6a5bcd84e886 ("page_pool: Allow drivers to hint on SKB recycling") Signed-off-by: Yunsheng Lin linyunsheng@huawei.com --- net/core/page_pool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/page_pool.c b/net/core/page_pool.c index 5e4eb45..33b7dd7 100644 --- a/net/core/page_pool.c +++ b/net/core/page_pool.c @@ -634,7 +634,7 @@ bool page_pool_return_skb_page(struct page *page) struct page_pool *pp;
page = compound_head(page); - if (unlikely(page->pp_magic != PP_SIGNATURE)) + if (unlikely((page->pp_magic & ~0x3UL) != PP_SIGNATURE)) return false;
pp = page->pp;