diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-09-09 09:11:50 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2016-09-09 09:23:03 -0400 |
commit | 22dd3bb9190566c7c3b80edb7dea67d1e21d0f91 (patch) | |
tree | 01898a53077a19a7c4608716a7c638924bc0992b /drivers/gpu/drm | |
parent | ea746f3659232b3104d9534d5a7ebd9934ae1dd6 (diff) |
drm/i915: Mark up all locked waiters
In the next patch we want to handle reset directly by a locked waiter in
order to avoid issues with returning before the reset is handled. To
handle the reset, we must first know whether we hold the struct_mutex.
If we do not hold the struct_mtuex we can not perform the reset, but we do
not block the reset worker either (and so we can just continue to wait for
request completion) - otherwise we must relinquish the mutex.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20160909131201.16673-10-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_evict.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_request.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_request.h | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_shrinker.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 3 |
8 files changed, 38 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 0e4cbad7a883..6a270bc0fdb3 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -4794,7 +4794,9 @@ i915_drop_caches_set(void *data, u64 val) | |||
4794 | return ret; | 4794 | return ret; |
4795 | 4795 | ||
4796 | if (val & DROP_ACTIVE) { | 4796 | if (val & DROP_ACTIVE) { |
4797 | ret = i915_gem_wait_for_idle(dev_priv, I915_WAIT_INTERRUPTIBLE); | 4797 | ret = i915_gem_wait_for_idle(dev_priv, |
4798 | I915_WAIT_INTERRUPTIBLE | | ||
4799 | I915_WAIT_LOCKED); | ||
4798 | if (ret) | 4800 | if (ret) |
4799 | goto unlock; | 4801 | goto unlock; |
4800 | } | 4802 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4617250c3000..23069a2d2850 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2802,7 +2802,8 @@ __i915_gem_object_sync(struct drm_i915_gem_request *to, | |||
2802 | 2802 | ||
2803 | if (!i915.semaphores) { | 2803 | if (!i915.semaphores) { |
2804 | ret = i915_wait_request(from, | 2804 | ret = i915_wait_request(from, |
2805 | from->i915->mm.interruptible, | 2805 | from->i915->mm.interruptible | |
2806 | I915_WAIT_LOCKED, | ||
2806 | NULL, | 2807 | NULL, |
2807 | NO_WAITBOOST); | 2808 | NO_WAITBOOST); |
2808 | if (ret) | 2809 | if (ret) |
@@ -4304,7 +4305,9 @@ int i915_gem_suspend(struct drm_device *dev) | |||
4304 | if (ret) | 4305 | if (ret) |
4305 | goto err; | 4306 | goto err; |
4306 | 4307 | ||
4307 | ret = i915_gem_wait_for_idle(dev_priv, I915_WAIT_INTERRUPTIBLE); | 4308 | ret = i915_gem_wait_for_idle(dev_priv, |
4309 | I915_WAIT_INTERRUPTIBLE | | ||
4310 | I915_WAIT_LOCKED); | ||
4308 | if (ret) | 4311 | if (ret) |
4309 | goto err; | 4312 | goto err; |
4310 | 4313 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 103085246975..5b6f81c1dbca 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -170,7 +170,9 @@ search_again: | |||
170 | if (ret) | 170 | if (ret) |
171 | return ret; | 171 | return ret; |
172 | 172 | ||
173 | ret = i915_gem_wait_for_idle(dev_priv, I915_WAIT_INTERRUPTIBLE); | 173 | ret = i915_gem_wait_for_idle(dev_priv, |
174 | I915_WAIT_INTERRUPTIBLE | | ||
175 | I915_WAIT_LOCKED); | ||
174 | if (ret) | 176 | if (ret) |
175 | return ret; | 177 | return ret; |
176 | 178 | ||
@@ -275,7 +277,9 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle) | |||
275 | return ret; | 277 | return ret; |
276 | } | 278 | } |
277 | 279 | ||
278 | ret = i915_gem_wait_for_idle(dev_priv, I915_WAIT_INTERRUPTIBLE); | 280 | ret = i915_gem_wait_for_idle(dev_priv, |
281 | I915_WAIT_INTERRUPTIBLE | | ||
282 | I915_WAIT_LOCKED); | ||
279 | if (ret) | 283 | if (ret) |
280 | return ret; | 284 | return ret; |
281 | 285 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 9bcac52b8268..f3c6876da521 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -2683,7 +2683,7 @@ void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj) | |||
2683 | struct i915_ggtt *ggtt = &dev_priv->ggtt; | 2683 | struct i915_ggtt *ggtt = &dev_priv->ggtt; |
2684 | 2684 | ||
2685 | if (unlikely(ggtt->do_idle_maps)) { | 2685 | if (unlikely(ggtt->do_idle_maps)) { |
2686 | if (i915_gem_wait_for_idle(dev_priv, 0)) { | 2686 | if (i915_gem_wait_for_idle(dev_priv, I915_WAIT_LOCKED)) { |
2687 | DRM_ERROR("Failed to wait for idle; VT'd may hang.\n"); | 2687 | DRM_ERROR("Failed to wait for idle; VT'd may hang.\n"); |
2688 | /* Wait a bit, in hopes it avoids the hang */ | 2688 | /* Wait a bit, in hopes it avoids the hang */ |
2689 | udelay(10); | 2689 | udelay(10); |
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index f4c15f319d08..5f89801e6a16 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c | |||
@@ -260,7 +260,9 @@ static int i915_gem_init_seqno(struct drm_i915_private *dev_priv, u32 seqno) | |||
260 | 260 | ||
261 | /* Carefully retire all requests without writing to the rings */ | 261 | /* Carefully retire all requests without writing to the rings */ |
262 | for_each_engine(engine, dev_priv) { | 262 | for_each_engine(engine, dev_priv) { |
263 | ret = intel_engine_idle(engine, I915_WAIT_INTERRUPTIBLE); | 263 | ret = intel_engine_idle(engine, |
264 | I915_WAIT_INTERRUPTIBLE | | ||
265 | I915_WAIT_LOCKED); | ||
264 | if (ret) | 266 | if (ret) |
265 | return ret; | 267 | return ret; |
266 | } | 268 | } |
@@ -625,6 +627,10 @@ int i915_wait_request(struct drm_i915_gem_request *req, | |||
625 | int ret = 0; | 627 | int ret = 0; |
626 | 628 | ||
627 | might_sleep(); | 629 | might_sleep(); |
630 | #if IS_ENABLED(CONFIG_LOCKDEP) | ||
631 | GEM_BUG_ON(!!lockdep_is_held(&req->i915->drm.struct_mutex) != | ||
632 | !!(flags & I915_WAIT_LOCKED)); | ||
633 | #endif | ||
628 | 634 | ||
629 | if (i915_gem_request_completed(req)) | 635 | if (i915_gem_request_completed(req)) |
630 | return 0; | 636 | return 0; |
@@ -667,7 +673,8 @@ int i915_wait_request(struct drm_i915_gem_request *req, | |||
667 | goto complete; | 673 | goto complete; |
668 | 674 | ||
669 | set_current_state(state); | 675 | set_current_state(state); |
670 | add_wait_queue(&req->i915->gpu_error.wait_queue, &reset); | 676 | if (flags & I915_WAIT_LOCKED) |
677 | add_wait_queue(&req->i915->gpu_error.wait_queue, &reset); | ||
671 | 678 | ||
672 | intel_wait_init(&wait, req->fence.seqno); | 679 | intel_wait_init(&wait, req->fence.seqno); |
673 | if (intel_engine_add_wait(req->engine, &wait)) | 680 | if (intel_engine_add_wait(req->engine, &wait)) |
@@ -707,10 +714,12 @@ wakeup: | |||
707 | if (i915_spin_request(req, state, 2)) | 714 | if (i915_spin_request(req, state, 2)) |
708 | break; | 715 | break; |
709 | } | 716 | } |
710 | remove_wait_queue(&req->i915->gpu_error.wait_queue, &reset); | ||
711 | 717 | ||
712 | intel_engine_remove_wait(req->engine, &wait); | 718 | intel_engine_remove_wait(req->engine, &wait); |
719 | if (flags & I915_WAIT_LOCKED) | ||
720 | remove_wait_queue(&req->i915->gpu_error.wait_queue, &reset); | ||
713 | __set_current_state(TASK_RUNNING); | 721 | __set_current_state(TASK_RUNNING); |
722 | |||
714 | complete: | 723 | complete: |
715 | trace_i915_gem_request_wait_end(req); | 724 | trace_i915_gem_request_wait_end(req); |
716 | 725 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h index 479896ef791e..def35721e9ed 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.h +++ b/drivers/gpu/drm/i915/i915_gem_request.h | |||
@@ -222,7 +222,8 @@ int i915_wait_request(struct drm_i915_gem_request *req, | |||
222 | s64 *timeout, | 222 | s64 *timeout, |
223 | struct intel_rps_client *rps) | 223 | struct intel_rps_client *rps) |
224 | __attribute__((nonnull(1))); | 224 | __attribute__((nonnull(1))); |
225 | #define I915_WAIT_INTERRUPTIBLE BIT(0) | 225 | #define I915_WAIT_INTERRUPTIBLE BIT(0) |
226 | #define I915_WAIT_LOCKED BIT(1) /* struct_mutex held, handle GPU reset */ | ||
226 | 227 | ||
227 | static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine); | 228 | static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine); |
228 | 229 | ||
@@ -576,7 +577,9 @@ i915_gem_active_wait(const struct i915_gem_active *active, struct mutex *mutex) | |||
576 | if (!request) | 577 | if (!request) |
577 | return 0; | 578 | return 0; |
578 | 579 | ||
579 | return i915_wait_request(request, I915_WAIT_INTERRUPTIBLE, NULL, NULL); | 580 | return i915_wait_request(request, |
581 | I915_WAIT_INTERRUPTIBLE | I915_WAIT_LOCKED, | ||
582 | NULL, NULL); | ||
580 | } | 583 | } |
581 | 584 | ||
582 | /** | 585 | /** |
@@ -639,7 +642,9 @@ i915_gem_active_retire(struct i915_gem_active *active, | |||
639 | if (!request) | 642 | if (!request) |
640 | return 0; | 643 | return 0; |
641 | 644 | ||
642 | ret = i915_wait_request(request, I915_WAIT_INTERRUPTIBLE, NULL, NULL); | 645 | ret = i915_wait_request(request, |
646 | I915_WAIT_INTERRUPTIBLE | I915_WAIT_LOCKED, | ||
647 | NULL, NULL); | ||
643 | if (ret) | 648 | if (ret) |
644 | return ret; | 649 | return ret; |
645 | 650 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index 35a05f4c51c1..1c237d02f30b 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c | |||
@@ -414,7 +414,7 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr | |||
414 | return NOTIFY_DONE; | 414 | return NOTIFY_DONE; |
415 | 415 | ||
416 | /* Force everything onto the inactive lists */ | 416 | /* Force everything onto the inactive lists */ |
417 | ret = i915_gem_wait_for_idle(dev_priv, 0); | 417 | ret = i915_gem_wait_for_idle(dev_priv, I915_WAIT_LOCKED); |
418 | if (ret) | 418 | if (ret) |
419 | goto out; | 419 | goto out; |
420 | 420 | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index a5bf18877068..8687a84a7ff3 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -2223,7 +2223,8 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes) | |||
2223 | if (WARN_ON(&target->ring_link == &ring->request_list)) | 2223 | if (WARN_ON(&target->ring_link == &ring->request_list)) |
2224 | return -ENOSPC; | 2224 | return -ENOSPC; |
2225 | 2225 | ||
2226 | ret = i915_wait_request(target, I915_WAIT_INTERRUPTIBLE, | 2226 | ret = i915_wait_request(target, |
2227 | I915_WAIT_INTERRUPTIBLE | I915_WAIT_LOCKED, | ||
2227 | NULL, NO_WAITBOOST); | 2228 | NULL, NO_WAITBOOST); |
2228 | if (ret) | 2229 | if (ret) |
2229 | return ret; | 2230 | return ret; |