]>
Commit | Line | Data |
---|---|---|
19956850 GKH |
1 | From cad9946c2a4375386062131858881cfd30fc1b8f Mon Sep 17 00:00:00 2001 |
2 | From: Chris Wilson <chris@chris-wilson.co.uk> | |
3 | Date: Sat, 26 Aug 2017 12:09:33 +0100 | |
4 | Subject: drm/i915: Always sanity check engine state upon idling | |
5 | ||
6 | From: Chris Wilson <chris@chris-wilson.co.uk> | |
7 | ||
8 | commit cad9946c2a4375386062131858881cfd30fc1b8f upstream. | |
9 | ||
10 | When we do a locked idle we know that afterwards all requests have been | |
11 | completed and the engines have been cleared of tasks. For whatever | |
12 | reason, this doesn't always happen and we may go into a suspend with | |
13 | ELSP still full, and this causes an issue upon resume as we get very, | |
14 | very confused. | |
15 | ||
16 | If the engines refuse to idle, mark the device as wedged. In the process | |
17 | we get rid of the maybe unused open-coded version of wait_for_engines | |
18 | reported by Nick Desaulniers and Matthias Kaehlcke. | |
19 | ||
20 | v2: Suppress the -EIO before suspend, but keep it for seqno wrap. | |
21 | ||
22 | References: https://bugs.freedesktop.org/show_bug.cgi?id=101891 | |
23 | References: https://bugs.freedesktop.org/show_bug.cgi?id=102456 | |
24 | Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> | |
25 | Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com> | |
26 | Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> | |
27 | Cc: Matthias Kaehlcke <mka@chromium.org> | |
28 | Link: https://patchwork.freedesktop.org/patch/msgid/20170826110935.10237-1-chris@chris-wilson.co.uk | |
29 | Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> | |
30 | Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com> | |
31 | Cc: Guenter Roeck <linux@roeck-us.net> | |
32 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
33 | ||
34 | --- | |
35 | drivers/gpu/drm/i915/i915_gem.c | 27 ++++++++------------------- | |
36 | 1 file changed, 8 insertions(+), 19 deletions(-) | |
37 | ||
38 | --- a/drivers/gpu/drm/i915/i915_gem.c | |
39 | +++ b/drivers/gpu/drm/i915/i915_gem.c | |
40 | @@ -3378,24 +3378,12 @@ static int wait_for_timeline(struct i915 | |
41 | return 0; | |
42 | } | |
43 | ||
44 | -static int wait_for_engine(struct intel_engine_cs *engine, int timeout_ms) | |
45 | -{ | |
46 | - return wait_for(intel_engine_is_idle(engine), timeout_ms); | |
47 | -} | |
48 | - | |
49 | static int wait_for_engines(struct drm_i915_private *i915) | |
50 | { | |
51 | - struct intel_engine_cs *engine; | |
52 | - enum intel_engine_id id; | |
53 | - | |
54 | - for_each_engine(engine, i915, id) { | |
55 | - if (GEM_WARN_ON(wait_for_engine(engine, 50))) { | |
56 | - i915_gem_set_wedged(i915); | |
57 | - return -EIO; | |
58 | - } | |
59 | - | |
60 | - GEM_BUG_ON(intel_engine_get_seqno(engine) != | |
61 | - intel_engine_last_submit(engine)); | |
62 | + if (wait_for(intel_engines_are_idle(i915), 50)) { | |
63 | + DRM_ERROR("Failed to idle engines, declaring wedged!\n"); | |
64 | + i915_gem_set_wedged(i915); | |
65 | + return -EIO; | |
66 | } | |
67 | ||
68 | return 0; | |
69 | @@ -4575,7 +4563,7 @@ int i915_gem_suspend(struct drm_i915_pri | |
70 | ret = i915_gem_wait_for_idle(dev_priv, | |
71 | I915_WAIT_INTERRUPTIBLE | | |
72 | I915_WAIT_LOCKED); | |
73 | - if (ret) | |
74 | + if (ret && ret != -EIO) | |
75 | goto err_unlock; | |
76 | ||
77 | assert_kernel_context_is_current(dev_priv); | |
78 | @@ -4619,11 +4607,12 @@ int i915_gem_suspend(struct drm_i915_pri | |
79 | * machine in an unusable condition. | |
80 | */ | |
81 | i915_gem_sanitize(dev_priv); | |
82 | - goto out_rpm_put; | |
83 | + | |
84 | + intel_runtime_pm_put(dev_priv); | |
85 | + return 0; | |
86 | ||
87 | err_unlock: | |
88 | mutex_unlock(&dev->struct_mutex); | |
89 | -out_rpm_put: | |
90 | intel_runtime_pm_put(dev_priv); | |
91 | return ret; | |
92 | } |