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.c63
1 files changed, 46 insertions, 17 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index e32a2b55b54f..f1e61b3df640 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}
@@ -119,6 +120,10 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj,
119 if (mm && mm != current->mm) 120 if (mm && mm != current->mm)
120 return -EPERM; 121 return -EPERM;
121 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
122 r = amdgpu_bo_reserve(abo, false); 127 r = amdgpu_bo_reserve(abo, false);
123 if (r) 128 if (r)
124 return r; 129 return r;
@@ -142,13 +147,14 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
142 struct amdgpu_vm *vm = &fpriv->vm; 147 struct amdgpu_vm *vm = &fpriv->vm;
143 148
144 struct amdgpu_bo_list_entry vm_pd; 149 struct amdgpu_bo_list_entry vm_pd;
145 struct list_head list; 150 struct list_head list, duplicates;
146 struct ttm_validate_buffer tv; 151 struct ttm_validate_buffer tv;
147 struct ww_acquire_ctx ticket; 152 struct ww_acquire_ctx ticket;
148 struct amdgpu_bo_va *bo_va; 153 struct amdgpu_bo_va *bo_va;
149 int r; 154 int r;
150 155
151 INIT_LIST_HEAD(&list); 156 INIT_LIST_HEAD(&list);
157 INIT_LIST_HEAD(&duplicates);
152 158
153 tv.bo = &bo->tbo; 159 tv.bo = &bo->tbo;
154 tv.shared = true; 160 tv.shared = true;
@@ -156,7 +162,7 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
156 162
157 amdgpu_vm_get_pd_bo(vm, &list, &vm_pd); 163 amdgpu_vm_get_pd_bo(vm, &list, &vm_pd);
158 164
159 r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL); 165 r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates);
160 if (r) { 166 if (r) {
161 dev_err(adev->dev, "leaking bo va because " 167 dev_err(adev->dev, "leaking bo va because "
162 "we fail to reserve bo (%d)\n", r); 168 "we fail to reserve bo (%d)\n", r);
@@ -191,9 +197,12 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
191 struct drm_file *filp) 197 struct drm_file *filp)
192{ 198{
193 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;
194 union drm_amdgpu_gem_create *args = data; 202 union drm_amdgpu_gem_create *args = data;
195 uint64_t flags = args->in.domain_flags; 203 uint64_t flags = args->in.domain_flags;
196 uint64_t size = args->in.bo_size; 204 uint64_t size = args->in.bo_size;
205 struct reservation_object *resv = NULL;
197 struct drm_gem_object *gobj; 206 struct drm_gem_object *gobj;
198 uint32_t handle; 207 uint32_t handle;
199 int r; 208 int r;
@@ -202,7 +211,8 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
202 if (flags & ~(AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | 211 if (flags & ~(AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
203 AMDGPU_GEM_CREATE_NO_CPU_ACCESS | 212 AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
204 AMDGPU_GEM_CREATE_CPU_GTT_USWC | 213 AMDGPU_GEM_CREATE_CPU_GTT_USWC |
205 AMDGPU_GEM_CREATE_VRAM_CLEARED)) 214 AMDGPU_GEM_CREATE_VRAM_CLEARED |
215 AMDGPU_GEM_CREATE_VM_ALWAYS_VALID))
206 return -EINVAL; 216 return -EINVAL;
207 217
208 /* reject invalid gem domains */ 218 /* reject invalid gem domains */
@@ -229,9 +239,25 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
229 } 239 }
230 size = roundup(size, PAGE_SIZE); 240 size = roundup(size, PAGE_SIZE);
231 241
242 if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) {
243 r = amdgpu_bo_reserve(vm->root.base.bo, false);
244 if (r)
245 return r;
246
247 resv = vm->root.base.bo->tbo.resv;
248 }
249
232 r = amdgpu_gem_object_create(adev, size, args->in.alignment, 250 r = amdgpu_gem_object_create(adev, size, args->in.alignment,
233 (u32)(0xffffffff & args->in.domains), 251 (u32)(0xffffffff & args->in.domains),
234 flags, false, &gobj); 252 flags, false, resv, &gobj);
253 if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) {
254 if (!r) {
255 struct amdgpu_bo *abo = gem_to_amdgpu_bo(gobj);
256
257 abo->parent = amdgpu_bo_ref(vm->root.base.bo);
258 }
259 amdgpu_bo_unreserve(vm->root.base.bo);
260 }
235 if (r) 261 if (r)
236 return r; 262 return r;
237 263
@@ -273,9 +299,8 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
273 } 299 }
274 300
275 /* create a gem object to contain this object in */ 301 /* create a gem object to contain this object in */
276 r = amdgpu_gem_object_create(adev, args->size, 0, 302 r = amdgpu_gem_object_create(adev, args->size, 0, AMDGPU_GEM_DOMAIN_CPU,
277 AMDGPU_GEM_DOMAIN_CPU, 0, 303 0, 0, NULL, &gobj);
278 0, &gobj);
279 if (r) 304 if (r)
280 return r; 305 return r;
281 306
@@ -527,7 +552,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
527 struct amdgpu_bo_list_entry vm_pd; 552 struct amdgpu_bo_list_entry vm_pd;
528 struct ttm_validate_buffer tv; 553 struct ttm_validate_buffer tv;
529 struct ww_acquire_ctx ticket; 554 struct ww_acquire_ctx ticket;
530 struct list_head list; 555 struct list_head list, duplicates;
531 uint64_t va_flags; 556 uint64_t va_flags;
532 int r = 0; 557 int r = 0;
533 558
@@ -563,6 +588,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
563 } 588 }
564 589
565 INIT_LIST_HEAD(&list); 590 INIT_LIST_HEAD(&list);
591 INIT_LIST_HEAD(&duplicates);
566 if ((args->operation != AMDGPU_VA_OP_CLEAR) && 592 if ((args->operation != AMDGPU_VA_OP_CLEAR) &&
567 !(args->flags & AMDGPU_VM_PAGE_PRT)) { 593 !(args->flags & AMDGPU_VM_PAGE_PRT)) {
568 gobj = drm_gem_object_lookup(filp, args->handle); 594 gobj = drm_gem_object_lookup(filp, args->handle);
@@ -579,7 +605,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
579 605
580 amdgpu_vm_get_pd_bo(&fpriv->vm, &list, &vm_pd); 606 amdgpu_vm_get_pd_bo(&fpriv->vm, &list, &vm_pd);
581 607
582 r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL); 608 r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates);
583 if (r) 609 if (r)
584 goto error_unref; 610 goto error_unref;
585 611
@@ -645,6 +671,7 @@ error_unref:
645int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, 671int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
646 struct drm_file *filp) 672 struct drm_file *filp)
647{ 673{
674 struct amdgpu_device *adev = dev->dev_private;
648 struct drm_amdgpu_gem_op *args = data; 675 struct drm_amdgpu_gem_op *args = data;
649 struct drm_gem_object *gobj; 676 struct drm_gem_object *gobj;
650 struct amdgpu_bo *robj; 677 struct amdgpu_bo *robj;
@@ -692,6 +719,9 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
692 if (robj->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM) 719 if (robj->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM)
693 robj->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT; 720 robj->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT;
694 721
722 if (robj->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID)
723 amdgpu_vm_bo_invalidate(adev, robj, true);
724
695 amdgpu_bo_unreserve(robj); 725 amdgpu_bo_unreserve(robj);
696 break; 726 break;
697 default: 727 default:
@@ -721,8 +751,7 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
721 r = amdgpu_gem_object_create(adev, args->size, 0, 751 r = amdgpu_gem_object_create(adev, args->size, 0,
722 AMDGPU_GEM_DOMAIN_VRAM, 752 AMDGPU_GEM_DOMAIN_VRAM,
723 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, 753 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
724 ttm_bo_type_device, 754 false, NULL, &gobj);
725 &gobj);
726 if (r) 755 if (r)
727 return -ENOMEM; 756 return -ENOMEM;
728 757