]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
netmem, mlx4: access ->pp_ref_count through netmem_desc instead of page
authorByungchul Park <byungchul@sk.com>
Mon, 21 Jul 2025 02:18:26 +0000 (11:18 +0900)
committerJakub Kicinski <kuba@kernel.org>
Thu, 24 Jul 2025 00:46:54 +0000 (17:46 -0700)
To eliminate the use of struct page in page pool, the page pool users
should use netmem descriptor and APIs instead.

Make mlx4 access ->pp_ref_count through netmem_desc instead of page.

While at it, add a helper, pp_page_to_nmdesc() and __pp_page_to_nmdesc(),
that can be used to get netmem_desc from page only if it's a pp page.
For now that netmem_desc overlays on page, it can be achieved by just
casting, and use macro and _Generic to cover const casting as well.

Plus, change page_pool_page_is_pp() to check for 'const struct page *'
instead of 'struct page *' since it doesn't modify data and additionally
covers const type.

Signed-off-by: Byungchul Park <byungchul@sk.com>
Link: https://patch.msgid.link/20250721021835.63939-4-byungchul@sk.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlx4/en_rx.c
include/linux/mm.h
include/net/netmem.h

index b33285d755b90788316bb7088b08bb232d2e5d65..92a16ddb7d8653207b2afcda2b88c14135636457 100644 (file)
@@ -460,9 +460,11 @@ static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
 
                truesize += frag_info->frag_stride;
                if (frag_info->frag_stride == PAGE_SIZE / 2) {
+                       struct netmem_desc *desc = pp_page_to_nmdesc(page);
+
                        frags->page_offset ^= PAGE_SIZE / 2;
                        release = page_count(page) != 1 ||
-                                 atomic_long_read(&page->pp_ref_count) != 1 ||
+                                 atomic_long_read(&desc->pp_ref_count) != 1 ||
                                  page_is_pfmemalloc(page) ||
                                  page_to_nid(page) != numa_mem_id();
                } else if (!priv->rx_headroom) {
index fa538feaa8d953900bfef37e68e10f72a98141cb..ae50c1641bed7b3e18b81066c79b024fa5008804 100644 (file)
@@ -4178,12 +4178,12 @@ int arch_lock_shadow_stack_status(struct task_struct *t, unsigned long status);
 #define PP_MAGIC_MASK ~(PP_DMA_INDEX_MASK | 0x3UL)
 
 #ifdef CONFIG_PAGE_POOL
-static inline bool page_pool_page_is_pp(struct page *page)
+static inline bool page_pool_page_is_pp(const struct page *page)
 {
        return (page->pp_magic & PP_MAGIC_MASK) == PP_SIGNATURE;
 }
 #else
-static inline bool page_pool_page_is_pp(struct page *page)
+static inline bool page_pool_page_is_pp(const struct page *page)
 {
        return false;
 }
index 097bc74d9555429e1e2920900412f99ea1b6c6be..f7dacc9e75fd1073d36e284de21b6eee7a0e9ae8 100644 (file)
@@ -285,6 +285,23 @@ static inline struct net_iov *__netmem_clear_lsb(netmem_ref netmem)
        return (struct net_iov *)((__force unsigned long)netmem & ~NET_IOV);
 }
 
+/* XXX: How to extract netmem_desc from page must be changed, once
+ * netmem_desc no longer overlays on page and will be allocated through
+ * slab.
+ */
+#define __pp_page_to_nmdesc(p) (_Generic((p),                          \
+       const struct page * :   (const struct netmem_desc *)(p),        \
+       struct page * :         (struct netmem_desc *)(p)))
+
+/* CAUTION: Check if the page is a pp page before calling this helper or
+ * know it's a pp page.
+ */
+#define pp_page_to_nmdesc(p)                                           \
+({                                                                     \
+       DEBUG_NET_WARN_ON_ONCE(!page_pool_page_is_pp(p));               \
+       __pp_page_to_nmdesc(p);                                         \
+})
+
 /**
  * __netmem_get_pp - unsafely get pointer to the &page_pool backing @netmem
  * @netmem: netmem reference to get the pointer from