diff mbox series

[net-next,2/9] net: skbuff: don't include <net/page_pool/types.h> to <linux/skbuff.h>

Message ID 20230727144336.1646454-3-aleksander.lobakin@intel.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series page_pool: a couple of assorted optimizations | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 6412 this patch: 6412
netdev/cc_maintainers success CCed 7 of 7 maintainers
netdev/build_clang success Errors and warnings before: 3321 this patch: 3321
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 6660 this patch: 6660
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 79 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Alexander Lobakin July 27, 2023, 2:43 p.m. UTC
Currently, touching <net/page_pool/types.h> triggers a rebuild of more
than half of the kernel. That's because it's included in
<linux/skbuff.h>. And each new include to page_pool/types.h adds more
[useless] data for the toolchain to process per each source file from
that pile.

In commit 6a5bcd84e886 ("page_pool: Allow drivers to hint on SKB
recycling"), Matteo included it to be able to call a couple of functions
defined there. Then, in commit 57f05bc2ab24 ("page_pool: keep pp info as
long as page pool owns the page") one of the calls was removed, so only
one was left. It's the call to page_pool_return_skb_page() in
napi_frag_unref(). The function is external and doesn't have any
dependencies. Having very niche page_pool_types.h included only for that
looks like an overkill.

As %PP_SIGNATURE is not local to page_pool.c (was only in the
early submissions), nothing holds this function there. Teleport
page_pool_return_skb_page() to skbuff.c, just next to the main
consumer, skb_pp_recycle(). It's used also in napi_frag_unref() ->
{__,}skb_frag_unref(), so no `static` unfortunately. Maybe next time.
Now, touching page_pool_types.h only triggers rebuilding of the drivers
using it and a couple of core networking files.

Suggested-by: Jakub Kicinski <kuba@kernel.org> # make skbuff.h less heavy
Suggested-by: Alexander Duyck <alexanderduyck@fb.com> # move to skbuff.c
Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
---
 include/linux/skbuff.h        |  3 ++-
 include/net/page_pool/types.h |  2 --
 net/core/page_pool.c          | 39 ---------------------------------
 net/core/skbuff.c             | 41 ++++++++++++++++++++++++++++++++++-
 4 files changed, 42 insertions(+), 43 deletions(-)

Comments

Yunsheng Lin July 28, 2023, 12:02 p.m. UTC | #1
On 2023/7/27 22:43, Alexander Lobakin wrote:
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c

...

> +bool page_pool_return_skb_page(struct page *page, bool napi_safe)

Still having the 'page_pool_' prefix seems odd here when it is in the
skbuff.c where most have skb_ or napi_ prefix, is it better to rename
it to something like napi_return_page_pool_page()?

> +{
> +	struct napi_struct *napi;
> +	struct page_pool *pp;
> +	bool allow_direct;
> +
> +	page = compound_head(page);
> +
> +	/* 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((page->pp_magic & ~0x3UL) != PP_SIGNATURE))
> +		return false;
> +
> +	pp = page->pp;
> +
> +	/* Allow direct recycle if we have reasons to believe that we are
> +	 * in the same context as the consumer would run, so there's
> +	 * no possible race.
> +	 */
> +	napi = READ_ONCE(pp->p.napi);
> +	allow_direct = napi_safe && napi &&
> +		READ_ONCE(napi->list_owner) == smp_processor_id();
> +
> +	/* Driver set this to memory recycling info. Reset it on recycle.
> +	 * This will *not* work for NIC using a split-page memory model.
> +	 * The page will be returned to the pool here regardless of the
> +	 * 'flipped' fragment being in use or not.
> +	 */
> +	page_pool_put_full_page(pp, page, allow_direct);
> +
> +	return true;
> +}
> +EXPORT_SYMBOL(page_pool_return_skb_page);
> +
>  static bool skb_pp_recycle(struct sk_buff *skb, void *data, bool napi_safe)
>  {
>  	if (!IS_ENABLED(CONFIG_PAGE_POOL) || !skb->pp_recycle)
>
Alexander Lobakin July 28, 2023, 1:58 p.m. UTC | #2
From: Yunsheng Lin <linyunsheng@huawei.com>
Date: Fri, 28 Jul 2023 20:02:51 +0800

> On 2023/7/27 22:43, Alexander Lobakin wrote:
>> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> 
> ...
> 
>> +bool page_pool_return_skb_page(struct page *page, bool napi_safe)
> 
> Still having the 'page_pool_' prefix seems odd here when it is in the
> skbuff.c where most have skb_ or napi_ prefix, is it better to rename
> it to something like napi_return_page_pool_page()?

Given that how the function that goes next is named, maybe
skb_pp_return_page() (or skb_pp_put_page())?

> 
>> +{
>> +	struct napi_struct *napi;
>> +	struct page_pool *pp;
>> +	bool allow_direct;
>> +
>> +	page = compound_head(page);
>> +
>> +	/* 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((page->pp_magic & ~0x3UL) != PP_SIGNATURE))
>> +		return false;
>> +
>> +	pp = page->pp;
>> +
>> +	/* Allow direct recycle if we have reasons to believe that we are
>> +	 * in the same context as the consumer would run, so there's
>> +	 * no possible race.
>> +	 */
>> +	napi = READ_ONCE(pp->p.napi);
>> +	allow_direct = napi_safe && napi &&
>> +		READ_ONCE(napi->list_owner) == smp_processor_id();
>> +
>> +	/* Driver set this to memory recycling info. Reset it on recycle.
>> +	 * This will *not* work for NIC using a split-page memory model.
>> +	 * The page will be returned to the pool here regardless of the
>> +	 * 'flipped' fragment being in use or not.
>> +	 */
>> +	page_pool_put_full_page(pp, page, allow_direct);
>> +
>> +	return true;
>> +}
>> +EXPORT_SYMBOL(page_pool_return_skb_page);
>> +
>>  static bool skb_pp_recycle(struct sk_buff *skb, void *data, bool napi_safe)

(this one)

>>  {
>>  	if (!IS_ENABLED(CONFIG_PAGE_POOL) || !skb->pp_recycle)
>>

Thanks,
Olek
Yunsheng Lin July 29, 2023, 11:40 a.m. UTC | #3
On 2023/7/28 21:58, Alexander Lobakin wrote:
> From: Yunsheng Lin <linyunsheng@huawei.com>
> Date: Fri, 28 Jul 2023 20:02:51 +0800
> 
>> On 2023/7/27 22:43, Alexander Lobakin wrote:
>>> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
>>
>> ...
>>
>>> +bool page_pool_return_skb_page(struct page *page, bool napi_safe)
>>
>> Still having the 'page_pool_' prefix seems odd here when it is in the
>> skbuff.c where most have skb_ or napi_ prefix, is it better to rename
>> it to something like napi_return_page_pool_page()?
> 
> Given that how the function that goes next is named, maybe
> skb_pp_return_page() (or skb_pp_put_page())?

skb_pp_put_page() seems better.

And I like napi_pp_put_page() with 'napi_' prefix better as
it does not take a skb as parameter and the naming is aligned
with the 'napi_safe' parameter.

> 
>>
>>> +{
>>> +	struct napi_struct *napi;
>>> +	struct page_pool *pp;
>>> +	bool allow_direct;
>>> +
>>> +	page = compound_head(page);
>>> +
>>> +	/* 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((page->pp_magic & ~0x3UL) != PP_SIGNATURE))
>>> +		return false;
>>> +
>>> +	pp = page->pp;
>>> +
>>> +	/* Allow direct recycle if we have reasons to believe that we are
>>> +	 * in the same context as the consumer would run, so there's
>>> +	 * no possible race.
>>> +	 */
>>> +	napi = READ_ONCE(pp->p.napi);
>>> +	allow_direct = napi_safe && napi &&
>>> +		READ_ONCE(napi->list_owner) == smp_processor_id();
>>> +
>>> +	/* Driver set this to memory recycling info. Reset it on recycle.
>>> +	 * This will *not* work for NIC using a split-page memory model.
>>> +	 * The page will be returned to the pool here regardless of the
>>> +	 * 'flipped' fragment being in use or not.
>>> +	 */
>>> +	page_pool_put_full_page(pp, page, allow_direct);
>>> +
>>> +	return true;
>>> +}
>>> +EXPORT_SYMBOL(page_pool_return_skb_page);
>>> +
>>>  static bool skb_pp_recycle(struct sk_buff *skb, void *data, bool napi_safe)
> 
> (this one)
> 
>>>  {
>>>  	if (!IS_ENABLED(CONFIG_PAGE_POOL) || !skb->pp_recycle)

We may need the 'IS_ENABLED(CONFIG_PAGE_POOL' checking in the newly
moved function too.

>>>
> 
> Thanks,
> Olek
> 
> .
>
Alexander Lobakin Aug. 1, 2023, 1:25 p.m. UTC | #4
From: Yunsheng Lin <linyunsheng@huawei.com>
Date: Sat, 29 Jul 2023 19:40:19 +0800

> On 2023/7/28 21:58, Alexander Lobakin wrote:
>> From: Yunsheng Lin <linyunsheng@huawei.com>
>> Date: Fri, 28 Jul 2023 20:02:51 +0800
>>
>>> On 2023/7/27 22:43, Alexander Lobakin wrote:
>>>> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
>>>
>>> ...
>>>
>>>> +bool page_pool_return_skb_page(struct page *page, bool napi_safe)
>>>
>>> Still having the 'page_pool_' prefix seems odd here when it is in the
>>> skbuff.c where most have skb_ or napi_ prefix, is it better to rename
>>> it to something like napi_return_page_pool_page()?
>>
>> Given that how the function that goes next is named, maybe
>> skb_pp_return_page() (or skb_pp_put_page())?
> 
> skb_pp_put_page() seems better.
> 
> And I like napi_pp_put_page() with 'napi_' prefix better as
> it does not take a skb as parameter and the naming is aligned
> with the 'napi_safe' parameter.

Ah, I see. Sounds reasonable. I'll pick napi_pp_put_page() for the next
round, I like this one.

> 
>>
>>>
>>>> +{
>>>> +	struct napi_struct *napi;
>>>> +	struct page_pool *pp;
>>>> +	bool allow_direct;
>>>> +
>>>> +	page = compound_head(page);
>>>> +
>>>> +	/* 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((page->pp_magic & ~0x3UL) != PP_SIGNATURE))
>>>> +		return false;
>>>> +
>>>> +	pp = page->pp;
>>>> +
>>>> +	/* Allow direct recycle if we have reasons to believe that we are
>>>> +	 * in the same context as the consumer would run, so there's
>>>> +	 * no possible race.
>>>> +	 */
>>>> +	napi = READ_ONCE(pp->p.napi);
>>>> +	allow_direct = napi_safe && napi &&
>>>> +		READ_ONCE(napi->list_owner) == smp_processor_id();
>>>> +
>>>> +	/* Driver set this to memory recycling info. Reset it on recycle.
>>>> +	 * This will *not* work for NIC using a split-page memory model.
>>>> +	 * The page will be returned to the pool here regardless of the
>>>> +	 * 'flipped' fragment being in use or not.
>>>> +	 */
>>>> +	page_pool_put_full_page(pp, page, allow_direct);
>>>> +
>>>> +	return true;
>>>> +}
>>>> +EXPORT_SYMBOL(page_pool_return_skb_page);
>>>> +
>>>>  static bool skb_pp_recycle(struct sk_buff *skb, void *data, bool napi_safe)
>>
>> (this one)
>>
>>>>  {
>>>>  	if (!IS_ENABLED(CONFIG_PAGE_POOL) || !skb->pp_recycle)
> 
> We may need the 'IS_ENABLED(CONFIG_PAGE_POOL' checking in the newly
> moved function too.

The first person who noticed this, for sure we should have it!

> 
>>>>
>>
>> Thanks,
>> Olek
>>
>> .
>>

Thanks,
Olek
diff mbox series

Patch

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 888e3d7e74c1..7effd94efd6c 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -32,7 +32,6 @@ 
 #include <linux/if_packet.h>
 #include <linux/llist.h>
 #include <net/flow.h>
-#include <net/page_pool/types.h>
 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
 #include <linux/netfilter/nf_conntrack_common.h>
 #endif
@@ -3421,6 +3420,8 @@  static inline void skb_frag_ref(struct sk_buff *skb, int f)
 	__skb_frag_ref(&skb_shinfo(skb)->frags[f]);
 }
 
+bool page_pool_return_skb_page(struct page *page, bool napi_safe);
+
 static inline void
 napi_frag_unref(skb_frag_t *frag, bool recycle, bool napi_safe)
 {
diff --git a/include/net/page_pool/types.h b/include/net/page_pool/types.h
index 4a0270291deb..c7aef6c75935 100644
--- a/include/net/page_pool/types.h
+++ b/include/net/page_pool/types.h
@@ -156,8 +156,6 @@  struct page_pool {
 struct page *page_pool_alloc_pages(struct page_pool *pool, gfp_t gfp);
 struct page *page_pool_alloc_frag(struct page_pool *pool, unsigned int *offset,
 				  unsigned int size, gfp_t gfp);
-bool page_pool_return_skb_page(struct page *page, bool napi_safe);
-
 struct page_pool *page_pool_create(const struct page_pool_params *params);
 
 struct xdp_mem_info;
diff --git a/net/core/page_pool.c b/net/core/page_pool.c
index 2a75f61264c5..7a23ca6b1124 100644
--- a/net/core/page_pool.c
+++ b/net/core/page_pool.c
@@ -906,42 +906,3 @@  void page_pool_update_nid(struct page_pool *pool, int new_nid)
 	}
 }
 EXPORT_SYMBOL(page_pool_update_nid);
-
-bool page_pool_return_skb_page(struct page *page, bool napi_safe)
-{
-	struct napi_struct *napi;
-	struct page_pool *pp;
-	bool allow_direct;
-
-	page = compound_head(page);
-
-	/* 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((page->pp_magic & ~0x3UL) != PP_SIGNATURE))
-		return false;
-
-	pp = page->pp;
-
-	/* Allow direct recycle if we have reasons to believe that we are
-	 * in the same context as the consumer would run, so there's
-	 * no possible race.
-	 */
-	napi = READ_ONCE(pp->p.napi);
-	allow_direct = napi_safe && napi &&
-		READ_ONCE(napi->list_owner) == smp_processor_id();
-
-	/* Driver set this to memory recycling info. Reset it on recycle.
-	 * This will *not* work for NIC using a split-page memory model.
-	 * The page will be returned to the pool here regardless of the
-	 * 'flipped' fragment being in use or not.
-	 */
-	page_pool_put_full_page(pp, page, allow_direct);
-
-	return true;
-}
-EXPORT_SYMBOL(page_pool_return_skb_page);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index ac8f421f8ab3..3084ef59400b 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -73,7 +73,7 @@ 
 #include <net/mpls.h>
 #include <net/mptcp.h>
 #include <net/mctp.h>
-#include <net/page_pool/types.h>
+#include <net/page_pool/helpers.h>
 #include <net/dropreason.h>
 
 #include <linux/uaccess.h>
@@ -879,6 +879,45 @@  static void skb_clone_fraglist(struct sk_buff *skb)
 		skb_get(list);
 }
 
+bool page_pool_return_skb_page(struct page *page, bool napi_safe)
+{
+	struct napi_struct *napi;
+	struct page_pool *pp;
+	bool allow_direct;
+
+	page = compound_head(page);
+
+	/* 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((page->pp_magic & ~0x3UL) != PP_SIGNATURE))
+		return false;
+
+	pp = page->pp;
+
+	/* Allow direct recycle if we have reasons to believe that we are
+	 * in the same context as the consumer would run, so there's
+	 * no possible race.
+	 */
+	napi = READ_ONCE(pp->p.napi);
+	allow_direct = napi_safe && napi &&
+		READ_ONCE(napi->list_owner) == smp_processor_id();
+
+	/* Driver set this to memory recycling info. Reset it on recycle.
+	 * This will *not* work for NIC using a split-page memory model.
+	 * The page will be returned to the pool here regardless of the
+	 * 'flipped' fragment being in use or not.
+	 */
+	page_pool_put_full_page(pp, page, allow_direct);
+
+	return true;
+}
+EXPORT_SYMBOL(page_pool_return_skb_page);
+
 static bool skb_pp_recycle(struct sk_buff *skb, void *data, bool napi_safe)
 {
 	if (!IS_ENABLED(CONFIG_PAGE_POOL) || !skb->pp_recycle)