netmem: replace __netmem_clear_lsb() with netmem_to_nmdesc()

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>
This commit is contained in:
Byungchul Park
2025-10-13 13:41:33 +09:00
committed by Paolo Abeni
parent 3dacc900c0
commit 53615ad26e
2 changed files with 42 additions and 42 deletions

View File

@@ -247,6 +247,23 @@ static inline unsigned long netmem_pfn_trace(netmem_ref netmem)
return page_to_pfn(netmem_to_page(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_to_nmdesc - unsafely get pointer to the &netmem_desc backing
* @netmem * @netmem
@@ -265,43 +282,26 @@ static inline struct netmem_desc *__netmem_to_nmdesc(netmem_ref netmem)
return (__force struct netmem_desc *)netmem; return (__force struct netmem_desc *)netmem;
} }
/* __netmem_clear_lsb - convert netmem_ref to struct net_iov * for access to /* netmem_to_nmdesc - convert netmem_ref to struct netmem_desc * for
* common fields. * access to common fields.
* @netmem: netmem reference to extract as net_iov. * @netmem: netmem reference to get netmem_desc.
* *
* All the sub types of netmem_ref (page, net_iov) have the same pp, pp_magic, * All the sub types of netmem_ref (netmem_desc, net_iov) have the same
* dma_addr, and pp_ref_count fields at the same offsets. Thus, we can access * pp, pp_magic, dma_addr, and pp_ref_count fields via netmem_desc.
* these fields without a type check to make sure that the underlying mem is
* net_iov or page.
* *
* The resulting value of this function can only be used to access the fields * Return: the pointer to struct netmem_desc * regardless of its
* that are NET_IOV_ASSERT_OFFSET'd. Accessing any other fields will result in * underlying type.
* undefined behavior.
*
* Return: the netmem_ref cast to net_iov* 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);
if (netmem_is_net_iov(netmem))
return &((struct net_iov *)p)->desc;
return __pp_page_to_nmdesc((struct page *)p);
} }
/* 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_get_pp - unsafely get pointer to the &page_pool backing @netmem
* @netmem: netmem reference to get the pointer from * @netmem: netmem reference to get the pointer from
@@ -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) 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) 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) 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) 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); void get_netmem(netmem_ref netmem);

View File

@@ -5,19 +5,19 @@
static inline unsigned long netmem_get_pp_magic(netmem_ref netmem) 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) 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) 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) 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) 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, static inline void netmem_set_dma_addr(netmem_ref netmem,
unsigned long dma_addr) 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) 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))) if (WARN_ON_ONCE(netmem_is_net_iov(netmem)))
return 0; 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; 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; return;
magic = netmem_get_pp_magic(netmem) | (id << PP_DMA_INDEX_SHIFT); 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 #endif