[PATCH 55/55] lut

Chris Wilson chris at chris-wilson.co.uk
Sat Jun 30 15:38:08 UTC 2018


---
 drivers/gpu/drm/i915/gvt/scheduler.c          |  6 +-
 drivers/gpu/drm/i915/i915_drv.h               |  1 +
 drivers/gpu/drm/i915/i915_gem.c               | 14 ++--
 drivers/gpu/drm/i915/i915_gem_context.c       |  9 +++
 drivers/gpu/drm/i915/i915_gem_context.h       |  2 +
 drivers/gpu/drm/i915/i915_gem_execbuffer.c    | 11 ++-
 drivers/gpu/drm/i915/i915_gem_object.h        |  1 +
 drivers/gpu/drm/i915/i915_gem_render_state.c  |  2 +-
 drivers/gpu/drm/i915/i915_vma.c               | 73 +++++++++++++------
 drivers/gpu/drm/i915/i915_vma.h               | 14 +++-
 drivers/gpu/drm/i915/intel_engine_cs.c        | 10 +--
 drivers/gpu/drm/i915/intel_ringbuffer.c       |  6 +-
 drivers/gpu/drm/i915/selftests/huge_pages.c   | 28 ++++---
 .../gpu/drm/i915/selftests/i915_gem_context.c |  5 +-
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  1 +
 15 files changed, 118 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
index a4756a9b82cd..4bc2789f8c7b 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -557,8 +557,10 @@ static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload)
 				i915_gem_object_unpin_map(bb->obj);
 
 			if (bb->vma && !IS_ERR(bb->vma)) {
-				i915_vma_unpin(bb->vma);
-				i915_vma_close(bb->vma);
+				mutex_lock(&bb->vma->vm->mutex);
+				__i915_vma_unpin(bb->vma);
+				__i915_vma_close(bb->vma);
+				mutex_unlock(&bb->vma->vm->mutex);
 			}
 			i915_gem_object_put(bb->obj);
 		}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c3408efa7d07..77ac188443ca 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2074,6 +2074,7 @@ struct drm_i915_private {
 
 		struct list_head timelines;
 
+		spinlock_t closed_lock;
 		struct list_head active_rings;
 		struct list_head closed_vma;
 		u32 active_requests;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index cf4d340b8819..8ca292e296b9 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3174,8 +3174,7 @@ void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file)
 	struct drm_i915_file_private *fpriv = file->driver_priv;
 	struct i915_lut_handle *lut, *ln;
 
-	mutex_lock(&i915->drm.struct_mutex);
-
+	i915_gem_object_lock(obj);
 	list_for_each_entry_safe(lut, ln, &obj->lut_list, obj_link) {
 		struct i915_gem_context *ctx = lut->ctx;
 		struct i915_vma *vma;
@@ -3187,12 +3186,15 @@ void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file)
 		vma = radix_tree_delete(&ctx->handles_vma, lut->handle);
 		GEM_BUG_ON(vma->obj != obj);
 
-		/* We allow the process to have multiple handles to the same
+		/*
+		 * We allow the process to have multiple handles to the same
 		 * vma, in the same fd namespace, by virtue of flink/open.
 		 */
+		mutex_lock(&vma->vm->mutex);
 		GEM_BUG_ON(!vma->open_count);
 		if (!--vma->open_count && !i915_vma_is_ggtt(vma))
-			i915_vma_close(vma);
+			__i915_vma_close(vma);
+		mutex_unlock(&vma->vm->mutex);
 
 		list_del(&lut->obj_link);
 		list_del(&lut->ctx_link);
@@ -3200,8 +3202,7 @@ void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file)
 		kmem_cache_free(i915->luts, lut);
 		i915_gem_object_put(obj);
 	}
-
-	mutex_unlock(&i915->drm.struct_mutex);
+	i915_gem_object_unlock(obj);
 }
 
 static unsigned long to_wait_timeout(s64 timeout_ns)
