1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#ifndef KFD_SVM_H_
26#define KFD_SVM_H_
27
28#if IS_ENABLED(CONFIG_HSA_AMD_SVM)
29
30#include <linux/rwsem.h>
31#include <linux/list.h>
32#include <linux/mutex.h>
33#include <linux/sched/mm.h>
34#include <linux/hmm.h>
35#include "amdgpu.h"
36#include "kfd_priv.h"
37
38#define SVM_RANGE_VRAM_DOMAIN (1UL << 0)
39#define SVM_ADEV_PGMAP_OWNER(adev)\
40 ((adev)->hive ? (void *)(adev)->hive : (void *)(adev))
41
42struct svm_range_bo {
43 struct amdgpu_bo *bo;
44 struct kref kref;
45 struct list_head range_list;
46 spinlock_t list_lock;
47 struct amdgpu_amdkfd_fence *eviction_fence;
48 struct work_struct eviction_work;
49 struct svm_range_list *svms;
50 uint32_t evicting;
51 struct work_struct release_work;
52};
53
54enum svm_work_list_ops {
55 SVM_OP_NULL,
56 SVM_OP_UNMAP_RANGE,
57 SVM_OP_UPDATE_RANGE_NOTIFIER,
58 SVM_OP_UPDATE_RANGE_NOTIFIER_AND_MAP,
59 SVM_OP_ADD_RANGE,
60 SVM_OP_ADD_RANGE_AND_MAP
61};
62
63struct svm_work_list_item {
64 enum svm_work_list_ops op;
65 struct mm_struct *mm;
66};
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106struct svm_range {
107 struct svm_range_list *svms;
108 struct mutex migrate_mutex;
109 unsigned long start;
110 unsigned long last;
111 struct interval_tree_node it_node;
112 struct list_head list;
113 struct list_head update_list;
114 uint64_t npages;
115 dma_addr_t *dma_addr[MAX_GPU_INSTANCE];
116 struct ttm_resource *ttm_res;
117 uint64_t offset;
118 struct svm_range_bo *svm_bo;
119 struct list_head svm_bo_list;
120 struct mutex lock;
121 unsigned int saved_flags;
122 uint32_t flags;
123 uint32_t preferred_loc;
124 uint32_t prefetch_loc;
125 uint32_t actual_loc;
126 uint8_t granularity;
127 atomic_t invalid;
128 uint64_t validate_timestamp;
129 struct mmu_interval_notifier notifier;
130 struct svm_work_list_item work_item;
131 struct list_head deferred_list;
132 struct list_head child_list;
133 DECLARE_BITMAP(bitmap_access, MAX_GPU_INSTANCE);
134 DECLARE_BITMAP(bitmap_aip, MAX_GPU_INSTANCE);
135 bool validated_once;
136};
137
138static inline void svm_range_lock(struct svm_range *prange)
139{
140 mutex_lock(&prange->lock);
141 prange->saved_flags = memalloc_noreclaim_save();
142
143}
144static inline void svm_range_unlock(struct svm_range *prange)
145{
146 memalloc_noreclaim_restore(prange->saved_flags);
147 mutex_unlock(&prange->lock);
148}
149
150static inline struct svm_range_bo *svm_range_bo_ref(struct svm_range_bo *svm_bo)
151{
152 if (svm_bo)
153 kref_get(&svm_bo->kref);
154
155 return svm_bo;
156}
157
158int svm_range_list_init(struct kfd_process *p);
159void svm_range_list_fini(struct kfd_process *p);
160int svm_ioctl(struct kfd_process *p, enum kfd_ioctl_svm_op op, uint64_t start,
161 uint64_t size, uint32_t nattrs,
162 struct kfd_ioctl_svm_attribute *attrs);
163struct svm_range *svm_range_from_addr(struct svm_range_list *svms,
164 unsigned long addr,
165 struct svm_range **parent);
166struct amdgpu_device *svm_range_get_adev_by_id(struct svm_range *prange,
167 uint32_t id);
168int svm_range_vram_node_new(struct amdgpu_device *adev,
169 struct svm_range *prange, bool clear);
170void svm_range_vram_node_free(struct svm_range *prange);
171int svm_range_split_by_granularity(struct kfd_process *p, struct mm_struct *mm,
172 unsigned long addr, struct svm_range *parent,
173 struct svm_range *prange);
174int svm_range_restore_pages(struct amdgpu_device *adev,
175 unsigned int pasid, uint64_t addr, bool write_fault);
176int svm_range_schedule_evict_svm_bo(struct amdgpu_amdkfd_fence *fence);
177void svm_range_add_list_work(struct svm_range_list *svms,
178 struct svm_range *prange, struct mm_struct *mm,
179 enum svm_work_list_ops op);
180void schedule_deferred_list_work(struct svm_range_list *svms);
181void svm_range_dma_unmap(struct device *dev, dma_addr_t *dma_addr,
182 unsigned long offset, unsigned long npages);
183void svm_range_free_dma_mappings(struct svm_range *prange);
184void svm_range_prefault(struct svm_range *prange, struct mm_struct *mm,
185 void *owner);
186int svm_range_get_info(struct kfd_process *p, uint32_t *num_svm_ranges,
187 uint64_t *svm_priv_data_size);
188int kfd_criu_checkpoint_svm(struct kfd_process *p,
189 uint8_t __user *user_priv_data,
190 uint64_t *priv_offset);
191int kfd_criu_restore_svm(struct kfd_process *p,
192 uint8_t __user *user_priv_ptr,
193 uint64_t *priv_data_offset,
194 uint64_t max_priv_data_size);
195int kfd_criu_resume_svm(struct kfd_process *p);
196struct kfd_process_device *
197svm_range_get_pdd_by_adev(struct svm_range *prange, struct amdgpu_device *adev);
198void svm_range_list_lock_and_flush_work(struct svm_range_list *svms, struct mm_struct *mm);
199
200
201
202
203#define KFD_IS_SVM_API_SUPPORTED(dev) ((dev)->pgmap.type != 0)
204
205void svm_range_bo_unref_async(struct svm_range_bo *svm_bo);
206#else
207
208struct kfd_process;
209
210static inline int svm_range_list_init(struct kfd_process *p)
211{
212 return 0;
213}
214static inline void svm_range_list_fini(struct kfd_process *p)
215{
216
217}
218
219static inline int svm_range_restore_pages(struct amdgpu_device *adev,
220 unsigned int pasid, uint64_t addr,
221 bool write_fault)
222{
223 return -EFAULT;
224}
225
226static inline int svm_range_schedule_evict_svm_bo(
227 struct amdgpu_amdkfd_fence *fence)
228{
229 WARN_ONCE(1, "SVM eviction fence triggered, but SVM is disabled");
230 return -EINVAL;
231}
232
233static inline int svm_range_get_info(struct kfd_process *p,
234 uint32_t *num_svm_ranges,
235 uint64_t *svm_priv_data_size)
236{
237 *num_svm_ranges = 0;
238 *svm_priv_data_size = 0;
239 return 0;
240}
241
242static inline int kfd_criu_checkpoint_svm(struct kfd_process *p,
243 uint8_t __user *user_priv_data,
244 uint64_t *priv_offset)
245{
246 return 0;
247}
248
249static inline int kfd_criu_restore_svm(struct kfd_process *p,
250 uint8_t __user *user_priv_ptr,
251 uint64_t *priv_data_offset,
252 uint64_t max_priv_data_size)
253{
254 return -EINVAL;
255}
256
257static inline int kfd_criu_resume_svm(struct kfd_process *p)
258{
259 return 0;
260}
261
262#define KFD_IS_SVM_API_SUPPORTED(dev) false
263
264#endif
265
266#endif
267