To eliminate the use of the page pool fields in struct page, the page pool code should use netmem descriptor and APIs instead. However, some code e.g. __netmem_to_page() is still used to access the page pool fields e.g. ->pp via struct page, which should be changed so as to access them via netmem descriptor, struct netmem_desc instead, since the fields no longer will be available in struct page. Introduce utility APIs to make them easy to use struct netmem_desc as descriptor. The APIs are: 1. __netmem_to_nmdesc(), to convert netmem_ref to struct netmem_desc, but unsafely without checking if it's net_iov or system memory. 2. netmem_to_nmdesc(), to convert netmem_ref to struct netmem_desc, safely with checking if it's net_iov or system memory. 3. nmdesc_to_page(), to convert struct netmem_desc to struct page, assuming struct netmem_desc overlays on struct page. 4. page_to_nmdesc(), to convert struct page to struct netmem_desc, assuming struct netmem_desc overlays on struct page, allowing only head page to be converted. 5. nmdesc_adress(), to get its virtual address corresponding to the struct netmem_desc. Signed-off-by: Byungchul Park --- include/net/netmem.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/include/net/netmem.h b/include/net/netmem.h index 535cf17b9134..ad9444be229a 100644 --- a/include/net/netmem.h +++ b/include/net/netmem.h @@ -198,6 +198,32 @@ static inline struct page *netmem_to_page(netmem_ref netmem) return __netmem_to_page(netmem); } +/** + * __netmem_to_nmdesc - unsafely get pointer to the &netmem_desc backing + * @netmem + * @netmem: netmem reference to convert + * + * Unsafe version of netmem_to_nmdesc(). When @netmem is always backed + * by system memory, performs faster and generates smaller object code + * (no check for the LSB, no WARN). When @netmem points to IOV, provokes + * undefined behaviour. + * + * Return: pointer to the &netmem_desc (garbage if @netmem is not backed + * by system memory). + */ +static inline struct netmem_desc *__netmem_to_nmdesc(netmem_ref netmem) +{ + return (__force struct netmem_desc *)netmem; +} + +static inline struct netmem_desc *netmem_to_nmdesc(netmem_ref netmem) +{ + if (WARN_ON_ONCE(netmem_is_net_iov(netmem))) + return NULL; + + return __netmem_to_nmdesc(netmem); +} + static inline struct net_iov *netmem_to_net_iov(netmem_ref netmem) { if (netmem_is_net_iov(netmem)) @@ -314,6 +340,21 @@ static inline netmem_ref netmem_compound_head(netmem_ref netmem) return page_to_netmem(compound_head(netmem_to_page(netmem))); } +#define nmdesc_to_page(nmdesc) (_Generic((nmdesc), \ + const struct netmem_desc * : (const struct page *)(nmdesc), \ + struct netmem_desc * : (struct page *)(nmdesc))) + +static inline struct netmem_desc *page_to_nmdesc(struct page *page) +{ + VM_BUG_ON_PAGE(PageTail(page), page); + return (struct netmem_desc *)page; +} + +static inline void *nmdesc_address(struct netmem_desc *nmdesc) +{ + return page_address(nmdesc_to_page(nmdesc)); +} + /** * __netmem_address - unsafely get pointer to the memory backing @netmem * @netmem: netmem reference to get the pointer for -- 2.17.1