]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
netmem: replace __netmem_clear_lsb() with netmem_to_nmdesc()
authorByungchul Park <byungchul@sk.com>
Mon, 13 Oct 2025 04:41:33 +0000 (13:41 +0900)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 14 Oct 2025 11:37:26 +0000 (13:37 +0200)
Now that we have struct netmem_desc, it'd better access the pp fields
via struct netmem_desc rather than struct net_iov.

Introduce netmem_to_nmdesc() for safely converting netmem_ref to
netmem_desc regardless of the type underneath e.i. netmem_desc, net_iov.

While at it, remove __netmem_clear_lsb() and make netmem_to_nmdesc()
used instead.

Suggested-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Byungchul Park <byungchul@sk.com>
Reviewed-by: Mina Almasry <almasrymina@google.com>
Link: https://patch.msgid.link/20251013044133.69472-1-byungchul@sk.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
include/net/netmem.h
net/core/netmem_priv.h

index f7dacc9e75fd1073d36e284de21b6eee7a0e9ae8..651e2c62d1dde2a6960c05c9e09c379943a4accd 100644 (file)
@@ -247,6 +247,23 @@ static inline unsigned long netmem_pfn_trace(netmem_ref netmem)
        return page_to_pfn(netmem_to_page(netmem));
 }
 
+/* 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_to_nmdesc - unsafely get pointer to the &netmem_desc backing
  * @netmem
@@ -265,42 +282,25 @@ static inline struct netmem_desc *__netmem_to_nmdesc(netmem_ref netmem)
        return (__force struct netmem_desc *)netmem;
 }
 
-/* __netmem_clear_lsb - convert netmem_ref to struct net_iov * for access to
- * common fields.
- * @netmem: netmem reference to extract as net_iov.
- *
- * All the sub types of netmem_ref (page, net_iov) have the same pp, pp_magic,
- * dma_addr, and pp_ref_count fields at the same offsets. Thus, we can access
- * these fields without a type check to make sure that the underlying mem is
- * net_iov or page.
+/* netmem_to_nmdesc - convert netmem_ref to struct netmem_desc * for
+ * access to common fields.
+ * @netmem: netmem reference to get netmem_desc.
  *
- * The resulting value of this function can only be used to access the fields
- * that are NET_IOV_ASSERT_OFFSET'd. Accessing any other fields will result in
- * undefined behavior.
+ * All the sub types of netmem_ref (netmem_desc, net_iov) have the same
+ * pp, pp_magic, dma_addr, and pp_ref_count fields via netmem_desc.
  *
- * Return: the netmem_ref cast to net_iov* regardless of its underlying type.
+ * Return: the pointer to struct netmem_desc * regardless of its
+ * underlying type.
  */
-static inline struct net_iov *__netmem_clear_lsb(netmem_ref netmem)
+static inline struct netmem_desc *netmem_to_nmdesc(netmem_ref netmem)
 {
-       return (struct net_iov *)((__force unsigned long)netmem & ~NET_IOV);
-}
+       void *p = (void *)((__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)))
+       if (netmem_is_net_iov(netmem))
+               return &((struct net_iov *)p)->desc;
 
-/* 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);                                         \
-})
+       return __pp_page_to_nmdesc((struct page *)p);
+}
 
 /**
  * __netmem_get_pp - unsafely get pointer to the &page_pool backing @netmem
@@ -320,12 +320,12 @@ static inline struct page_pool *__netmem_get_pp(netmem_ref netmem)
 
 static inline struct page_pool *netmem_get_pp(netmem_ref netmem)
 {
-       return __netmem_clear_lsb(netmem)->pp;
+       return netmem_to_nmdesc(netmem)->pp;
 }
 
 static inline atomic_long_t *netmem_get_pp_ref_count_ref(netmem_ref netmem)
 {
-       return &__netmem_clear_lsb(netmem)->pp_ref_count;
+       return &netmem_to_nmdesc(netmem)->pp_ref_count;
 }
 
 static inline bool netmem_is_pref_nid(netmem_ref netmem, int pref_nid)
@@ -390,7 +390,7 @@ static inline bool netmem_is_pfmemalloc(netmem_ref netmem)
 
 static inline unsigned long netmem_get_dma_addr(netmem_ref netmem)
 {
-       return __netmem_clear_lsb(netmem)->dma_addr;
+       return netmem_to_nmdesc(netmem)->dma_addr;
 }
 
 void get_netmem(netmem_ref netmem);
index cd95394399b40c3604934ba7898eeeeacb8aee99..23175cb2bd86688c2ecd0978336949955734c9dd 100644 (file)
@@ -5,19 +5,19 @@
 
 static inline unsigned long netmem_get_pp_magic(netmem_ref netmem)
 {
-       return __netmem_clear_lsb(netmem)->pp_magic & ~PP_DMA_INDEX_MASK;
+       return netmem_to_nmdesc(netmem)->pp_magic & ~PP_DMA_INDEX_MASK;
 }
 
 static inline void netmem_or_pp_magic(netmem_ref netmem, unsigned long pp_magic)
 {
-       __netmem_clear_lsb(netmem)->pp_magic |= pp_magic;
+       netmem_to_nmdesc(netmem)->pp_magic |= pp_magic;
 }
 
 static inline void netmem_clear_pp_magic(netmem_ref netmem)
 {
-       WARN_ON_ONCE(__netmem_clear_lsb(netmem)->pp_magic & PP_DMA_INDEX_MASK);
+       WARN_ON_ONCE(netmem_to_nmdesc(netmem)->pp_magic & PP_DMA_INDEX_MASK);
 
-       __netmem_clear_lsb(netmem)->pp_magic = 0;
+       netmem_to_nmdesc(netmem)->pp_magic = 0;
 }
 
 static inline bool netmem_is_pp(netmem_ref netmem)
@@ -27,13 +27,13 @@ static inline bool netmem_is_pp(netmem_ref netmem)
 
 static inline void netmem_set_pp(netmem_ref netmem, struct page_pool *pool)
 {
-       __netmem_clear_lsb(netmem)->pp = pool;
+       netmem_to_nmdesc(netmem)->pp = pool;
 }
 
 static inline void netmem_set_dma_addr(netmem_ref netmem,
                                       unsigned long dma_addr)
 {
-       __netmem_clear_lsb(netmem)->dma_addr = dma_addr;
+       netmem_to_nmdesc(netmem)->dma_addr = dma_addr;
 }
 
 static inline unsigned long netmem_get_dma_index(netmem_ref netmem)
@@ -43,7 +43,7 @@ static inline unsigned long netmem_get_dma_index(netmem_ref netmem)
        if (WARN_ON_ONCE(netmem_is_net_iov(netmem)))
                return 0;
 
-       magic = __netmem_clear_lsb(netmem)->pp_magic;
+       magic = netmem_to_nmdesc(netmem)->pp_magic;
 
        return (magic & PP_DMA_INDEX_MASK) >> PP_DMA_INDEX_SHIFT;
 }
@@ -57,6 +57,6 @@ static inline void netmem_set_dma_index(netmem_ref netmem,
                return;
 
        magic = netmem_get_pp_magic(netmem) | (id << PP_DMA_INDEX_SHIFT);
-       __netmem_clear_lsb(netmem)->pp_magic = magic;
+       netmem_to_nmdesc(netmem)->pp_magic = magic;
 }
 #endif