[PATCH 28/40] timeline-lock

Chris Wilson chris at chris-wilson.co.uk
Sat Oct 27 16:22:52 UTC 2018


---
 drivers/gpu/drm/i915/i915_drv.h                  |  1 +
 drivers/gpu/drm/i915/i915_gem.c                  | 10 ++++++++++
 drivers/gpu/drm/i915/i915_request.c              |  2 ++
 drivers/gpu/drm/i915/i915_timeline.c             | 11 +++++++----
 drivers/gpu/drm/i915/i915_timeline.h             |  1 +
 drivers/gpu/drm/i915/selftests/mock_gem_device.c |  4 ++++
 drivers/gpu/drm/i915/selftests/mock_timeline.c   |  3 ++-
 7 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4940871bbf01..1818ae34e4c5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2107,6 +2107,7 @@ struct drm_i915_private {
 		void (*resume)(struct drm_i915_private *);
 		void (*cleanup_engine)(struct intel_engine_cs *engine);
 
+		struct mutex timeline_lock;
 		struct list_head timelines;
 
 		struct list_head active_rings;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 02ddda1d24c8..65d96fc7cd64 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3396,11 +3396,17 @@ int i915_gem_wait_for_idle(struct drm_i915_private *i915,
 
 		lockdep_assert_held(&i915->drm.struct_mutex);
 
+		mutex_lock(&i915->gt.timeline_lock);
 		list_for_each_entry(tl, &i915->gt.timelines, link) {
+			mutex_unlock(&i915->gt.timeline_lock);
+
 			timeout = wait_for_timeline(tl, flags, timeout);
 			if (timeout < 0)
 				return timeout;
+
+			mutex_lock(&i915->gt.timeline_lock);
 		}
+		mutex_unlock(&i915->gt.timeline_lock);
 		if (GEM_SHOW_DEBUG() && !timeout) {
 			/* Presume that timeout was non-zero to begin with! */
 			dev_warn(&i915->drm.pdev->dev,
@@ -5338,7 +5344,9 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
 	if (!dev_priv->priorities)
 		goto err_dependencies;
 
+	mutex_init(&dev_priv->gt.timeline_lock);
 	INIT_LIST_HEAD(&dev_priv->gt.timelines);
+
 	INIT_LIST_HEAD(&dev_priv->gt.active_rings);
 	INIT_LIST_HEAD(&dev_priv->gt.closed_vma);
 
@@ -5382,7 +5390,9 @@ void i915_gem_cleanup_early(struct drm_i915_private *dev_priv)
 	GEM_BUG_ON(!llist_empty(&dev_priv->mm.free_list));
 	GEM_BUG_ON(atomic_read(&dev_priv->mm.free_count));
 	WARN_ON(dev_priv->mm.object_count);
+
 	WARN_ON(!list_empty(&dev_priv->gt.timelines));
+	mutex_destroy(&dev_priv->gt.timeline_lock);
 
 	kmem_cache_destroy(dev_priv->priorities);
 	kmem_cache_destroy(dev_priv->dependencies);
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 6a8a51901c34..3df5063f7b18 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -157,8 +157,10 @@ static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
 		kthread_unpark(engine->breadcrumbs.signaler);
 	}
 
+	mutex_lock(&i915->gt.timeline_lock);
 	list_for_each_entry(timeline, &i915->gt.timelines, link)
 		memset(timeline->global_sync, 0, sizeof(timeline->global_sync));
+	mutex_unlock(&i915->gt.timeline_lock);
 
 	i915->gt.request_serial = seqno;
 
diff --git a/drivers/gpu/drm/i915/i915_timeline.c b/drivers/gpu/drm/i915/i915_timeline.c
index 4667cc08c416..c4e7ad179d86 100644
--- a/drivers/gpu/drm/i915/i915_timeline.c
+++ b/drivers/gpu/drm/i915/i915_timeline.c
@@ -13,8 +13,6 @@ void i915_timeline_init(struct drm_i915_private *i915,
 			struct i915_timeline *timeline,
 			const char *name)
 {
-	lockdep_assert_held(&i915->drm.struct_mutex);
-
 	/*
 	 * Ideally we want a set of engines on a single leaf as we expect
 	 * to mostly be tracking synchronisation between engines. It is not
@@ -23,9 +21,12 @@ void i915_timeline_init(struct drm_i915_private *i915,
 	 */
 	BUILD_BUG_ON(KSYNCMAP < I915_NUM_ENGINES);
 
+	timeline->i915 = i915;
 	timeline->name = name;
 
+	mutex_lock(&i915->gt.timeline_lock);
 	list_add(&timeline->link, &i915->gt.timelines);
+	mutex_unlock(&i915->gt.timeline_lock);
 
 	/* Called during early_init before we know how many engines there are */
 
@@ -53,8 +54,7 @@ void i915_timelines_park(struct drm_i915_private *i915)
 {
 	struct i915_timeline *timeline;
 
-	lockdep_assert_held(&i915->drm.struct_mutex);
-
+	mutex_lock(&i915->gt.timeline_lock);
 	list_for_each_entry(timeline, &i915->gt.timelines, link) {
 		/*
 		 * All known fences are completed so we can scrap
@@ -64,6 +64,7 @@ void i915_timelines_park(struct drm_i915_private *i915)
 		 */
 		i915_syncmap_free(&timeline->sync);
 	}
+	mutex_unlock(&i915->gt.timeline_lock);
 }
 
 void i915_timeline_fini(struct i915_timeline *timeline)
@@ -72,7 +73,9 @@ void i915_timeline_fini(struct i915_timeline *timeline)
 
 	i915_syncmap_free(&timeline->sync);
 
+	mutex_lock(&timeline->i915->gt.timeline_lock);
 	list_del(&timeline->link);
+	mutex_unlock(&timeline->i915->gt.timeline_lock);
 }
 
 struct i915_timeline *
diff --git a/drivers/gpu/drm/i915/i915_timeline.h b/drivers/gpu/drm/i915/i915_timeline.h
index a2c2c3ab5fb0..83921bab91da 100644
--- a/drivers/gpu/drm/i915/i915_timeline.h
+++ b/drivers/gpu/drm/i915/i915_timeline.h
@@ -74,6 +74,7 @@ struct i915_timeline {
 
 	struct list_head link;
 	const char *name;
+	struct drm_i915_private *i915;
 
 	struct kref kref;
 };
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 4a25d2a344f2..b2292eb609f8 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -74,7 +74,9 @@ static void mock_device_release(struct drm_device *dev)
 	mutex_lock(&i915->drm.struct_mutex);
 	mock_fini_ggtt(i915);
 	mutex_unlock(&i915->drm.struct_mutex);
+
 	WARN_ON(!list_empty(&i915->gt.timelines));
+	mutex_destroy(&i915->gt.timeline_lock);
 
 	destroy_workqueue(i915->wq);
 
@@ -227,7 +229,9 @@ struct drm_i915_private *mock_gem_device(void)
 	if (!i915->priorities)
 		goto err_dependencies;
 
+	mutex_init(&i915->gt.timeline_lock);
 	INIT_LIST_HEAD(&i915->gt.timelines);
+
 	INIT_LIST_HEAD(&i915->gt.active_rings);
 	INIT_LIST_HEAD(&i915->gt.closed_vma);
 
diff --git a/drivers/gpu/drm/i915/selftests/mock_timeline.c b/drivers/gpu/drm/i915/selftests/mock_timeline.c
index dcf3b16f5a07..cf39ccd9fc05 100644
--- a/drivers/gpu/drm/i915/selftests/mock_timeline.c
+++ b/drivers/gpu/drm/i915/selftests/mock_timeline.c
@@ -10,6 +10,7 @@
 
 void mock_timeline_init(struct i915_timeline *timeline, u64 context)
 {
+	timeline->i915 = NULL;
 	timeline->fence_context = context;
 
 	spin_lock_init(&timeline->lock);
@@ -24,5 +25,5 @@ void mock_timeline_init(struct i915_timeline *timeline, u64 context)
 
 void mock_timeline_fini(struct i915_timeline *timeline)
 {
-	i915_timeline_fini(timeline);
+	i915_syncmap_free(&timeline->sync);
 }
-- 
2.19.1



More information about the Intel-gfx-trybot mailing list