summaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorMina Almasry <almasrymina@google.com>2024-05-02 10:54:22 -0700
committerJakub Kicinski <kuba@kernel.org>2024-05-03 16:05:53 -0700
commit173e7622ccb3f46834bd4176ed363f435e142942 (patch)
treefd39a0842d666f9f90ba0740223613d16e1d08fa /include/linux
parent5bfadc573711a1e68d05d25e10ae747385c4c253 (diff)
downloadlinux-stable-173e7622ccb3f46834bd4176ed363f435e142942.tar.gz
linux-stable-173e7622ccb3f46834bd4176ed363f435e142942.tar.bz2
linux-stable-173e7622ccb3f46834bd4176ed363f435e142942.zip
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 <dtatulea@nvidia.com> Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://lore.kernel.org/r/20240502175423.2456544-1-almasrymina@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/skbuff_ref.h39
1 files changed, 4 insertions, 35 deletions
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 <linux/skbuff.h>
-#include <net/page_pool/helpers.h>
-
-#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);