kfd_svm.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /* SPDX-License-Identifier: GPL-2.0 OR MIT */
  2. /*
  3. * Copyright 2020-2021 Advanced Micro Devices, Inc.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the "Software"),
  7. * to deal in the Software without restriction, including without limitation
  8. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. * and/or sell copies of the Software, and to permit persons to whom the
  10. * Software is furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  19. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21. * OTHER DEALINGS IN THE SOFTWARE.
  22. *
  23. */
  24. #ifndef KFD_SVM_H_
  25. #define KFD_SVM_H_
  26. #if IS_ENABLED(CONFIG_HSA_AMD_SVM)
  27. #include <linux/rwsem.h>
  28. #include <linux/list.h>
  29. #include <linux/mutex.h>
  30. #include <linux/sched/mm.h>
  31. #include <linux/hmm.h>
  32. #include "amdgpu.h"
  33. #include "kfd_priv.h"
  34. #define SVM_RANGE_VRAM_DOMAIN (1UL << 0)
  35. #define SVM_ADEV_PGMAP_OWNER(adev)\
  36. ((adev)->hive ? (void *)(adev)->hive : (void *)(adev))
  37. struct svm_range_bo {
  38. struct amdgpu_bo *bo;
  39. struct kref kref;
  40. struct list_head range_list; /* all svm ranges shared this bo */
  41. spinlock_t list_lock;
  42. struct amdgpu_amdkfd_fence *eviction_fence;
  43. struct work_struct eviction_work;
  44. uint32_t evicting;
  45. struct work_struct release_work;
  46. struct kfd_node *node;
  47. };
  48. enum svm_work_list_ops {
  49. SVM_OP_NULL,
  50. SVM_OP_UNMAP_RANGE,
  51. SVM_OP_UPDATE_RANGE_NOTIFIER,
  52. SVM_OP_UPDATE_RANGE_NOTIFIER_AND_MAP,
  53. SVM_OP_ADD_RANGE,
  54. SVM_OP_ADD_RANGE_AND_MAP
  55. };
  56. struct svm_work_list_item {
  57. enum svm_work_list_ops op;
  58. struct mm_struct *mm;
  59. };
  60. /**
  61. * struct svm_range - shared virtual memory range
  62. *
  63. * @svms: list of svm ranges, structure defined in kfd_process
  64. * @migrate_mutex: to serialize range migration, validation and mapping update
  65. * @start: range start address in pages
  66. * @last: range last address in pages
  67. * @it_node: node [start, last] stored in interval tree, start, last are page
  68. * aligned, page size is (last - start + 1)
  69. * @list: link list node, used to scan all ranges of svms
  70. * @update_list:link list node used to add to update_list
  71. * @mapping: bo_va mapping structure to create and update GPU page table
  72. * @npages: number of pages
  73. * @vram_pages: vram pages number in this svm_range
  74. * @dma_addr: dma mapping address on each GPU for system memory physical page
  75. * @ttm_res: vram ttm resource map
  76. * @offset: range start offset within mm_nodes
  77. * @svm_bo: struct to manage splited amdgpu_bo
  78. * @svm_bo_list:link list node, to scan all ranges which share same svm_bo
  79. * @lock: protect prange start, last, child_list, svm_bo_list
  80. * @saved_flags:save/restore current PF_MEMALLOC flags
  81. * @flags: flags defined as KFD_IOCTL_SVM_FLAG_*
  82. * @perferred_loc: perferred location, 0 for CPU, or GPU id
  83. * @perfetch_loc: last prefetch location, 0 for CPU, or GPU id
  84. * @actual_loc: this svm_range location. 0: all pages are from sys ram;
  85. * GPU id: this svm_range may include vram pages from GPU with
  86. * id actual_loc.
  87. * @granularity:migration granularity, log2 num pages
  88. * @invalid: not 0 means cpu page table is invalidated
  89. * @validate_timestamp: system timestamp when range is validated
  90. * @notifier: register mmu interval notifier
  91. * @work_item: deferred work item information
  92. * @deferred_list: list header used to add range to deferred list
  93. * @child_list: list header for split ranges which are not added to svms yet
  94. * @bitmap_access: index bitmap of GPUs which can access the range
  95. * @bitmap_aip: index bitmap of GPUs which can access the range in place
  96. *
  97. * Data structure for virtual memory range shared by CPU and GPUs, it can be
  98. * allocated from system memory ram or device vram, and migrate from ram to vram
  99. * or from vram to ram.
  100. */
  101. struct svm_range {
  102. struct svm_range_list *svms;
  103. struct mutex migrate_mutex;
  104. unsigned long start;
  105. unsigned long last;
  106. struct interval_tree_node it_node;
  107. struct list_head list;
  108. struct list_head update_list;
  109. uint64_t npages;
  110. uint64_t vram_pages;
  111. dma_addr_t *dma_addr[MAX_GPU_INSTANCE];
  112. struct ttm_resource *ttm_res;
  113. uint64_t offset;
  114. struct svm_range_bo *svm_bo;
  115. struct list_head svm_bo_list;
  116. struct mutex lock;
  117. unsigned int saved_flags;
  118. uint32_t flags;
  119. uint32_t preferred_loc;
  120. uint32_t prefetch_loc;
  121. uint32_t actual_loc;
  122. uint8_t granularity;
  123. atomic_t invalid;
  124. ktime_t validate_timestamp;
  125. struct mmu_interval_notifier notifier;
  126. struct svm_work_list_item work_item;
  127. struct list_head deferred_list;
  128. struct list_head child_list;
  129. DECLARE_BITMAP(bitmap_access, MAX_GPU_INSTANCE);
  130. DECLARE_BITMAP(bitmap_aip, MAX_GPU_INSTANCE);
  131. bool mapped_to_gpu;
  132. atomic_t queue_refcount;
  133. };
  134. static inline void svm_range_lock(struct svm_range *prange)
  135. {
  136. mutex_lock(&prange->lock);
  137. prange->saved_flags = memalloc_noreclaim_save();
  138. }
  139. static inline void svm_range_unlock(struct svm_range *prange)
  140. {
  141. memalloc_noreclaim_restore(prange->saved_flags);
  142. mutex_unlock(&prange->lock);
  143. }
  144. static inline struct svm_range_bo *svm_range_bo_ref(struct svm_range_bo *svm_bo)
  145. {
  146. if (svm_bo)
  147. kref_get(&svm_bo->kref);
  148. return svm_bo;
  149. }
  150. int svm_range_list_init(struct kfd_process *p);
  151. void svm_range_list_fini(struct kfd_process *p);
  152. int svm_ioctl(struct kfd_process *p, enum kfd_ioctl_svm_op op, uint64_t start,
  153. uint64_t size, uint32_t nattrs,
  154. struct kfd_ioctl_svm_attribute *attrs);
  155. struct svm_range *svm_range_from_addr(struct svm_range_list *svms,
  156. unsigned long addr,
  157. struct svm_range **parent);
  158. struct kfd_node *svm_range_get_node_by_id(struct svm_range *prange,
  159. uint32_t gpu_id);
  160. int svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange,
  161. bool clear);
  162. void svm_range_vram_node_free(struct svm_range *prange);
  163. int svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
  164. uint32_t vmid, uint32_t node_id, uint64_t addr, uint64_t ts,
  165. bool write_fault);
  166. int svm_range_schedule_evict_svm_bo(struct amdgpu_amdkfd_fence *fence);
  167. void svm_range_add_list_work(struct svm_range_list *svms,
  168. struct svm_range *prange, struct mm_struct *mm,
  169. enum svm_work_list_ops op);
  170. void schedule_deferred_list_work(struct svm_range_list *svms);
  171. void svm_range_dma_unmap_dev(struct device *dev, dma_addr_t *dma_addr,
  172. unsigned long offset, unsigned long npages);
  173. void svm_range_dma_unmap(struct svm_range *prange);
  174. int svm_range_get_info(struct kfd_process *p, uint32_t *num_svm_ranges,
  175. uint64_t *svm_priv_data_size);
  176. int kfd_criu_checkpoint_svm(struct kfd_process *p,
  177. uint8_t __user *user_priv_data,
  178. uint64_t *priv_offset);
  179. int kfd_criu_restore_svm(struct kfd_process *p,
  180. uint8_t __user *user_priv_ptr,
  181. uint64_t *priv_data_offset,
  182. uint64_t max_priv_data_size);
  183. int kfd_criu_resume_svm(struct kfd_process *p);
  184. struct kfd_process_device *
  185. svm_range_get_pdd_by_node(struct svm_range *prange, struct kfd_node *node);
  186. void svm_range_list_lock_and_flush_work(struct svm_range_list *svms, struct mm_struct *mm);
  187. /* SVM API and HMM page migration work together, device memory type
  188. * is initialized to not 0 when page migration register device memory.
  189. */
  190. #define KFD_IS_SVM_API_SUPPORTED(adev) ((adev)->kfd.pgmap.type != 0 ||\
  191. ((adev)->flags & AMD_IS_APU))
  192. void svm_range_bo_unref_async(struct svm_range_bo *svm_bo);
  193. void svm_range_set_max_pages(struct amdgpu_device *adev);
  194. int svm_range_switch_xnack_reserve_mem(struct kfd_process *p, bool xnack_enabled);
  195. #else
  196. struct kfd_process;
  197. static inline int svm_range_list_init(struct kfd_process *p)
  198. {
  199. return 0;
  200. }
  201. static inline void svm_range_list_fini(struct kfd_process *p)
  202. {
  203. /* empty */
  204. }
  205. static inline int svm_range_restore_pages(struct amdgpu_device *adev,
  206. unsigned int pasid,
  207. uint32_t client_id, uint32_t node_id,
  208. uint64_t addr, uint64_t ts, bool write_fault)
  209. {
  210. return -EFAULT;
  211. }
  212. static inline int svm_range_schedule_evict_svm_bo(
  213. struct amdgpu_amdkfd_fence *fence)
  214. {
  215. WARN_ONCE(1, "SVM eviction fence triggered, but SVM is disabled");
  216. return -EINVAL;
  217. }
  218. static inline int svm_range_get_info(struct kfd_process *p,
  219. uint32_t *num_svm_ranges,
  220. uint64_t *svm_priv_data_size)
  221. {
  222. *num_svm_ranges = 0;
  223. *svm_priv_data_size = 0;
  224. return 0;
  225. }
  226. static inline int kfd_criu_checkpoint_svm(struct kfd_process *p,
  227. uint8_t __user *user_priv_data,
  228. uint64_t *priv_offset)
  229. {
  230. return 0;
  231. }
  232. static inline int kfd_criu_restore_svm(struct kfd_process *p,
  233. uint8_t __user *user_priv_ptr,
  234. uint64_t *priv_data_offset,
  235. uint64_t max_priv_data_size)
  236. {
  237. return -EINVAL;
  238. }
  239. static inline int kfd_criu_resume_svm(struct kfd_process *p)
  240. {
  241. return 0;
  242. }
  243. static inline void svm_range_set_max_pages(struct amdgpu_device *adev)
  244. {
  245. }
  246. #define KFD_IS_SVM_API_SUPPORTED(dev) false
  247. #endif /* IS_ENABLED(CONFIG_HSA_AMD_SVM) */
  248. #endif /* KFD_SVM_H_ */