ib_umem.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
  2. /*
  3. * Copyright (c) 2007 Cisco Systems. All rights reserved.
  4. * Copyright (c) 2020 Intel Corporation. All rights reserved.
  5. */
  6. #ifndef IB_UMEM_H
  7. #define IB_UMEM_H
  8. #include <linux/list.h>
  9. #include <linux/scatterlist.h>
  10. #include <linux/workqueue.h>
  11. #include <rdma/ib_verbs.h>
  12. struct ib_ucontext;
  13. struct ib_umem_odp;
  14. struct dma_buf_attach_ops;
  15. struct ib_umem {
  16. struct ib_device *ibdev;
  17. struct mm_struct *owning_mm;
  18. u64 iova;
  19. size_t length;
  20. unsigned long address;
  21. u32 writable : 1;
  22. u32 is_odp : 1;
  23. u32 is_dmabuf : 1;
  24. struct sg_append_table sgt_append;
  25. };
  26. struct ib_umem_dmabuf {
  27. struct ib_umem umem;
  28. struct dma_buf_attachment *attach;
  29. struct sg_table *sgt;
  30. struct scatterlist *first_sg;
  31. struct scatterlist *last_sg;
  32. unsigned long first_sg_offset;
  33. unsigned long last_sg_trim;
  34. void *private;
  35. u8 pinned : 1;
  36. u8 revoked : 1;
  37. };
  38. static inline struct ib_umem_dmabuf *to_ib_umem_dmabuf(struct ib_umem *umem)
  39. {
  40. return container_of(umem, struct ib_umem_dmabuf, umem);
  41. }
  42. /* Returns the offset of the umem start relative to the first page. */
  43. static inline int ib_umem_offset(struct ib_umem *umem)
  44. {
  45. return umem->address & ~PAGE_MASK;
  46. }
  47. static inline dma_addr_t ib_umem_start_dma_addr(struct ib_umem *umem)
  48. {
  49. return sg_dma_address(umem->sgt_append.sgt.sgl) + ib_umem_offset(umem);
  50. }
  51. static inline unsigned long ib_umem_dma_offset(struct ib_umem *umem,
  52. unsigned long pgsz)
  53. {
  54. return ib_umem_start_dma_addr(umem) & (pgsz - 1);
  55. }
  56. static inline size_t ib_umem_num_dma_blocks(struct ib_umem *umem,
  57. unsigned long pgsz)
  58. {
  59. return (size_t)((ALIGN(umem->iova + umem->length, pgsz) -
  60. ALIGN_DOWN(umem->iova, pgsz))) /
  61. pgsz;
  62. }
  63. static inline size_t ib_umem_num_pages(struct ib_umem *umem)
  64. {
  65. return ib_umem_num_dma_blocks(umem, PAGE_SIZE);
  66. }
  67. static inline void __rdma_umem_block_iter_start(struct ib_block_iter *biter,
  68. struct ib_umem *umem,
  69. unsigned long pgsz)
  70. {
  71. __rdma_block_iter_start(biter, umem->sgt_append.sgt.sgl,
  72. umem->sgt_append.sgt.nents, pgsz);
  73. biter->__sg_advance = ib_umem_offset(umem) & ~(pgsz - 1);
  74. biter->__sg_numblocks = ib_umem_num_dma_blocks(umem, pgsz);
  75. }
  76. static inline bool __rdma_umem_block_iter_next(struct ib_block_iter *biter)
  77. {
  78. return __rdma_block_iter_next(biter) && biter->__sg_numblocks--;
  79. }
  80. /**
  81. * rdma_umem_for_each_dma_block - iterate over contiguous DMA blocks of the umem
  82. * @umem: umem to iterate over
  83. * @pgsz: Page size to split the list into
  84. *
  85. * pgsz must be <= PAGE_SIZE or computed by ib_umem_find_best_pgsz(). The
  86. * returned DMA blocks will be aligned to pgsz and span the range:
  87. * ALIGN_DOWN(umem->address, pgsz) to ALIGN(umem->address + umem->length, pgsz)
  88. *
  89. * Performs exactly ib_umem_num_dma_blocks() iterations.
  90. */
  91. #define rdma_umem_for_each_dma_block(umem, biter, pgsz) \
  92. for (__rdma_umem_block_iter_start(biter, umem, pgsz); \
  93. __rdma_umem_block_iter_next(biter);)
  94. #ifdef CONFIG_INFINIBAND_USER_MEM
  95. struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr,
  96. size_t size, int access);
  97. void ib_umem_release(struct ib_umem *umem);
  98. int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset,
  99. size_t length);
  100. unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem,
  101. unsigned long pgsz_bitmap,
  102. unsigned long virt);
  103. /**
  104. * ib_umem_find_best_pgoff - Find best HW page size
  105. *
  106. * @umem: umem struct
  107. * @pgsz_bitmap bitmap of HW supported page sizes
  108. * @pgoff_bitmask: Mask of bits that can be represented with an offset
  109. *
  110. * This is very similar to ib_umem_find_best_pgsz() except instead of accepting
  111. * an IOVA it accepts a bitmask specifying what address bits can be represented
  112. * with a page offset.
  113. *
  114. * For instance if the HW has multiple page sizes, requires 64 byte alignemnt,
  115. * and can support aligned offsets up to 4032 then pgoff_bitmask would be
  116. * "111111000000".
  117. *
  118. * If the pgoff_bitmask requires either alignment in the low bit or an
  119. * unavailable page size for the high bits, this function returns 0.
  120. */
  121. static inline unsigned long ib_umem_find_best_pgoff(struct ib_umem *umem,
  122. unsigned long pgsz_bitmap,
  123. u64 pgoff_bitmask)
  124. {
  125. dma_addr_t dma_addr;
  126. dma_addr = ib_umem_start_dma_addr(umem);
  127. return ib_umem_find_best_pgsz(umem, pgsz_bitmap,
  128. dma_addr & pgoff_bitmask);
  129. }
  130. static inline bool ib_umem_is_contiguous(struct ib_umem *umem)
  131. {
  132. dma_addr_t dma_addr;
  133. unsigned long pgsz;
  134. /*
  135. * Select the smallest aligned page that can contain the whole umem if
  136. * it was contiguous.
  137. */
  138. dma_addr = ib_umem_start_dma_addr(umem);
  139. pgsz = roundup_pow_of_two((dma_addr ^ (umem->length - 1 + dma_addr)) + 1);
  140. return !!ib_umem_find_best_pgoff(umem, pgsz, U64_MAX);
  141. }
  142. struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device *device,
  143. unsigned long offset, size_t size,
  144. int fd, int access,
  145. const struct dma_buf_attach_ops *ops);
  146. struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
  147. unsigned long offset,
  148. size_t size, int fd,
  149. int access);
  150. struct ib_umem_dmabuf *
  151. ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
  152. struct device *dma_device,
  153. unsigned long offset, size_t size,
  154. int fd, int access);
  155. int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf);
  156. void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf);
  157. void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf);
  158. void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf);
  159. #else /* CONFIG_INFINIBAND_USER_MEM */
  160. #include <linux/err.h>
  161. static inline struct ib_umem *ib_umem_get(struct ib_device *device,
  162. unsigned long addr, size_t size,
  163. int access)
  164. {
  165. return ERR_PTR(-EOPNOTSUPP);
  166. }
  167. static inline void ib_umem_release(struct ib_umem *umem) { }
  168. static inline int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset,
  169. size_t length) {
  170. return -EOPNOTSUPP;
  171. }
  172. static inline unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem,
  173. unsigned long pgsz_bitmap,
  174. unsigned long virt)
  175. {
  176. return 0;
  177. }
  178. static inline unsigned long ib_umem_find_best_pgoff(struct ib_umem *umem,
  179. unsigned long pgsz_bitmap,
  180. u64 pgoff_bitmask)
  181. {
  182. return 0;
  183. }
  184. static inline
  185. struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device *device,
  186. unsigned long offset,
  187. size_t size, int fd,
  188. int access,
  189. struct dma_buf_attach_ops *ops)
  190. {
  191. return ERR_PTR(-EOPNOTSUPP);
  192. }
  193. static inline struct ib_umem_dmabuf *
  194. ib_umem_dmabuf_get_pinned(struct ib_device *device, unsigned long offset,
  195. size_t size, int fd, int access)
  196. {
  197. return ERR_PTR(-EOPNOTSUPP);
  198. }
  199. static inline struct ib_umem_dmabuf *
  200. ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
  201. struct device *dma_device,
  202. unsigned long offset, size_t size,
  203. int fd, int access)
  204. {
  205. return ERR_PTR(-EOPNOTSUPP);
  206. }
  207. static inline int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf)
  208. {
  209. return -EOPNOTSUPP;
  210. }
  211. static inline void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf) { }
  212. static inline void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf) { }
  213. static inline void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf) {}
  214. #endif /* CONFIG_INFINIBAND_USER_MEM */
  215. #endif /* IB_UMEM_H */