aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_gem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_gem.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c54
1 files changed, 46 insertions, 8 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index 04c212da6f65..f38fbcc46935 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -123,6 +123,30 @@ void radeon_gem_fini(struct radeon_device *rdev)
123 */ 123 */
124int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv) 124int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv)
125{ 125{
126 struct radeon_bo *rbo = gem_to_radeon_bo(obj);
127 struct radeon_device *rdev = rbo->rdev;
128 struct radeon_fpriv *fpriv = file_priv->driver_priv;
129 struct radeon_vm *vm = &fpriv->vm;
130 struct radeon_bo_va *bo_va;
131 int r;
132
133 if (rdev->family < CHIP_CAYMAN) {
134 return 0;
135 }
136
137 r = radeon_bo_reserve(rbo, false);
138 if (r) {
139 return r;
140 }
141
142 bo_va = radeon_vm_bo_find(vm, rbo);
143 if (!bo_va) {
144 bo_va = radeon_vm_bo_add(rdev, vm, rbo);
145 } else {
146 ++bo_va->ref_count;
147 }
148 radeon_bo_unreserve(rbo);
149
126 return 0; 150 return 0;
127} 151}
128 152
@@ -133,16 +157,25 @@ void radeon_gem_object_close(struct drm_gem_object *obj,
133 struct radeon_device *rdev = rbo->rdev; 157 struct radeon_device *rdev = rbo->rdev;
134 struct radeon_fpriv *fpriv = file_priv->driver_priv; 158 struct radeon_fpriv *fpriv = file_priv->driver_priv;
135 struct radeon_vm *vm = &fpriv->vm; 159 struct radeon_vm *vm = &fpriv->vm;
160 struct radeon_bo_va *bo_va;
161 int r;
136 162
137 if (rdev->family < CHIP_CAYMAN) { 163 if (rdev->family < CHIP_CAYMAN) {
138 return; 164 return;
139 } 165 }
140 166
141 if (radeon_bo_reserve(rbo, false)) { 167 r = radeon_bo_reserve(rbo, true);
142 dev_err(rdev->dev, "leaking bo va because we fail to reserve bo\n"); 168 if (r) {
169 dev_err(rdev->dev, "leaking bo va because "
170 "we fail to reserve bo (%d)\n", r);
143 return; 171 return;
144 } 172 }
145 radeon_vm_bo_rmv(rdev, vm, rbo); 173 bo_va = radeon_vm_bo_find(vm, rbo);
174 if (bo_va) {
175 if (--bo_va->ref_count == 0) {
176 radeon_vm_bo_rmv(rdev, bo_va);
177 }
178 }
146 radeon_bo_unreserve(rbo); 179 radeon_bo_unreserve(rbo);
147} 180}
148 181
@@ -458,19 +491,24 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data,
458 drm_gem_object_unreference_unlocked(gobj); 491 drm_gem_object_unreference_unlocked(gobj);
459 return r; 492 return r;
460 } 493 }
494 bo_va = radeon_vm_bo_find(&fpriv->vm, rbo);
495 if (!bo_va) {
496 args->operation = RADEON_VA_RESULT_ERROR;
497 drm_gem_object_unreference_unlocked(gobj);
498 return -ENOENT;
499 }
500
461 switch (args->operation) { 501 switch (args->operation) {
462 case RADEON_VA_MAP: 502 case RADEON_VA_MAP:
463 bo_va = radeon_bo_va(rbo, &fpriv->vm); 503 if (bo_va->soffset) {
464 if (bo_va) {
465 args->operation = RADEON_VA_RESULT_VA_EXIST; 504 args->operation = RADEON_VA_RESULT_VA_EXIST;
466 args->offset = bo_va->soffset; 505 args->offset = bo_va->soffset;
467 goto out; 506 goto out;
468 } 507 }
469 r = radeon_vm_bo_add(rdev, &fpriv->vm, rbo, 508 r = radeon_vm_bo_set_addr(rdev, bo_va, args->offset, args->flags);
470 args->offset, args->flags);
471 break; 509 break;
472 case RADEON_VA_UNMAP: 510 case RADEON_VA_UNMAP:
473 r = radeon_vm_bo_rmv(rdev, &fpriv->vm, rbo); 511 r = radeon_vm_bo_set_addr(rdev, bo_va, 0, 0);
474 break; 512 break;
475 default: 513 default:
476 break; 514 break;