@@ -5228,6 +5229,7 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
 	if (!dev_priv->priorities)
 		goto err_dependencies;
 
+	spin_lock_init(&dev_priv->gt.closed_lock);
 	INIT_LIST_HEAD(&dev_priv->gt.timelines);
 	INIT_LIST_HEAD(&dev_priv->gt.active_rings);
 	INIT_LIST_HEAD(&dev_priv->gt.closed_vma);
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index e3723e9e17aa..da79f54b35a8 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -103,7 +103,9 @@ static void lut_close(struct i915_gem_context *ctx)
 	void __rcu **slot;
 
 	list_for_each_entry_safe(lut, ln, &ctx->handles_list, ctx_link) {
+		i915_gem_object_lock(lut->obj);
 		list_del(&lut->obj_link);
+		i915_gem_object_unlock(lut->obj);
 		kmem_cache_free(ctx->i915->luts, lut);
 	}
 
@@ -112,9 +114,15 @@ static void lut_close(struct i915_gem_context *ctx)
 		struct i915_vma *vma = rcu_dereference_raw(*slot);
 
 		radix_tree_iter_delete(&ctx->handles_vma, &iter, slot);
+		rcu_read_unlock();
 
+		i915_gem_object_lock(vma->obj);
 		vma->open_count--;
+		i915_gem_object_unlock(vma->obj);
+
 		i915_gem_object_put(vma->obj);
+
+		rcu_read_lock();
 	}
 	rcu_read_unlock();
 }
@@ -294,6 +302,7 @@ __create_hw_context(struct drm_i915_private *dev_priv,
 		return ERR_PTR(ret);
 	}
 
