Commit cd3c9316 authored by Toke Høiland-Jørgensen's avatar Toke Høiland-Jørgensen Committed by Jakub Kicinski
Browse files

page_pool: Move pp_magic check into helper functions



Since we are about to stash some more information into the pp_magic
field, let's move the magic signature checks into a pair of helper
functions so it can be changed in one place.

Reviewed-by: default avatarMina Almasry <almasrymina@google.com>
Tested-by: default avatarYonglong Liu <liuyonglong@huawei.com>
Acked-by: default avatarJesper Dangaard Brouer <hawk@kernel.org>
Reviewed-by: default avatarIlias Apalodimas <ilias.apalodimas@linaro.org>
Signed-off-by: default avatarToke Høiland-Jørgensen <toke@redhat.com>
Link: https://patch.msgid.link/20250409-page-pool-track-dma-v9-1-6a9ef2e0cba8@redhat.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 452446f8
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -707,8 +707,8 @@ static void mlx5e_free_xdpsq_desc(struct mlx5e_xdpsq *sq,
				xdpi = mlx5e_xdpi_fifo_pop(xdpi_fifo);
				page = xdpi.page.page;

				/* No need to check ((page->pp_magic & ~0x3UL) == PP_SIGNATURE)
				 * as we know this is a page_pool page.
				/* No need to check page_pool_page_is_pp() as we
				 * know this is a page_pool page.
				 */
				page_pool_recycle_direct(page->pp, page);
			} while (++n < num);
+20 −0
Original line number Diff line number Diff line
@@ -4248,4 +4248,24 @@ int arch_lock_shadow_stack_status(struct task_struct *t, unsigned long status);
#define VM_SEALED_SYSMAP	VM_NONE
#endif

/* Mask used for checking in page_pool_page_is_pp() below. page->pp_magic is
 * OR'ed with PP_SIGNATURE after the allocation in order to preserve bit 0 for
 * the head page of compound page and bit 1 for pfmemalloc page.
 * page_is_pfmemalloc() is checked in __page_pool_put_page() to avoid recycling
 * the pfmemalloc page.
 */
#define PP_MAGIC_MASK ~0x3UL

#ifdef CONFIG_PAGE_POOL
static inline bool page_pool_page_is_pp(struct page *page)
{
	return (page->pp_magic & PP_MAGIC_MASK) == PP_SIGNATURE;
}
#else
static inline bool page_pool_page_is_pp(struct page *page)
{
	return false;
}
#endif

#endif /* _LINUX_MM_H */
+2 −6
Original line number Diff line number Diff line
@@ -897,9 +897,7 @@ static inline bool page_expected_state(struct page *page,
#ifdef CONFIG_MEMCG
			page->memcg_data |
#endif
#ifdef CONFIG_PAGE_POOL
			((page->pp_magic & ~0x3UL) == PP_SIGNATURE) |
#endif
			page_pool_page_is_pp(page) |
			(page->flags & check_flags)))
		return false;

@@ -926,10 +924,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
#ifdef CONFIG_PAGE_POOL
	if (unlikely((page->pp_magic & ~0x3UL) == PP_SIGNATURE))
	if (unlikely(page_pool_page_is_pp(page)))
		bad_reason = "page_pool leak";
#endif
	return bad_reason;
}

+5 −0
Original line number Diff line number Diff line
@@ -18,6 +18,11 @@ static inline void netmem_clear_pp_magic(netmem_ref netmem)
	__netmem_clear_lsb(netmem)->pp_magic = 0;
}

static inline bool netmem_is_pp(netmem_ref netmem)
{
	return (netmem_get_pp_magic(netmem) & PP_MAGIC_MASK) == PP_SIGNATURE;
}

static inline void netmem_set_pp(netmem_ref netmem, struct page_pool *pool)
{
	__netmem_clear_lsb(netmem)->pp = pool;
+2 −14
Original line number Diff line number Diff line
@@ -893,11 +893,6 @@ static void skb_clone_fraglist(struct sk_buff *skb)
		skb_get(list);
}

static bool is_pp_netmem(netmem_ref netmem)
{
	return (netmem_get_pp_magic(netmem) & ~0x3UL) == PP_SIGNATURE;
}

int skb_pp_cow_data(struct page_pool *pool, struct sk_buff **pskb,
		    unsigned int headroom)
{
@@ -995,14 +990,7 @@ bool napi_pp_put_page(netmem_ref netmem)
{
	netmem = netmem_compound_head(netmem);

	/* page->pp_magic is OR'ed with PP_SIGNATURE after the allocation
	 * in order to preserve any existing bits, such as bit 0 for the
	 * head page of compound page and bit 1 for pfmemalloc page, so
	 * mask those bits for freeing side when doing below checking,
	 * and page_is_pfmemalloc() is checked in __page_pool_put_page()
	 * to avoid recycling the pfmemalloc page.
	 */
	if (unlikely(!is_pp_netmem(netmem)))
	if (unlikely(!netmem_is_pp(netmem)))
		return false;

	page_pool_put_full_netmem(netmem_get_pp(netmem), netmem, false);
@@ -1042,7 +1030,7 @@ static int skb_pp_frag_ref(struct sk_buff *skb)

	for (i = 0; i < shinfo->nr_frags; i++) {
		head_netmem = netmem_compound_head(shinfo->frags[i].netmem);
		if (likely(is_pp_netmem(head_netmem)))
		if (likely(netmem_is_pp(head_netmem)))
			page_pool_ref_netmem(head_netmem);
		else
			page_ref_inc(netmem_to_page(head_netmem));
Loading