diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_gem.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_gem.c | 54 |
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 | */ |
124 | int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv) | 124 | int 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; |