netmem.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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/mm.h>
  10. #include <net/net_debug.h>
  11. /* net_iov */
  12. DECLARE_STATIC_KEY_FALSE(page_pool_mem_providers);
  13. /* We overload the LSB of the struct page pointer to indicate whether it's
  14. * a page or net_iov.
  15. */
  16. #define NET_IOV 0x01UL
  17. struct net_iov {
  18. unsigned long __unused_padding;
  19. unsigned long pp_magic;
  20. struct page_pool *pp;
  21. struct dmabuf_genpool_chunk_owner *owner;
  22. unsigned long dma_addr;
  23. atomic_long_t pp_ref_count;
  24. };
  25. /* These fields in struct page are used by the page_pool and net stack:
  26. *
  27. * struct {
  28. * unsigned long pp_magic;
  29. * struct page_pool *pp;
  30. * unsigned long _pp_mapping_pad;
  31. * unsigned long dma_addr;
  32. * atomic_long_t pp_ref_count;
  33. * };
  34. *
  35. * We mirror the page_pool fields here so the page_pool can access these fields
  36. * without worrying whether the underlying fields belong to a page or net_iov.
  37. *
  38. * The non-net stack fields of struct page are private to the mm stack and must
  39. * never be mirrored to net_iov.
  40. */
  41. #define NET_IOV_ASSERT_OFFSET(pg, iov) \
  42. static_assert(offsetof(struct page, pg) == \
  43. offsetof(struct net_iov, iov))
  44. NET_IOV_ASSERT_OFFSET(pp_magic, pp_magic);
  45. NET_IOV_ASSERT_OFFSET(pp, pp);
  46. NET_IOV_ASSERT_OFFSET(dma_addr, dma_addr);
  47. NET_IOV_ASSERT_OFFSET(pp_ref_count, pp_ref_count);
  48. #undef NET_IOV_ASSERT_OFFSET
  49. /* netmem */
  50. /**
  51. * typedef netmem_ref - a nonexistent type marking a reference to generic
  52. * network memory.
  53. *
  54. * A netmem_ref currently is always a reference to a struct page. This
  55. * abstraction is introduced so support for new memory types can be added.
  56. *
  57. * Use the supplied helpers to obtain the underlying memory pointer and fields.
  58. */
  59. typedef unsigned long __bitwise netmem_ref;
  60. static inline bool netmem_is_net_iov(const netmem_ref netmem)
  61. {
  62. return (__force unsigned long)netmem & NET_IOV;
  63. }
  64. /* This conversion fails (returns NULL) if the netmem_ref is not struct page
  65. * backed.
  66. */
  67. static inline struct page *netmem_to_page(netmem_ref netmem)
  68. {
  69. if (WARN_ON_ONCE(netmem_is_net_iov(netmem)))
  70. return NULL;
  71. return (__force struct page *)netmem;
  72. }
  73. static inline struct net_iov *netmem_to_net_iov(netmem_ref netmem)
  74. {
  75. if (netmem_is_net_iov(netmem))
  76. return (struct net_iov *)((__force unsigned long)netmem &
  77. ~NET_IOV);
  78. DEBUG_NET_WARN_ON_ONCE(true);
  79. return NULL;
  80. }
  81. static inline netmem_ref net_iov_to_netmem(struct net_iov *niov)
  82. {
  83. return (__force netmem_ref)((unsigned long)niov | NET_IOV);
  84. }
  85. static inline netmem_ref page_to_netmem(struct page *page)
  86. {
  87. return (__force netmem_ref)page;
  88. }
  89. static inline int netmem_ref_count(netmem_ref netmem)
  90. {
  91. /* The non-pp refcount of net_iov is always 1. On net_iov, we only
  92. * support pp refcounting which uses the pp_ref_count field.
  93. */
  94. if (netmem_is_net_iov(netmem))
  95. return 1;
  96. return page_ref_count(netmem_to_page(netmem));
  97. }
  98. static inline unsigned long netmem_pfn_trace(netmem_ref netmem)
  99. {
  100. if (netmem_is_net_iov(netmem))
  101. return 0;
  102. return page_to_pfn(netmem_to_page(netmem));
  103. }
  104. static inline struct net_iov *__netmem_clear_lsb(netmem_ref netmem)
  105. {
  106. return (struct net_iov *)((__force unsigned long)netmem & ~NET_IOV);
  107. }
  108. static inline struct page_pool *netmem_get_pp(netmem_ref netmem)
  109. {
  110. return __netmem_clear_lsb(netmem)->pp;
  111. }
  112. static inline atomic_long_t *netmem_get_pp_ref_count_ref(netmem_ref netmem)
  113. {
  114. return &__netmem_clear_lsb(netmem)->pp_ref_count;
  115. }
  116. static inline bool netmem_is_pref_nid(netmem_ref netmem, int pref_nid)
  117. {
  118. /* NUMA node preference only makes sense if we're allocating
  119. * system memory. Memory providers (which give us net_iovs)
  120. * choose for us.
  121. */
  122. if (netmem_is_net_iov(netmem))
  123. return true;
  124. return page_to_nid(netmem_to_page(netmem)) == pref_nid;
  125. }
  126. static inline netmem_ref netmem_compound_head(netmem_ref netmem)
  127. {
  128. /* niov are never compounded */
  129. if (netmem_is_net_iov(netmem))
  130. return netmem;
  131. return page_to_netmem(compound_head(netmem_to_page(netmem)));
  132. }
  133. static inline void *netmem_address(netmem_ref netmem)
  134. {
  135. if (netmem_is_net_iov(netmem))
  136. return NULL;
  137. return page_address(netmem_to_page(netmem));
  138. }
  139. static inline unsigned long netmem_get_dma_addr(netmem_ref netmem)
  140. {
  141. return __netmem_clear_lsb(netmem)->dma_addr;
  142. }
  143. #endif /* _NET_NETMEM_H */