Re: [RFC PATCH net-next v7 06/14] page_pool: convert to use netmem
On Tue, Mar 26, 2024 at 3:51 PM Mina Almasry wrote: > > Abstrace the memory type from the page_pool so we can later add support > for new memory types. Convert the page_pool to use the new netmem type > abstraction, rather than use struct page directly. > > As of this patch the netmem type is a no-op abstraction: it's always a > struct page underneath. All the page pool internals are converted to > use struct netmem instead of struct page, and the page pool now exports > 2 APIs: > > 1. The existing struct page API. > 2. The new struct netmem API. > > Keeping the existing API is transitional; we do not want to refactor all > the current drivers using the page pool at once. > > The netmem abstraction is currently a no-op. The page_pool uses > page_to_netmem() to convert allocated pages to netmem, and uses > netmem_to_page() to convert the netmem back to pages to pass to mm APIs, > > Follow up patches to this series add non-paged netmem support to the > page_pool. This change is factored out on its own to limit the code > churn to this 1 patch, for ease of code review. > > Signed-off-by: Mina Almasry > > --- > > v6: > > - Rebased on top of the merged netmem_ref type. > > To: linux...@kvack.org It looks like this tag to add linux-mm did not work as intended. CCing linux-mm manually. > Cc: Matthew Wilcox > > --- > include/linux/skbuff.h | 4 +- > include/net/netmem.h | 15 ++ > include/net/page_pool/helpers.h | 122 + > include/net/page_pool/types.h| 17 +- > include/trace/events/page_pool.h | 29 +-- > net/bpf/test_run.c | 5 +- > net/core/page_pool.c | 303 +-- > net/core/skbuff.c| 7 +- > 8 files changed, 302 insertions(+), 200 deletions(-) > > diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h > index b945af8a6208..78659c8efa4e 100644 > --- a/include/linux/skbuff.h > +++ b/include/linux/skbuff.h > @@ -3521,7 +3521,7 @@ int skb_pp_cow_data(struct page_pool *pool, struct > sk_buff **pskb, > unsigned int headroom); > int skb_cow_data_for_xdp(struct page_pool *pool, struct sk_buff **pskb, > struct bpf_prog *prog); > -bool napi_pp_put_page(struct page *page, bool napi_safe); > +bool napi_pp_put_page(netmem_ref netmem, bool napi_safe); > > static inline void > skb_page_unref(const struct sk_buff *skb, struct page *page, bool napi_safe) > @@ -3539,7 +3539,7 @@ napi_frag_unref(skb_frag_t *frag, bool recycle, bool > napi_safe) > struct page *page = skb_frag_page(frag); > > #ifdef CONFIG_PAGE_POOL > - if (recycle && napi_pp_put_page(page, napi_safe)) > + if (recycle && napi_pp_put_page(page_to_netmem(page), napi_safe)) > return; > #endif > put_page(page); > diff --git a/include/net/netmem.h b/include/net/netmem.h > index ca17ea1d33f8..21f53b29e5fe 100644 > --- a/include/net/netmem.h > +++ b/include/net/netmem.h > @@ -88,4 +88,19 @@ static inline netmem_ref page_to_netmem(struct page *page) > return (__force netmem_ref)page; > } > > +static inline int netmem_ref_count(netmem_ref netmem) > +{ > + return page_ref_count(netmem_to_page(netmem)); > +} > + > +static inline unsigned long netmem_to_pfn(netmem_ref netmem) > +{ > + return page_to_pfn(netmem_to_page(netmem)); > +} > + > +static inline netmem_ref netmem_compound_head(netmem_ref netmem) > +{ > + return page_to_netmem(compound_head(netmem_to_page(netmem))); > +} > + > #endif /* _NET_NETMEM_H */ > diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h > index 1d397c1a0043..61814f91a458 100644 > --- a/include/net/page_pool/helpers.h > +++ b/include/net/page_pool/helpers.h > @@ -53,6 +53,8 @@ > #define _NET_PAGE_POOL_HELPERS_H > > #include > +#include > +#include > > #ifdef CONFIG_PAGE_POOL_STATS > /* Deprecated driver-facing API, use netlink instead */ > @@ -101,7 +103,7 @@ static inline struct page > *page_pool_dev_alloc_pages(struct page_pool *pool) > * Get a page fragment from the page allocator or page_pool caches. > * > * Return: > - * Return allocated page fragment, otherwise return NULL. > + * Return allocated page fragment, otherwise return 0. > */ > static inline struct page *page_pool_dev_alloc_frag(struct page_pool *pool, > unsigned int *offset, > @@ -112,22 +114,22 @@ static inline struct page > *page_pool_dev_alloc_frag(struct page_pool *pool, > return page_pool_alloc_frag(pool, offset, size, gfp); > } > > -static inline struct page *page_pool_alloc(struct page_pool *pool, > - unsigned int *offset, > - unsigned int *size, gfp_t gfp) > +static inline netmem_ref page_pool_alloc(struct page_pool *pool, > +unsigned int *offset, > +unsigned int *
[RFC PATCH net-next v7 06/14] page_pool: convert to use netmem
Abstrace the memory type from the page_pool so we can later add support for new memory types. Convert the page_pool to use the new netmem type abstraction, rather than use struct page directly. As of this patch the netmem type is a no-op abstraction: it's always a struct page underneath. All the page pool internals are converted to use struct netmem instead of struct page, and the page pool now exports 2 APIs: 1. The existing struct page API. 2. The new struct netmem API. Keeping the existing API is transitional; we do not want to refactor all the current drivers using the page pool at once. The netmem abstraction is currently a no-op. The page_pool uses page_to_netmem() to convert allocated pages to netmem, and uses netmem_to_page() to convert the netmem back to pages to pass to mm APIs, Follow up patches to this series add non-paged netmem support to the page_pool. This change is factored out on its own to limit the code churn to this 1 patch, for ease of code review. Signed-off-by: Mina Almasry --- v6: - Rebased on top of the merged netmem_ref type. To: linux...@kvack.org Cc: Matthew Wilcox --- include/linux/skbuff.h | 4 +- include/net/netmem.h | 15 ++ include/net/page_pool/helpers.h | 122 + include/net/page_pool/types.h| 17 +- include/trace/events/page_pool.h | 29 +-- net/bpf/test_run.c | 5 +- net/core/page_pool.c | 303 +-- net/core/skbuff.c| 7 +- 8 files changed, 302 insertions(+), 200 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index b945af8a6208..78659c8efa4e 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -3521,7 +3521,7 @@ int skb_pp_cow_data(struct page_pool *pool, struct sk_buff **pskb, unsigned int headroom); int skb_cow_data_for_xdp(struct page_pool *pool, struct sk_buff **pskb, struct bpf_prog *prog); -bool napi_pp_put_page(struct page *page, bool napi_safe); +bool napi_pp_put_page(netmem_ref netmem, bool napi_safe); static inline void skb_page_unref(const struct sk_buff *skb, struct page *page, bool napi_safe) @@ -3539,7 +3539,7 @@ napi_frag_unref(skb_frag_t *frag, bool recycle, bool napi_safe) struct page *page = skb_frag_page(frag); #ifdef CONFIG_PAGE_POOL - if (recycle && napi_pp_put_page(page, napi_safe)) + if (recycle && napi_pp_put_page(page_to_netmem(page), napi_safe)) return; #endif put_page(page); diff --git a/include/net/netmem.h b/include/net/netmem.h index ca17ea1d33f8..21f53b29e5fe 100644 --- a/include/net/netmem.h +++ b/include/net/netmem.h @@ -88,4 +88,19 @@ static inline netmem_ref page_to_netmem(struct page *page) return (__force netmem_ref)page; } +static inline int netmem_ref_count(netmem_ref netmem) +{ + return page_ref_count(netmem_to_page(netmem)); +} + +static inline unsigned long netmem_to_pfn(netmem_ref netmem) +{ + return page_to_pfn(netmem_to_page(netmem)); +} + +static inline netmem_ref netmem_compound_head(netmem_ref netmem) +{ + return page_to_netmem(compound_head(netmem_to_page(netmem))); +} + #endif /* _NET_NETMEM_H */ diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h index 1d397c1a0043..61814f91a458 100644 --- a/include/net/page_pool/helpers.h +++ b/include/net/page_pool/helpers.h @@ -53,6 +53,8 @@ #define _NET_PAGE_POOL_HELPERS_H #include +#include +#include #ifdef CONFIG_PAGE_POOL_STATS /* Deprecated driver-facing API, use netlink instead */ @@ -101,7 +103,7 @@ static inline struct page *page_pool_dev_alloc_pages(struct page_pool *pool) * Get a page fragment from the page allocator or page_pool caches. * * Return: - * Return allocated page fragment, otherwise return NULL. + * Return allocated page fragment, otherwise return 0. */ static inline struct page *page_pool_dev_alloc_frag(struct page_pool *pool, unsigned int *offset, @@ -112,22 +114,22 @@ static inline struct page *page_pool_dev_alloc_frag(struct page_pool *pool, return page_pool_alloc_frag(pool, offset, size, gfp); } -static inline struct page *page_pool_alloc(struct page_pool *pool, - unsigned int *offset, - unsigned int *size, gfp_t gfp) +static inline netmem_ref page_pool_alloc(struct page_pool *pool, +unsigned int *offset, +unsigned int *size, gfp_t gfp) { unsigned int max_size = PAGE_SIZE << pool->p.order; - struct page *page; + netmem_ref netmem; if ((*size << 1) > max_size) { *size = max_size; *offset = 0; - return page_pool_alloc_pages(pool, gfp); + return page_pool_alloc_netmem(pool, gfp); } - page