+	mutex_init(&ctx->mutex);
 	kref_init(&ctx->ref);
 	list_add_tail(&ctx->link, &dev_priv->contexts.list);
 	ctx->i915 = dev_priv;
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
index 95c0abfc6d9c..1bcb2b8151b6 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -61,6 +61,8 @@ struct intel_context_ops {
  * logical hardware state for a particular client.
  */
 struct i915_gem_context {
+	struct mutex mutex;
+
 	/** i915: i915 device backpointer */
 	struct drm_i915_private *i915;
 
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 37e1af2ebe7d..fdf7d41b9b3d 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -762,6 +762,7 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
 
 	batch = eb_batch_index(eb);
 
+	mutex_lock(&eb->ctx->mutex);
 	mutex_lock(&eb->vm->mutex);
 	for (i = 0; i < eb->buffer_count; i++) {
 		u32 handle = eb->exec[i].handle;
@@ -798,16 +799,18 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
 			goto err_obj;
 		}
 
-		mutex_lock(&eb->vm->mutex);
-
-		/* transfer ref to ctx */
+		/* transfer ref to obj/ctx */
+		i915_gem_object_lock(obj);
 		if (!vma->open_count++)
 			i915_vma_reopen(vma);
 		list_add(&lut->obj_link, &obj->lut_list);
 		list_add(&lut->ctx_link, &eb->ctx->handles_list);
+		lut->obj = obj;
 		lut->ctx = eb->ctx;
 		lut->handle = handle;
+		i915_gem_object_unlock(obj);
 
+		mutex_lock(&eb->vm->mutex);
 add_vma:
 		err = eb_add_vma(eb, i, batch, vma);
 		if (unlikely(err)) {
@@ -824,12 +827,14 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
 	eb->args->flags |= __EXEC_VALIDATED;
 	err = eb_reserve(eb);
 	mutex_unlock(&eb->vm->mutex);
+	mutex_unlock(&eb->ctx->mutex);
 	return err;
 
 err_obj:
 	i915_gem_object_put(obj);
 err_vma:
 	eb->vma[i] = NULL;
+	mutex_unlock(&eb->ctx->mutex);
 	return err;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 5d153e0f1601..198d7f465ac5 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -47,6 +47,7 @@ struct drm_i915_gem_object;
 struct i915_lut_handle {
 	struct list_head obj_link;
 	struct list_head ctx_link;
+	struct drm_i915_gem_object *obj;
 	struct i915_gem_context *ctx;
 	u32 handle;
 };
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
index fcc221b260d2..a64038d87aeb 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -236,7 +236,7 @@ int i915_gem_render_state_emit(struct i915_request *rq)
 	mutex_lock(&ggtt->vm.mutex);
 	__i915_vma_unpin(so.vma);
 err_vma_locked:
-	i915_vma_close(so.vma);
+	__i915_vma_close(so.vma);
 	mutex_unlock(&ggtt->vm.mutex);
 err_obj:
 	i915_gem_object_put(so.obj);
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index de64041b9ac3..63484f46aa97 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -433,8 +433,11 @@ void i915_vma_unpin_and_release(struct i915_vma **p_vma)
 	if (!vma)
 		return;
 
-	i915_vma_unpin(vma);
-	i915_vma_close(vma);
+	mutex_lock(&vma->vm->mutex);
+	__i915_vma_unpin(vma);
+	__i915_vma_close(vma);
+	mutex_unlock(&vma->vm->mutex);
+
 	i915_vma_put(vma);
 }
 
@@ -805,9 +808,12 @@ int __i915_vma_do_pin(struct i915_vma *vma,
 	return ret;
 }
 
-void i915_vma_close(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;
+
+	lockdep_assert_held(&vma->vm->mutex);
+	GEM_BUG_ON(i915_vma_is_pinned(vma));
 
 	GEM_BUG_ON(i915_vma_is_closed(vma));
 	vma->flags |= I915_VMA_CLOSED;
@@ -824,16 +830,24 @@ 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(&i915->gt.closed_lock);
+	list_add_tail(&vma->closed_link, &i915->gt.closed_vma);
+	spin_unlock(&i915->gt.closed_lock);
 }
 
 void i915_vma_reopen(struct i915_vma *vma)
 {
-	lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
+	i915_vma_assert_held(vma);
 
 	if (vma->flags & I915_VMA_CLOSED) {
+		struct drm_i915_private *i915 = vma->vm->i915;
+
 		vma->flags &= ~I915_VMA_CLOSED;
+
+		spin_lock(&i915->gt.closed_lock);
 		list_del(&vma->closed_link);
+		spin_unlock(&i915->gt.closed_lock);
 	}
 }
 
@@ -842,7 +856,15 @@ static void __i915_vma_destroy(struct i915_vma *vma)
 	struct drm_i915_private *i915 = vma->vm->i915;
 	struct i915_vma_active *iter, *n;
 
-	GEM_BUG_ON(vma->node.allocated);
+	GEM_BUG_ON(i915_vma_is_pinned(vma));
+
+	if (drm_mm_node_allocated(&vma->node)) {
+		mutex_lock(&vma->vm->mutex);
+		i915_vma_unbind(vma);
+		mutex_unlock(&vma->vm->mutex);
+	}
+
+	GEM_BUG_ON(drm_mm_node_allocated(&vma->node));
 	GEM_BUG_ON(vma->fence);
 
 	GEM_BUG_ON(i915_gem_active_isset(&vma->last_fence));
@@ -869,33 +891,42 @@ static void __i915_vma_destroy(struct i915_vma *vma)
 
 void i915_vma_destroy(struct i915_vma *vma)
 {
-	struct i915_address_space *vm = vma->vm;
-
-	lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
-
 	GEM_BUG_ON(i915_vma_is_active(vma));
 	GEM_BUG_ON(i915_vma_is_pinned(vma));
 
-	if (i915_vma_is_closed(vma))
-		list_del(&vma->closed_link);
+	if (i915_vma_is_closed(vma)) {
+		struct drm_i915_private *i915 = vma->vm->i915;
 
-	mutex_lock(&vm->mutex);
-	WARN_ON(i915_vma_unbind(vma));
-	mutex_unlock(&vm->mutex);
+		spin_lock(&i915->gt.closed_lock);
+		list_del(&vma->closed_link);
+		spin_unlock(&i915->gt.closed_lock);
+	}
 
 	__i915_vma_destroy(vma);
 }
 
 void i915_vma_parked(struct drm_i915_private *i915)
 {
-	struct i915_vma *vma, *next;
+	if (list_empty(&i915->gt.closed_vma))
+		return;
+
+	spin_lock(&i915->gt.closed_lock);
+	while (!list_empty(&i915->gt.closed_vma)) {
+		struct i915_vma *vma;
+
+		vma = list_first_entry(&i915->gt.closed_vma,
+				       typeof(*vma), closed_link);
 
-	list_for_each_entry_safe(vma, next, &i915->gt.closed_vma, closed_link) {
 		GEM_BUG_ON(!i915_vma_is_closed(vma));
-		i915_vma_destroy(vma);
-	}
+		vma->flags &= ~I915_VMA_CLOSED;
+		list_del(&vma->closed_link);
+		spin_unlock(&i915->gt.closed_lock);
 
-	GEM_BUG_ON(!list_empty(&i915->gt.closed_vma));
+		__i915_vma_destroy(vma);
+
+		spin_lock(&i915->gt.closed_lock);
+	}
+	spin_unlock(&i915->gt.closed_lock);
 }
 
 static void __i915_vma_iounmap(struct i915_vma *vma)
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index aef9877652d9..c6d4ae404eaa 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -283,10 +283,8 @@ bool i915_vma_misplaced(const struct i915_vma *vma,
 			u64 size, u64 alignment, u64 flags);
 void __i915_vma_set_map_and_fenceable(struct i915_vma *vma);
 void i915_vma_revoke_mmap(struct i915_vma *vma);
-int __must_check i915_vma_unbind(struct i915_vma *vma);
+int i915_vma_unbind(struct i915_vma *vma);
 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 void ____i915_vma_pin(struct i915_vma *vma)
@@ -359,6 +357,16 @@ static inline void i915_vma_unpin(struct i915_vma *vma)
 	mutex_unlock(&vma->vm->mutex);
 }
 
+void __i915_vma_close(struct i915_vma *vma);
+static inline void i915_vma_close(struct i915_vma *vma)
+{
+	mutex_lock(&vma->vm->mutex);
+	__i915_vma_close(vma);
+	mutex_unlock(&vma->vm->mutex);
+}
+
+void i915_vma_reopen(struct i915_vma *vma);
+
 static inline bool i915_vma_is_bound(const struct i915_vma *vma,
 				     unsigned int where)
 {
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index 4ae04144c30a..881014c518d1 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -543,19 +543,13 @@ static void cleanup_phys_status_page(struct intel_engine_cs *engine)
 static void cleanup_status_page(struct intel_engine_cs *engine)
 {
 	struct i915_vma *vma;
-	struct drm_i915_gem_object *obj;
 
 	vma = fetch_and_zero(&engine->status_page.vma);
 	if (!vma)
 		return;
 
-	obj = vma->obj;
-
-	i915_vma_unpin(vma);
-	i915_vma_close(vma);
-
-	i915_gem_object_unpin_map(obj);
-	i915_gem_object_put(obj);
+	i915_gem_object_unpin_map(vma->obj);
+	i915_vma_unpin_and_release(&vma);
 }
 
 static int init_status_page(struct intel_engine_cs *engine)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index fa947f374e6f..41f47a57944d 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1194,8 +1194,10 @@ intel_engine_create_ring(struct intel_engine_cs *engine,
 void
 intel_ring_free(struct intel_ring *ring)
 {
-	i915_vma_close(ring->vma);
-	i915_vma_put(ring->vma);
+	struct drm_i915_gem_object *obj = ring->vma->obj;
+
+	i915_vma_destroy(ring->vma);
+	i915_gem_object_put(obj);
 
 	i915_timeline_put(ring->timeline);
 	kfree(ring);
diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c
index 5acce448a150..b1357aba02cb 100644
--- a/drivers/gpu/drm/i915/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/selftests/huge_pages.c
@@ -433,8 +433,10 @@ static int igt_mock_exhaust_device_supported_pages(void *arg)
 				err = -EINVAL;
 			}
 
-			i915_vma_unpin(vma);
-			i915_vma_close(vma);
+			mutex_lock(&vma->vm->mutex);
+			__i915_vma_unpin(vma);
+			__i915_vma_close(vma);
+			mutex_unlock(&vma->vm->mutex);
 
 			i915_gem_object_put(obj);
 
@@ -512,7 +514,6 @@ static int igt_mock_ppgtt_misaligned_dma(void *arg)
 			goto out_unpin;
 		}
 
-
 		err = igt_check_page_sizes(vma);
 
 		if (vma->page_sizes.gtt != page_size) {
@@ -862,8 +863,10 @@ static int igt_mock_ppgtt_64K(void *arg)
 				goto out_vma_unpin;
 			}
 
-			i915_vma_unpin(vma);
-			i915_vma_close(vma);
+			mutex_lock(&vma->vm->mutex);
+			__i915_vma_unpin(vma);
+			__i915_vma_close(vma);
+			mutex_lock(&vma->vm->mutex);
 
 			i915_gem_object_unpin_pages(obj);
 			i915_gem_object_put(obj);
@@ -989,17 +992,13 @@ static int gpu_write(struct i915_vma *vma,
 	err = i915_vma_move_to_active(batch, rq, 0);
 	i915_vma_unlock(batch);
 	if (err)
-		goto err_request;
-
-	i915_vma_unpin(batch);
-	i915_vma_close(batch);
-	i915_vma_put(batch);
+		goto err_unpin;
 
 	err = engine->emit_bb_start(rq,
 				    batch->node.start, batch->node.size,
 				    flags);
 	if (err)
-		goto err_request;
+		goto err_unpin;
 
 	i915_vma_lock(vma);
 	err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);
@@ -1007,6 +1006,8 @@ static int gpu_write(struct i915_vma *vma,
 	if (err)
 		i915_request_skip(rq, err);
 
+err_unpin:
+	i915_vma_unpin_and_release(&batch);
 err_request:
 	i915_request_add(rq);
 
@@ -1490,10 +1491,7 @@ static int igt_ppgtt_pin_update(void *arg)
 		if (err)
 			goto out_unpin;
 
-		i915_vma_unpin(vma);
-		i915_vma_close(vma);
-
-		i915_gem_object_put(obj);
+		i915_vma_unpin_and_release(&vma);
 	}
 
 	obj = i915_gem_object_create_internal(dev_priv, PAGE_SIZE);
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
index 3ae29cb2050c..6331a1f02914 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
@@ -183,10 +183,7 @@ static int gpu_fill(struct drm_i915_gem_object *obj,
 	if (err)
 		goto skip_request;
 
-	i915_vma_unpin(batch);
-	i915_vma_close(batch);
-	i915_vma_put(batch);
-
+	i915_vma_unpin_and_release(&batch);
 	i915_vma_unpin(vma);
 
 	i915_request_add(rq);
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index c97075c5ccaf..0cd0ba90a5a3 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -222,6 +222,7 @@ struct drm_i915_private *mock_gem_device(void)
 	if (!i915->priorities)
 		goto err_dependencies;
 
+	spin_lock_init(&i915->gt.closed_lock);
 	INIT_LIST_HEAD(&i915->gt.timelines);
 	INIT_LIST_HEAD(&i915->gt.active_rings);
 	INIT_LIST_HEAD(&i915->gt.closed_vma);
-- 
2.18.0



More information about the Intel-gfx-trybot mailing list