|
@@ -146,6 +146,59 @@ __i915_vma_create(struct drm_i915_gem_object *obj,
|
|
|
return vma;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * i915_vma_lookup - finds a matching VMA
|
|
|
+ * @obj: parent &struct drm_i915_gem_object to be mapped
|
|
|
+ * @vm: address space in which the mapping is located
|
|
|
+ * @view: additional mapping requirements
|
|
|
+ *
|
|
|
+ * i915_vma_lookup() looks up an existing VMA of the @obj in the @vm with
|
|
|
+ * the same @view characteristics.
|
|
|
+ *
|
|
|
+ * Must be called with struct_mutex held.
|
|
|
+ *
|
|
|
+ * Returns the vma if found, or NULL.
|
|
|
+ */
|
|
|
+struct i915_vma *
|
|
|
+i915_vma_lookup(struct drm_i915_gem_object *obj,
|
|
|
+ struct i915_address_space *vm,
|
|
|
+ const struct i915_ggtt_view *view)
|
|
|
+{
|
|
|
+ struct rb_node *rb;
|
|
|
+
|
|
|
+ lockdep_assert_held(&obj->base.dev->struct_mutex);
|
|
|
+
|
|
|
+ rb = obj->vma_tree.rb_node;
|
|
|
+ while (rb) {
|
|
|
+ struct i915_vma *vma = rb_entry(rb, struct i915_vma, obj_node);
|
|
|
+ long cmp;
|
|
|
+
|
|
|
+ cmp = i915_vma_compare(vma, vm, view);
|
|
|
+ if (cmp == 0)
|
|
|
+ return vma;
|
|
|
+
|
|
|
+ if (cmp < 0)
|
|
|
+ rb = rb->rb_right;
|
|
|
+ else
|
|
|
+ rb = rb->rb_left;
|
|
|
+ }
|
|
|
+
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * i915_vma_create - creates a VMA
|
|
|
+ * @obj: parent &struct drm_i915_gem_object to be mapped
|
|
|
+ * @vm: address space in which the mapping is located
|
|
|
+ * @view: additional mapping requirements
|
|
|
+ *
|
|
|
+ * i915_vma_create() allocates a new VMA of the @obj in the @vm with
|
|
|
+ * @view characteristics.
|
|
|
+ *
|
|
|
+ * Must be called with struct_mutex held.
|
|
|
+ *
|
|
|
+ * Returns the vma if found, or an error pointer.
|
|
|
+ */
|
|
|
struct i915_vma *
|
|
|
i915_vma_create(struct drm_i915_gem_object *obj,
|
|
|
struct i915_address_space *vm,
|
|
@@ -153,11 +206,46 @@ i915_vma_create(struct drm_i915_gem_object *obj,
|
|
|
{
|
|
|
lockdep_assert_held(&obj->base.dev->struct_mutex);
|
|
|
GEM_BUG_ON(view && !i915_is_ggtt(vm));
|
|
|
- GEM_BUG_ON(i915_gem_obj_to_vma(obj, vm, view));
|
|
|
+ GEM_BUG_ON(i915_vma_lookup(obj, vm, view));
|
|
|
|
|
|
return __i915_vma_create(obj, vm, view);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * i915_vma_instance - return the singleton instance of the VMA
|
|
|
+ * @obj: parent &struct drm_i915_gem_object to be mapped
|
|
|
+ * @vm: address space in which the mapping is located
|
|
|
+ * @view: additional mapping requirements
|
|
|
+ *
|
|
|
+ * i915_vma_instance() looks up an existing VMA of the @obj in the @vm with
|
|
|
+ * the same @view characteristics. If a match is not found, one is created.
|
|
|
+ * Once created, the VMA is kept until either the object is freed, or the
|
|
|
+ * address space is closed.
|
|
|
+ *
|
|
|
+ * Must be called with struct_mutex held.
|
|
|
+ *
|
|
|
+ * Returns the vma, or an error pointer.
|
|
|
+ */
|
|
|
+struct i915_vma *
|
|
|
+i915_vma_instance(struct drm_i915_gem_object *obj,
|
|
|
+ struct i915_address_space *vm,
|
|
|
+ const struct i915_ggtt_view *view)
|
|
|
+{
|
|
|
+ struct i915_vma *vma;
|
|
|
+
|
|
|
+ lockdep_assert_held(&obj->base.dev->struct_mutex);
|
|
|
+ GEM_BUG_ON(view && !i915_is_ggtt(vm));
|
|
|
+ GEM_BUG_ON(vm->closed);
|
|
|
+
|
|
|
+ vma = i915_vma_lookup(obj, vm, view);
|
|
|
+ if (!vma)
|
|
|
+ vma = i915_vma_create(obj, vm, view);
|
|
|
+
|
|
|
+ GEM_BUG_ON(!IS_ERR(vma) && i915_vma_is_closed(vma));
|
|
|
+ GEM_BUG_ON(!IS_ERR(vma) && i915_vma_lookup(obj, vm, view) != vma);
|
|
|
+ return vma;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* i915_vma_bind - Sets up PTEs for an VMA in it's corresponding address space.
|
|
|
* @vma: VMA to map
|