From 173e7622ccb3f46834bd4176ed363f435e142942 Mon Sep 17 00:00:00 2001 From: Mina Almasry Date: Thu, 2 May 2024 10:54:22 -0700 Subject: Revert "net: mirror skb frag ref/unref helpers" This reverts commit a580ea994fd37f4105028f5a85c38ff6508a2b25. This revert is to resolve Dragos's report of page_pool leak here: https://lore.kernel.org/lkml/20240424165646.1625690-2-dtatulea@nvidia.com/ The reverted patch interacts very badly with commit 2cc3aeb5eccc ("skbuff: Fix a potential race while recycling page_pool packets"). The reverted commit hopes that the pp_recycle + is_pp_page variables do not change between the skb_frag_ref and skb_frag_unref operation. If such a change occurs, the skb_frag_ref/unref will not operate on the same reference type. In the case of Dragos's report, the grabbed ref was a pp ref, but the unref was a page ref, because the pp_recycle setting on the skb was changed. Attempting to fix this issue on the fly is risky. Lets revert and I hope to reland this with better understanding and testing to ensure we don't regress some edge case while streamlining skb reffing. Fixes: a580ea994fd3 ("net: mirror skb frag ref/unref helpers") Reported-by: Dragos Tatulea Signed-off-by: Mina Almasry Link: https://lore.kernel.org/r/20240502175423.2456544-1-almasrymina@google.com Signed-off-by: Jakub Kicinski --- include/linux/skbuff_ref.h | 39 ++++----------------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) (limited to 'include/linux') diff --git a/include/linux/skbuff_ref.h b/include/linux/skbuff_ref.h index 4dcdbe9fbc5f..11f0a4063403 100644 --- a/include/linux/skbuff_ref.h +++ b/include/linux/skbuff_ref.h @@ -8,47 +8,16 @@ #define _LINUX_SKBUFF_REF_H #include -#include - -#ifdef CONFIG_PAGE_POOL -static inline bool is_pp_page(struct page *page) -{ - return (page->pp_magic & ~0x3UL) == PP_SIGNATURE; -} - -static inline bool napi_pp_get_page(struct page *page) -{ - page = compound_head(page); - - if (!is_pp_page(page)) - return false; - - page_pool_ref_page(page); - return true; -} -#endif - -static inline void skb_page_ref(struct page *page, bool recycle) -{ -#ifdef CONFIG_PAGE_POOL - if (recycle && napi_pp_get_page(page)) - return; -#endif - get_page(page); -} /** * __skb_frag_ref - take an addition reference on a paged fragment. * @frag: the paged fragment - * @recycle: skb->pp_recycle param of the parent skb. False if no parent skb. * - * Takes an additional reference on the paged fragment @frag. Obtains the - * correct reference count depending on whether skb->pp_recycle is set and - * whether the frag is a page pool frag. + * Takes an additional reference on the paged fragment @frag. */ -static inline void __skb_frag_ref(skb_frag_t *frag, bool recycle) +static inline void __skb_frag_ref(skb_frag_t *frag) { - skb_page_ref(skb_frag_page(frag), recycle); + get_page(skb_frag_page(frag)); } /** @@ -60,7 +29,7 @@ static inline void __skb_frag_ref(skb_frag_t *frag, bool recycle) */ static inline void skb_frag_ref(struct sk_buff *skb, int f) { - __skb_frag_ref(&skb_shinfo(skb)->frags[f], skb->pp_recycle); + __skb_frag_ref(&skb_shinfo(skb)->frags[f]); } bool napi_pp_put_page(struct page *page); -- cgit v1.2.3