drm/i915/gt: Convert timeline tracking to spinlock
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 15 Aug 2019 20:57:07 +0000 (21:57 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 15 Aug 2019 22:21:13 +0000 (23:21 +0100)
Convert the active_list manipulation of timelines to use spinlocks so
that we can perform the updates from underneath a quick interrupt
callback, if need be.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190815205709.24285-2-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/gt/intel_gt_types.h
drivers/gpu/drm/i915/gt/intel_reset.c
drivers/gpu/drm/i915/gt/intel_timeline.c
drivers/gpu/drm/i915/i915_gem.c

index adab4d2c29ac6c9e251a786ca810dd2b5140bcc8..143b2d78c2cc99c6ceebff319751021381ebdd0d 100644 (file)
@@ -40,7 +40,7 @@ struct intel_gt {
        struct intel_uc uc;
 
        struct intel_gt_timelines {
-               struct mutex mutex; /* protects list */
+               spinlock_t lock; /* protects active_list */
                struct list_head active_list;
 
                /* Pack multiple timelines' seqnos into the same page */
index ec85740de942f582602e31f18b411db6e6463fff..077716442c90a4832c7acdde3c4eaaf1c05c8987 100644 (file)
@@ -811,7 +811,7 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
         *
         * No more can be submitted until we reset the wedged bit.
         */
-       mutex_lock(&timelines->mutex);
+       spin_lock(&timelines->lock);
        list_for_each_entry(tl, &timelines->active_list, link) {
                struct i915_request *rq;
 
@@ -819,6 +819,8 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
                if (!rq)
                        continue;
 
+               spin_unlock(&timelines->lock);
+
                /*
                 * All internal dependencies (i915_requests) will have
                 * been flushed by the set-wedge, but we may be stuck waiting
@@ -828,8 +830,12 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
                 */
                dma_fence_default_wait(&rq->fence, false, MAX_SCHEDULE_TIMEOUT);
                i915_request_put(rq);
+
+               /* Restart iteration after droping lock */
+               spin_lock(&timelines->lock);
+               tl = list_entry(&timelines->active_list, typeof(*tl), link);
        }
-       mutex_unlock(&timelines->mutex);
+       spin_unlock(&timelines->lock);
 
        intel_gt_sanitize(gt, false);
 
index 4af0b9801d915b575f4d7bb9cf12ef956591bac2..355dfc52c804951651ed4ee482965f00461d8d65 100644 (file)
@@ -266,7 +266,7 @@ static void timelines_init(struct intel_gt *gt)
 {
        struct intel_gt_timelines *timelines = &gt->timelines;
 
-       mutex_init(&timelines->mutex);
+       spin_lock_init(&timelines->lock);
        INIT_LIST_HEAD(&timelines->active_list);
 
        spin_lock_init(&timelines->hwsp_lock);
@@ -345,9 +345,9 @@ void intel_timeline_enter(struct intel_timeline *tl)
                return;
        GEM_BUG_ON(!tl->active_count); /* overflow? */
 
-       mutex_lock(&timelines->mutex);
+       spin_lock(&timelines->lock);
        list_add(&tl->link, &timelines->active_list);
-       mutex_unlock(&timelines->mutex);
+       spin_unlock(&timelines->lock);
 }
 
 void intel_timeline_exit(struct intel_timeline *tl)
@@ -358,9 +358,9 @@ void intel_timeline_exit(struct intel_timeline *tl)
        if (--tl->active_count)
                return;
 
-       mutex_lock(&timelines->mutex);
+       spin_lock(&timelines->lock);
        list_del(&tl->link);
-       mutex_unlock(&timelines->mutex);
+       spin_unlock(&timelines->lock);
 
        /*
         * Since this timeline is idle, all bariers upon which we were waiting
@@ -548,8 +548,6 @@ static void timelines_fini(struct intel_gt *gt)
 
        GEM_BUG_ON(!list_empty(&timelines->active_list));
        GEM_BUG_ON(!list_empty(&timelines->hwsp_free_list));
-
-       mutex_destroy(&timelines->mutex);
 }
 
 void intel_timelines_fini(struct drm_i915_private *i915)
index 4752a3bf963611e45a180d927f77ae85fabfc1e7..29be25a7aaded8603ee19effba75b3187603c3ee 100644 (file)
@@ -897,18 +897,18 @@ static long
 wait_for_timelines(struct drm_i915_private *i915,
                   unsigned int flags, long timeout)
 {
-       struct intel_gt_timelines *gt = &i915->gt.timelines;
+       struct intel_gt_timelines *timelines = &i915->gt.timelines;
        struct intel_timeline *tl;
 
-       mutex_lock(&gt->mutex);
-       list_for_each_entry(tl, &gt->active_list, link) {
+       spin_lock(&timelines->lock);
+       list_for_each_entry(tl, &timelines->active_list, link) {
                struct i915_request *rq;
 
                rq = i915_active_request_get_unlocked(&tl->last_request);
                if (!rq)
                        continue;
 
-               mutex_unlock(&gt->mutex);
+               spin_unlock(&timelines->lock);
 
                /*
                 * "Race-to-idle".
@@ -928,10 +928,10 @@ wait_for_timelines(struct drm_i915_private *i915,
                        return timeout;
 
                /* restart after reacquiring the lock */
-               mutex_lock(&gt->mutex);
-               tl = list_entry(&gt->active_list, typeof(*tl), link);
+               spin_lock(&timelines->lock);
+               tl = list_entry(&timelines->active_list, typeof(*tl), link);
        }
-       mutex_unlock(&gt->mutex);
+       spin_unlock(&timelines->lock);
 
        return timeout;
 }