GEM_BUG_ON(vma->obj != obj);
spin_unlock(&obj->vma.lock);
- i915_vma_destroy(vma);
+ __i915_vma_put(vma);
spin_lock(&obj->vma.lock);
}
out_vma_unpin:
i915_vma_unpin(vma);
out_vma_close:
- i915_vma_destroy(vma);
-
+ __i915_vma_put(vma);
return err;
}
kunmap(p);
out:
- i915_vma_destroy(vma);
+ __i915_vma_put(vma);
return err;
}
if (err)
return err;
- i915_vma_destroy(vma);
+ __i915_vma_put(vma);
if (igt_timeout(end_time,
"%s: timed out after tiling=%d stride=%d\n",
struct i915_vma,
obj_link))) {
struct i915_address_space *vm = vma->vm;
- bool awake = false;
list_move_tail(&vma->obj_link, &still_in_list);
if (!i915_vma_is_bound(vma, I915_VMA_BIND_MASK))
break;
/* Prevent vma being freed by i915_vma_parked as we unbind */
- if (intel_gt_pm_get_if_awake(vm->gt)) {
- awake = true;
- } else {
- if (i915_vma_is_closed(vma)) {
- spin_unlock(&obj->vma.lock);
- i915_vma_parked(vm->gt);
- goto err_vm;
- }
- }
-
+ vma = __i915_vma_get(vma);
spin_unlock(&obj->vma.lock);
- ret = -EBUSY;
- if (flags & I915_GEM_OBJECT_UNBIND_ACTIVE ||
- !i915_vma_is_active(vma))
- ret = i915_vma_unbind(vma);
+ if (vma) {
+ ret = -EBUSY;
+ if (flags & I915_GEM_OBJECT_UNBIND_ACTIVE ||
+ !i915_vma_is_active(vma))
+ ret = i915_vma_unbind(vma);
+
+ __i915_vma_put(vma);
+ }
- if (awake)
- intel_gt_pm_put(vm->gt);
-err_vm:
i915_vm_close(vm);
spin_lock(&obj->vma.lock);
}
atomic_and(~I915_VMA_PIN_MASK, &vma->flags);
WARN_ON(__i915_vma_unbind(vma));
- i915_vma_destroy(vma);
+ __i915_vma_put(vma);
i915_gem_object_put(obj);
}
{
struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(i915_vm_to_ppgtt(vm));
- i915_vma_destroy(ppgtt->vma);
+ __i915_vma_put(ppgtt->vma);
gen6_ppgtt_free_pd(ppgtt);
free_scratch(vm);
i915_active_init(&vma->active, NULL, NULL);
+ kref_init(&vma->ref);
mutex_init(&vma->pages_mutex);
vma->vm = i915_vm_get(&ggtt->vm);
vma->ops = &pd_vma_ops;
if (vma == NULL)
return ERR_PTR(-ENOMEM);
+ kref_init(&vma->ref);
mutex_init(&vma->pages_mutex);
vma->vm = i915_vm_get(vm);
vma->ops = &vm->vma_ops;
__i915_vma_remove_closed(vma);
}
-void i915_vma_destroy(struct i915_vma *vma)
+void i915_vma_release(struct kref *ref)
{
+ struct i915_vma *vma = container_of(ref, typeof(*vma), ref);
+
if (drm_mm_node_allocated(&vma->node)) {
mutex_lock(&vma->vm->mutex);
atomic_and(~I915_VMA_PIN_MASK, &vma->flags);
spin_unlock_irq(>->closed_lock);
if (obj) {
- i915_vma_destroy(vma);
+ __i915_vma_put(vma);
i915_gem_object_put(obj);
}
i915_vma_detach(vma);
vma_unbind_pages(vma);
- drm_mm_remove_node(&vma->node); /* pairs with i915_vma_destroy() */
+ drm_mm_remove_node(&vma->node); /* pairs with i915_vma_release() */
return 0;
}
*/
struct i915_vma {
struct drm_mm_node node;
- struct drm_i915_gem_object *obj;
+
struct i915_address_space *vm;
const struct i915_vma_ops *ops;
- struct i915_fence_reg *fence;
+
+ struct drm_i915_gem_object *obj;
struct dma_resv *resv; /** Alias of obj->resv */
+
struct sg_table *pages;
void __iomem *iomap;
void *private; /* owned by creator */
+
+ struct i915_fence_reg *fence;
+
u64 size;
u64 display_alignment;
struct i915_page_sizes page_sizes;
* handles (but same file) for execbuf, i.e. the number of aliases
* that exist in the ctx->handle_vmas LUT for this vma.
*/
+ struct kref ref;
atomic_t open_count;
atomic_t flags;
/**
void i915_vma_unlink_ctx(struct i915_vma *vma);
void i915_vma_close(struct i915_vma *vma);
void i915_vma_reopen(struct i915_vma *vma);
-void i915_vma_destroy(struct i915_vma *vma);
+
+static inline struct i915_vma *__i915_vma_get(struct i915_vma *vma)
+{
+ if (kref_get_unless_zero(&vma->ref))
+ return vma;
+
+ return NULL;
+}
+
+void i915_vma_release(struct kref *ref);
+static inline void __i915_vma_put(struct i915_vma *vma)
+{
+ kref_put(&vma->ref, i915_vma_release);
+}
#define assert_vma_held(vma) dma_resv_assert_held((vma)->resv)