]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/gpu/drm/i915/i915_vma.c
drm/i915: Move object close under its own lock
[linux.git] / drivers / gpu / drm / i915 / i915_vma.c
index b7fb7d216f77d481a0bd7fcdd68444c67deac644..f6ac8394da77ae07e4c83959538f46d21680f8aa 100644 (file)
@@ -131,9 +131,6 @@ vma_create(struct drm_i915_gem_object *obj,
        if (vma == NULL)
                return ERR_PTR(-ENOMEM);
 
-       i915_active_init(vm->i915, &vma->active, __i915_vma_retire);
-       INIT_ACTIVE_REQUEST(&vma->last_fence);
-
        vma->vm = vm;
        vma->ops = &vm->vma_ops;
        vma->obj = obj;
@@ -141,6 +138,11 @@ vma_create(struct drm_i915_gem_object *obj,
        vma->size = obj->base.size;
        vma->display_alignment = I915_GTT_MIN_ALIGNMENT;
 
+       i915_active_init(vm->i915, &vma->active, __i915_vma_retire);
+       INIT_ACTIVE_REQUEST(&vma->last_fence);
+
+       INIT_LIST_HEAD(&vma->closed_link);
+
        if (view && view->type != I915_GGTT_VIEW_NORMAL) {
                vma->ggtt_view = *view;
                if (view->type == I915_GGTT_VIEW_PARTIAL) {
@@ -787,10 +789,10 @@ int __i915_vma_do_pin(struct i915_vma *vma,
 
 void i915_vma_close(struct i915_vma *vma)
 {
-       lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
+       struct drm_i915_private *i915 = vma->vm->i915;
+       unsigned long flags;
 
        GEM_BUG_ON(i915_vma_is_closed(vma));
-       vma->flags |= I915_VMA_CLOSED;
 
        /*
         * We defer actually closing, unbinding and destroying the VMA until
@@ -804,17 +806,26 @@ void i915_vma_close(struct i915_vma *vma)
         * causing us to rebind the VMA once more. This ends up being a lot
         * of wasted work for the steady state.
         */
-       list_add_tail(&vma->closed_link, &vma->vm->i915->gt.closed_vma);
+       spin_lock_irqsave(&i915->gt.closed_lock, flags);
+       list_add(&vma->closed_link, &i915->gt.closed_vma);
+       spin_unlock_irqrestore(&i915->gt.closed_lock, flags);
 }
 
-void i915_vma_reopen(struct i915_vma *vma)
+static void __i915_vma_remove_closed(struct i915_vma *vma)
 {
-       lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
+       struct drm_i915_private *i915 = vma->vm->i915;
 
-       if (vma->flags & I915_VMA_CLOSED) {
-               vma->flags &= ~I915_VMA_CLOSED;
-               list_del(&vma->closed_link);
-       }
+       if (!i915_vma_is_closed(vma))
+               return;
+
+       spin_lock_irq(&i915->gt.closed_lock);
+       list_del_init(&vma->closed_link);
+       spin_unlock_irq(&i915->gt.closed_lock);
+}
+
+void i915_vma_reopen(struct i915_vma *vma)
+{
+       __i915_vma_remove_closed(vma);
 }
 
 static void __i915_vma_destroy(struct i915_vma *vma)
@@ -848,8 +859,7 @@ void i915_vma_destroy(struct i915_vma *vma)
 
        GEM_BUG_ON(i915_vma_is_pinned(vma));
 
-       if (i915_vma_is_closed(vma))
-               list_del(&vma->closed_link);
+       __i915_vma_remove_closed(vma);
 
        WARN_ON(i915_vma_unbind(vma));
        GEM_BUG_ON(i915_vma_is_active(vma));
@@ -861,12 +871,16 @@ void i915_vma_parked(struct drm_i915_private *i915)
 {
        struct i915_vma *vma, *next;
 
+       spin_lock_irq(&i915->gt.closed_lock);
        list_for_each_entry_safe(vma, next, &i915->gt.closed_vma, closed_link) {
-               GEM_BUG_ON(!i915_vma_is_closed(vma));
+               list_del_init(&vma->closed_link);
+               spin_unlock_irq(&i915->gt.closed_lock);
+
                i915_vma_destroy(vma);
-       }
 
-       GEM_BUG_ON(!list_empty(&i915->gt.closed_vma));
+               spin_lock_irq(&i915->gt.closed_lock);
+       }
+       spin_unlock_irq(&i915->gt.closed_lock);
 }
 
 static void __i915_vma_iounmap(struct i915_vma *vma)