aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c128
1 files changed, 63 insertions, 65 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index 0bda8f2a188a..a418df1b9422 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -44,11 +44,12 @@ void amdgpu_gem_object_free(struct drm_gem_object *gobj)
44} 44}
45 45
46int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size, 46int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
47 int alignment, u32 initial_domain, 47 int alignment, u32 initial_domain,
48 u64 flags, bool kernel, 48 u64 flags, bool kernel,
49 struct drm_gem_object **obj) 49 struct reservation_object *resv,
50 struct drm_gem_object **obj)
50{ 51{
51 struct amdgpu_bo *robj; 52 struct amdgpu_bo *bo;
52 int r; 53 int r;
53 54
54 *obj = NULL; 55 *obj = NULL;
@@ -59,7 +60,7 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
59 60
60retry: 61retry:
61 r = amdgpu_bo_create(adev, size, alignment, kernel, initial_domain, 62 r = amdgpu_bo_create(adev, size, alignment, kernel, initial_domain,
62 flags, NULL, NULL, 0, &robj); 63 flags, NULL, resv, 0, &bo);
63 if (r) { 64 if (r) {
64 if (r != -ERESTARTSYS) { 65 if (r != -ERESTARTSYS) {
65 if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) { 66 if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) {
@@ -71,7 +72,7 @@ retry:
71 } 72 }
72 return r; 73 return r;
73 } 74 }
74 *obj = &robj->gem_base; 75 *obj = &bo->gem_base;
75 76
76 return 0; 77 return 0;
77} 78}
@@ -112,7 +113,17 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj,
112 struct amdgpu_fpriv *fpriv = file_priv->driver_priv; 113 struct amdgpu_fpriv *fpriv = file_priv->driver_priv;
113 struct amdgpu_vm *vm = &fpriv->vm; 114 struct amdgpu_vm *vm = &fpriv->vm;
114 struct amdgpu_bo_va *bo_va; 115 struct amdgpu_bo_va *bo_va;
116 struct mm_struct *mm;
115 int r; 117 int r;
118
119 mm = amdgpu_ttm_tt_get_usermm(abo->tbo.ttm);
120 if (mm && mm != current->mm)
121 return -EPERM;
122
123 if (abo->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID &&
124 abo->tbo.resv != vm->root.base.bo->tbo.resv)
125 return -EPERM;
126
116 r = amdgpu_bo_reserve(abo, false); 127 r = amdgpu_bo_reserve(abo, false);
117 if (r) 128 if (r)
118 return r; 129 return r;
@@ -127,35 +138,6 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj,
127 return 0; 138 return 0;
128} 139}
129 140
130static int amdgpu_gem_vm_check(void *param, struct amdgpu_bo *bo)
131{
132 /* if anything is swapped out don't swap it in here,
133 just abort and wait for the next CS */
134 if (!amdgpu_bo_gpu_accessible(bo))
135 return -ERESTARTSYS;
136
137 if (bo->shadow && !amdgpu_bo_gpu_accessible(bo->shadow))
138 return -ERESTARTSYS;
139
140 return 0;
141}
142
143static bool amdgpu_gem_vm_ready(struct amdgpu_device *adev,
144 struct amdgpu_vm *vm,
145 struct list_head *list)
146{
147 struct ttm_validate_buffer *entry;
148
149 list_for_each_entry(entry, list, head) {
150 struct amdgpu_bo *bo =
151 container_of(entry->bo, struct amdgpu_bo, tbo);
152 if (amdgpu_gem_vm_check(NULL, bo))
153 return false;
154 }
155
156 return !amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_gem_vm_check, NULL);
157}
158
159void amdgpu_gem_object_close(struct drm_gem_object *obj, 141void amdgpu_gem_object_close(struct drm_gem_object *obj,
160 struct drm_file *file_priv) 142 struct drm_file *file_priv)
161{ 143{
@@ -165,13 +147,14 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
165 struct amdgpu_vm *vm = &fpriv->vm; 147 struct amdgpu_vm *vm = &fpriv->vm;
166 148
167 struct amdgpu_bo_list_entry vm_pd; 149 struct amdgpu_bo_list_entry vm_pd;
168 struct list_head list; 150 struct list_head list, duplicates;
169 struct ttm_validate_buffer tv; 151 struct ttm_validate_buffer tv;
170 struct ww_acquire_ctx ticket; 152 struct ww_acquire_ctx ticket;
171 struct amdgpu_bo_va *bo_va; 153 struct amdgpu_bo_va *bo_va;
172 int r; 154 int r;
173 155
174 INIT_LIST_HEAD(&list); 156 INIT_LIST_HEAD(&list);
157 INIT_LIST_HEAD(&duplicates);
175 158
176 tv.bo = &bo->tbo; 159 tv.bo = &bo->tbo;
177 tv.shared = true; 160 tv.shared = true;
@@ -179,7 +162,7 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
179 162
180 amdgpu_vm_get_pd_bo(vm, &list, &vm_pd); 163 amdgpu_vm_get_pd_bo(vm, &list, &vm_pd);
181 164
182 r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL); 165 r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates);
183 if (r) { 166 if (r) {
184 dev_err(adev->dev, "leaking bo va because " 167 dev_err(adev->dev, "leaking bo va because "
185 "we fail to reserve bo (%d)\n", r); 168 "we fail to reserve bo (%d)\n", r);
@@ -189,7 +172,7 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
189 if (bo_va && --bo_va->ref_count == 0) { 172 if (bo_va && --bo_va->ref_count == 0) {
190 amdgpu_vm_bo_rmv(adev, bo_va); 173 amdgpu_vm_bo_rmv(adev, bo_va);
191 174
192 if (amdgpu_gem_vm_ready(adev, vm, &list)) { 175 if (amdgpu_vm_ready(vm)) {
193 struct dma_fence *fence = NULL; 176 struct dma_fence *fence = NULL;
194 177
195 r = amdgpu_vm_clear_freed(adev, vm, &fence); 178 r = amdgpu_vm_clear_freed(adev, vm, &fence);
@@ -214,18 +197,24 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
214 struct drm_file *filp) 197 struct drm_file *filp)
215{ 198{
216 struct amdgpu_device *adev = dev->dev_private; 199 struct amdgpu_device *adev = dev->dev_private;
200 struct amdgpu_fpriv *fpriv = filp->driver_priv;
201 struct amdgpu_vm *vm = &fpriv->vm;
217 union drm_amdgpu_gem_create *args = data; 202 union drm_amdgpu_gem_create *args = data;
203 uint64_t flags = args->in.domain_flags;
218 uint64_t size = args->in.bo_size; 204 uint64_t size = args->in.bo_size;
205 struct reservation_object *resv = NULL;
219 struct drm_gem_object *gobj; 206 struct drm_gem_object *gobj;
220 uint32_t handle; 207 uint32_t handle;
221 bool kernel = false;
222 int r; 208 int r;
223 209
224 /* reject invalid gem flags */ 210 /* reject invalid gem flags */
225 if (args->in.domain_flags & ~(AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | 211 if (flags & ~(AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
226 AMDGPU_GEM_CREATE_NO_CPU_ACCESS | 212 AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
227 AMDGPU_GEM_CREATE_CPU_GTT_USWC | 213 AMDGPU_GEM_CREATE_CPU_GTT_USWC |
228 AMDGPU_GEM_CREATE_VRAM_CLEARED)) 214 AMDGPU_GEM_CREATE_VRAM_CLEARED |
215 AMDGPU_GEM_CREATE_VM_ALWAYS_VALID |
216 AMDGPU_GEM_CREATE_EXPLICIT_SYNC))
217
229 return -EINVAL; 218 return -EINVAL;
230 219
231 /* reject invalid gem domains */ 220 /* reject invalid gem domains */
@@ -240,7 +229,7 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
240 /* create a gem object to contain this object in */ 229 /* create a gem object to contain this object in */
241 if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS | 230 if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS |
242 AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) { 231 AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) {
243 kernel = true; 232 flags |= AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
244 if (args->in.domains == AMDGPU_GEM_DOMAIN_GDS) 233 if (args->in.domains == AMDGPU_GEM_DOMAIN_GDS)
245 size = size << AMDGPU_GDS_SHIFT; 234 size = size << AMDGPU_GDS_SHIFT;
246 else if (args->in.domains == AMDGPU_GEM_DOMAIN_GWS) 235 else if (args->in.domains == AMDGPU_GEM_DOMAIN_GWS)
@@ -252,10 +241,25 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
252 } 241 }
253 size = roundup(size, PAGE_SIZE);