netmem.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /* SPDX-License-Identifier: GPL-2.0
  2. *
  3. * Network memory
  4. *
  5. * Author: Mina Almasry <almasrymina@google.com>
  6. */
  7. #ifndef _NET_NETMEM_H
  8. #define _NET_NETMEM_H
  9. #include <linux/dma-mapping.h>
  10. #include <linux/mm.h>
  11. #include <net/net_debug.h>
  12. /* These fields in struct page are used by the page_pool and net stack:
  13. *
  14. * struct {
  15. * unsigned long pp_magic;
  16. * struct page_pool *pp;
  17. * unsigned long _pp_mapping_pad;
  18. * unsigned long dma_addr;
  19. * atomic_long_t pp_ref_count;
  20. * };
  21. *
  22. * We mirror the page_pool fields here so the page_pool can access these
  23. * fields without worrying whether the underlying fields belong to a
  24. * page or netmem_desc.
  25. *
  26. * CAUTION: Do not update the fields in netmem_desc without also
  27. * updating the anonymous aliasing union in struct net_iov.
  28. */
  29. struct netmem_desc {
  30. unsigned long _flags;
  31. unsigned long pp_magic;
  32. struct page_pool *pp;
  33. unsigned long _pp_mapping_pad;
  34. unsigned long dma_addr;
  35. atomic_long_t pp_ref_count;
  36. };
  37. #define NETMEM_DESC_ASSERT_OFFSET(pg, desc) \
  38. static_assert(offsetof(struct page, pg) == \
  39. offsetof(struct netmem_desc, desc))
  40. NETMEM_DESC_ASSERT_OFFSET(flags, _flags);
  41. NETMEM_DESC_ASSERT_OFFSET(pp_magic, pp_magic);
  42. NETMEM_DESC_ASSERT_OFFSET(pp, pp);
  43. NETMEM_DESC_ASSERT_OFFSET(_pp_mapping_pad, _pp_mapping_pad);
  44. NETMEM_DESC_ASSERT_OFFSET(dma_addr, dma_addr);
  45. NETMEM_DESC_ASSERT_OFFSET(pp_ref_count, pp_ref_count);
  46. #undef NETMEM_DESC_ASSERT_OFFSET
  47. /*
  48. * Since struct netmem_desc uses the space in struct page, the size
  49. * should be checked, until struct netmem_desc has its own instance from
  50. * slab, to avoid conflicting with other members within struct page.
  51. */
  52. static_assert(sizeof(struct netmem_desc) <= offsetof(struct page, _refcount));
  53. /* net_iov */
  54. DECLARE_STATIC_KEY_FALSE(page_pool_mem_providers);
  55. /* We overload the LSB of the struct page pointer to indicate whether it's
  56. * a page or net_iov.
  57. */
  58. #define NET_IOV 0x01UL
  59. enum net_iov_type {
  60. NET_IOV_DMABUF,
  61. NET_IOV_IOURING,
  62. };
  63. /* A memory descriptor representing abstract networking I/O vectors,
  64. * generally for non-pages memory that doesn't have its corresponding
  65. * struct page and needs to be explicitly allocated through slab.
  66. *
  67. * net_iovs are allocated and used by networking code, and the size of
  68. * the chunk is PAGE_SIZE.
  69. *
  70. * This memory can be any form of non-struct paged memory. Examples
  71. * include imported dmabuf memory and imported io_uring memory. See
  72. * net_iov_type for all the supported types.
  73. *
  74. * @pp_magic: pp field, similar to the one in struct page/struct
  75. * netmem_desc.
  76. * @pp: the pp this net_iov belongs to, if any.
  77. * @dma_addr: the dma addrs of the net_iov. Needed for the network
  78. * card to send/receive this net_iov.
  79. * @pp_ref_count: the pp ref count of this net_iov, exactly the same
  80. * usage as struct page/struct netmem_desc.
  81. * @owner: the net_iov_area this net_iov belongs to, if any.
  82. * @type: the type of the memory. Different types of net_iovs are
  83. * supported.
  84. */
  85. struct net_iov {
  86. union {
  87. struct netmem_desc desc;
  88. /* XXX: The following part should be removed once all
  89. * the references to them are converted so as to be
  90. * accessed via netmem_desc e.g. niov->desc.pp instead
  91. * of niov->pp.
  92. */
  93. struct {
  94. unsigned long _flags;
  95. unsigned long pp_magic;
  96. struct page_pool *pp;
  97. unsigned long _pp_mapping_pad;
  98. unsigned long dma_addr;
  99. atomic_long_t pp_ref_count;
  100. };
  101. };
  102. struct net_iov_area *owner;
  103. enum net_iov_type type;
  104. };
  105. struct net_iov_area {
  106. /* Array of net_iovs for this area. */
  107. struct net_iov *niovs;
  108. size_t num_niovs;
  109. /* Offset into the dma-buf where this chunk starts. */
  110. unsigned long base_virtual;
  111. };
  112. /* net_iov is union'ed with struct netmem_desc mirroring struct page, so
  113. * the page_pool can access these fields without worrying whether the
  114. * underlying fields are accessed via netmem_desc or directly via
  115. * net_iov, until all the references to them are converted so as to be
  116. * accessed via netmem_desc e.g. niov->desc.pp instead of niov->pp.
  117. *
  118. * The non-net stack fields of struct page are private to the mm stack
  119. * and must never be mirrored to net_iov.
  120. */
  121. #define NET_IOV_ASSERT_OFFSET(desc, iov) \
  122. static_assert(offsetof(struct netmem_desc, desc) == \
  123. offsetof(struct net_iov, iov))
  124. NET_IOV_ASSERT_OFFSET(_flags, _flags);
  125. NET_IOV_ASSERT_OFFSET(pp_magic, pp_magic);
  126. NET_IOV_ASSERT_OFFSET(pp, pp);
  127. NET_IOV_ASSERT_OFFSET(_pp_mapping_pad, _pp_mapping_pad);
  128. NET_IOV_ASSERT_OFFSET(dma_addr, dma_addr);
  129. NET_IOV_ASSERT_OFFSET(pp_ref_count, pp_ref_count);
  130. #undef NET_IOV_ASSERT_OFFSET
  131. static inline struct net_iov_area *net_iov_owner(const struct net_iov *niov)
  132. {
  133. return niov->owner;
  134. }
  135. static inline unsigned int net_iov_idx(const struct net_iov *niov)
  136. {
  137. return niov - net_iov_owner(niov)->niovs;
  138. }
  139. /* netmem */
  140. /**
  141. * typedef netmem_ref - a nonexistent type marking a reference to generic
  142. * network memory.
  143. *
  144. * A netmem_ref can be a struct page* or a struct net_iov* underneath.
  145. *
  146. * Use the supplied helpers to obtain the underlying memory pointer and fields.
  147. */
  148. typedef unsigned long __bitwise netmem_ref;
  149. static inline bool netmem_is_net_iov(const netmem_ref netmem)
  150. {
  151. return (__force unsigned long)netmem & NET_IOV;
  152. }
  153. /**
  154. * __netmem_to_page - unsafely get pointer to the &page backing @netmem
  155. * @netmem: netmem reference to convert
  156. *
  157. * Unsafe version of netmem_to_page(). When @netmem is always page-backed,
  158. * e.g. when it's a header buffer, performs faster and generates smaller
  159. * object code (no check for the LSB, no WARN). When @netmem points to IOV,
  160. * provokes undefined behaviour.
  161. *
  162. * Return: pointer to the &page (garbage if @netmem is not page-backed).
  163. */
  164. static inline struct page *__netmem_to_page(netmem_ref netmem)
  165. {
  166. return (__force struct page *)netmem;
  167. }
  168. static inline struct page *netmem_to_page(netmem_ref netmem)
  169. {
  170. if (WARN_ON_ONCE(netmem_is_net_iov(netmem)))
  171. return NULL;
  172. return __netmem_to_page(netmem);
  173. }
  174. static inline struct net_iov *netmem_to_net_iov(netmem_ref netmem)
  175. {
  176. if (netmem_is_net_iov(netmem))
  177. return (struct net_iov *)((__force unsigned long)netmem &
  178. ~NET_IOV);
  179. DEBUG_NET_WARN_ON_ONCE(true);
  180. return NULL;
  181. }
  182. static inline netmem_ref net_iov_to_netmem(struct net_iov *niov)
  183. {
  184. return (__force netmem_ref)((unsigned long)niov | NET_IOV);
  185. }
  186. #define page_to_netmem(p) (_Generic((p), \
  187. const struct page * : (__force const netmem_ref)(p), \
  188. struct page * : (__force netmem_ref)(p)))
  189. /**
  190. * virt_to_netmem - convert virtual memory pointer to a netmem reference
  191. * @data: host memory pointer to convert
  192. *
  193. * Return: netmem reference to the &page backing this virtual address.
  194. */
  195. static inline netmem_ref virt_to_netmem(const void *data)
  196. {
  197. return page_to_netmem(virt_to_page(data));
  198. }
  199. static inline int netmem_ref_count(netmem_ref netmem)
  200. {
  201. /* The non-pp refcount of net_iov is always 1. On net_iov, we only
  202. * support pp refcounting which uses the pp_ref_count field.
  203. */
  204. if (netmem_is_net_iov(netmem))
  205. return 1;
  206. return page_ref_count(netmem_to_page(netmem));
  207. }
  208. static inline unsigned long netmem_pfn_trace(netmem_ref netmem)
  209. {
  210. if (netmem_is_net_iov(netmem))
  211. return 0;
  212. return page_to_pfn(netmem_to_page(netmem));
  213. }
  214. /* XXX: How to extract netmem_desc from page must be changed, once
  215. * netmem_desc no longer overlays on page and will be allocated through
  216. * slab.
  217. */
  218. #define __pp_page_to_nmdesc(p) (_Generic((p), \
  219. const struct page * : (const struct netmem_desc *)(p), \
  220. struct page * : (struct netmem_desc *)(p)))
  221. /* CAUTION: Check if the page is a pp page before calling this helper or
  222. * know it's a pp page.
  223. */
  224. #define pp_page_to_nmdesc(p) \
  225. ({ \
  226. DEBUG_NET_WARN_ON_ONCE(!page_pool_page_is_pp(p)); \
  227. __pp_page_to_nmdesc(p); \
  228. })
  229. /**
  230. * __netmem_to_nmdesc - unsafely get pointer to the &netmem_desc backing
  231. * @netmem
  232. * @netmem: netmem reference to convert
  233. *
  234. * Unsafe version that can be used only when @netmem is always backed by
  235. * system memory, performs faster and generates smaller object code (no
  236. * check for the LSB, no WARN). When @netmem points to IOV, provokes
  237. * undefined behaviour.
  238. *
  239. * Return: pointer to the &netmem_desc (garbage if @netmem is not backed
  240. * by system memory).
  241. */
  242. static inline struct netmem_desc *__netmem_to_nmdesc(netmem_ref netmem)
  243. {
  244. return (__force struct netmem_desc *)netmem;
  245. }
  246. /* netmem_to_nmdesc - convert netmem_ref to struct netmem_desc * for
  247. * access to common fields.
  248. * @netmem: netmem reference to get netmem_desc.
  249. *
  250. * All the sub types of netmem_ref (netmem_desc, net_iov) have the same
  251. * pp, pp_magic, dma_addr, and pp_ref_count fields via netmem_desc.
  252. *
  253. * Return: the pointer to struct netmem_desc * regardless of its
  254. * underlying type.
  255. */
  256. static inline struct netmem_desc *netmem_to_nmdesc(netmem_ref netmem)
  257. {
  258. void *p = (void *)((__force unsigned long)netmem & ~NET_IOV);
  259. if (netmem_is_net_iov(netmem))
  260. return &((struct net_iov *)p)->desc;
  261. return __pp_page_to_nmdesc((struct page *)p);
  262. }
  263. /**
  264. * __netmem_get_pp - unsafely get pointer to the &page_pool backing @netmem
  265. * @netmem: netmem reference to get the pointer from
  266. *
  267. * Unsafe version of netmem_get_pp(). When @netmem is always page-backed,
  268. * e.g. when it's a header buffer, performs faster and generates smaller
  269. * object code (avoids clearing the LSB). When @netmem points to IOV,
  270. * provokes invalid memory access.
  271. *
  272. * Return: pointer to the &page_pool (garbage if @netmem is not page-backed).
  273. */
  274. static inline struct page_pool *__netmem_get_pp(netmem_ref netmem)
  275. {
  276. return __netmem_to_nmdesc(netmem)->pp;
  277. }
  278. static inline struct page_pool *netmem_get_pp(netmem_ref netmem)
  279. {
  280. return netmem_to_nmdesc(netmem)->pp;
  281. }
  282. static inline atomic_long_t *netmem_get_pp_ref_count_ref(netmem_ref netmem)
  283. {
  284. return &netmem_to_nmdesc(netmem)->pp_ref_count;
  285. }
  286. static inline bool netmem_is_pref_nid(netmem_ref netmem, int pref_nid)
  287. {
  288. /* NUMA node preference only makes sense if we're allocating
  289. * system memory. Memory providers (which give us net_iovs)
  290. * choose for us.
  291. */
  292. if (netmem_is_net_iov(netmem))
  293. return true;
  294. return page_to_nid(netmem_to_page(netmem)) == pref_nid;
  295. }
  296. static inline netmem_ref netmem_compound_head(netmem_ref netmem)
  297. {
  298. /* niov are never compounded */
  299. if (netmem_is_net_iov(netmem))
  300. return netmem;
  301. return page_to_netmem(compound_head(netmem_to_page(netmem)));
  302. }
  303. /**
  304. * __netmem_address - unsafely get pointer to the memory backing @netmem
  305. * @netmem: netmem reference to get the pointer for
  306. *
  307. * Unsafe version of netmem_address(). When @netmem is always page-backed,
  308. * e.g. when it's a header buffer, performs faster and generates smaller
  309. * object code (no check for the LSB). When @netmem points to IOV, provokes
  310. * undefined behaviour.
  311. *
  312. * Return: pointer to the memory (garbage if @netmem is not page-backed).
  313. */
  314. static inline void *__netmem_address(netmem_ref netmem)
  315. {
  316. return page_address(__netmem_to_page(netmem));
  317. }
  318. static inline void *netmem_address(netmem_ref netmem)
  319. {
  320. if (netmem_is_net_iov(netmem))
  321. return NULL;
  322. return __netmem_address(netmem);
  323. }
  324. /**
  325. * netmem_is_pfmemalloc - check if @netmem was allocated under memory pressure
  326. * @netmem: netmem reference to check
  327. *
  328. * Return: true if @netmem is page-backed and the page was allocated under
  329. * memory pressure, false otherwise.
  330. */
  331. static inline bool netmem_is_pfmemalloc(netmem_ref netmem)
  332. {
  333. if (netmem_is_net_iov(netmem))
  334. return false;
  335. return page_is_pfmemalloc(netmem_to_page(netmem));
  336. }
  337. static inline unsigned long netmem_get_dma_addr(netmem_ref netmem)
  338. {
  339. return netmem_to_nmdesc(netmem)->dma_addr;
  340. }
  341. #if defined(CONFIG_NET_DEVMEM)
  342. static inline bool net_is_devmem_iov(const struct net_iov *niov)
  343. {
  344. return niov->type == NET_IOV_DMABUF;
  345. }
  346. #else
  347. static inline bool net_is_devmem_iov(const struct net_iov *niov)
  348. {
  349. return false;
  350. }
  351. #endif
  352. void __get_netmem(netmem_ref netmem);
  353. void __put_netmem(netmem_ref netmem);
  354. static __always_inline void get_netmem(netmem_ref netmem)
  355. {
  356. if (netmem_is_net_iov(netmem))
  357. __get_netmem(netmem);
  358. else
  359. get_page(netmem_to_page(netmem));
  360. }
  361. static __always_inline void put_netmem(netmem_ref netmem)
  362. {
  363. if (netmem_is_net_iov(netmem))
  364. __put_netmem(netmem);
  365. else
  366. put_page(netmem_to_page(netmem));
  367. }
  368. #define netmem_dma_unmap_addr_set(NETMEM, PTR, ADDR_NAME, VAL) \
  369. do { \
  370. if (!netmem_is_net_iov(NETMEM)) \
  371. dma_unmap_addr_set(PTR, ADDR_NAME, VAL); \
  372. else \
  373. dma_unmap_addr_set(PTR, ADDR_NAME, 0); \
  374. } while (0)
  375. static inline void netmem_dma_unmap_page_attrs(struct device *dev,
  376. dma_addr_t addr, size_t size,
  377. enum dma_data_direction dir,
  378. unsigned long attrs)
  379. {
  380. if (!addr)
  381. return;
  382. dma_unmap_page_attrs(dev, addr, size, dir, attrs);
  383. }
  384. #endif /* _NET_NETMEM_H */