Loading...
Note: File does not exist in v3.1.
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright © 2018 Intel Corporation
4 */
5
6#include "i915_selftest.h"
7#include "selftests/igt_reset.h"
8#include "selftests/igt_atomic.h"
9
10static int igt_global_reset(void *arg)
11{
12 struct intel_gt *gt = arg;
13 unsigned int reset_count;
14 intel_wakeref_t wakeref;
15 int err = 0;
16
17 /* Check that we can issue a global GPU reset */
18
19 igt_global_reset_lock(gt);
20 wakeref = intel_runtime_pm_get(>->i915->runtime_pm);
21
22 reset_count = i915_reset_count(>->i915->gpu_error);
23
24 intel_gt_reset(gt, ALL_ENGINES, NULL);
25
26 if (i915_reset_count(>->i915->gpu_error) == reset_count) {
27 pr_err("No GPU reset recorded!\n");
28 err = -EINVAL;
29 }
30
31 intel_runtime_pm_put(>->i915->runtime_pm, wakeref);
32 igt_global_reset_unlock(gt);
33
34 if (intel_gt_is_wedged(gt))
35 err = -EIO;
36
37 return err;
38}
39
40static int igt_wedged_reset(void *arg)
41{
42 struct intel_gt *gt = arg;
43 intel_wakeref_t wakeref;
44
45 /* Check that we can recover a wedged device with a GPU reset */
46
47 igt_global_reset_lock(gt);
48 wakeref = intel_runtime_pm_get(>->i915->runtime_pm);
49
50 intel_gt_set_wedged(gt);
51
52 GEM_BUG_ON(!intel_gt_is_wedged(gt));
53 intel_gt_reset(gt, ALL_ENGINES, NULL);
54
55 intel_runtime_pm_put(>->i915->runtime_pm, wakeref);
56 igt_global_reset_unlock(gt);
57
58 return intel_gt_is_wedged(gt) ? -EIO : 0;
59}
60
61static int igt_atomic_reset(void *arg)
62{
63 struct intel_gt *gt = arg;
64 const typeof(*igt_atomic_phases) *p;
65 int err = 0;
66
67 /* Check that the resets are usable from atomic context */
68
69 intel_gt_pm_get(gt);
70 igt_global_reset_lock(gt);
71
72 /* Flush any requests before we get started and check basics */
73 if (!igt_force_reset(gt))
74 goto unlock;
75
76 for (p = igt_atomic_phases; p->name; p++) {
77 intel_engine_mask_t awake;
78
79 GEM_TRACE("__intel_gt_reset under %s\n", p->name);
80
81 awake = reset_prepare(gt);
82 p->critical_section_begin();
83
84 err = __intel_gt_reset(gt, ALL_ENGINES);
85
86 p->critical_section_end();
87 reset_finish(gt, awake);
88
89 if (err) {
90 pr_err("__intel_gt_reset failed under %s\n", p->name);
91 break;
92 }
93 }
94
95 /* As we poke around the guts, do a full reset before continuing. */
96 igt_force_reset(gt);
97
98unlock:
99 igt_global_reset_unlock(gt);
100 intel_gt_pm_put(gt);
101
102 return err;
103}
104
105static int igt_atomic_engine_reset(void *arg)
106{
107 struct intel_gt *gt = arg;
108 const typeof(*igt_atomic_phases) *p;
109 struct intel_engine_cs *engine;
110 enum intel_engine_id id;
111 int err = 0;
112
113 /* Check that the resets are usable from atomic context */
114
115 if (!intel_has_reset_engine(gt->i915))
116 return 0;
117
118 if (USES_GUC_SUBMISSION(gt->i915))
119 return 0;
120
121 intel_gt_pm_get(gt);
122 igt_global_reset_lock(gt);
123
124 /* Flush any requests before we get started and check basics */
125 if (!igt_force_reset(gt))
126 goto out_unlock;
127
128 for_each_engine(engine, gt->i915, id) {
129 tasklet_disable_nosync(&engine->execlists.tasklet);
130 intel_engine_pm_get(engine);
131
132 for (p = igt_atomic_phases; p->name; p++) {
133 GEM_TRACE("intel_engine_reset(%s) under %s\n",
134 engine->name, p->name);
135
136 p->critical_section_begin();
137 err = intel_engine_reset(engine, NULL);
138 p->critical_section_end();
139
140 if (err) {
141 pr_err("intel_engine_reset(%s) failed under %s\n",
142 engine->name, p->name);
143 break;
144 }
145 }
146
147 intel_engine_pm_put(engine);
148 tasklet_enable(&engine->execlists.tasklet);
149 if (err)
150 break;
151 }
152
153 /* As we poke around the guts, do a full reset before continuing. */
154 igt_force_reset(gt);
155
156out_unlock:
157 igt_global_reset_unlock(gt);
158 intel_gt_pm_put(gt);
159
160 return err;
161}
162
163int intel_reset_live_selftests(struct drm_i915_private *i915)
164{
165 static const struct i915_subtest tests[] = {
166 SUBTEST(igt_global_reset), /* attempt to recover GPU first */
167 SUBTEST(igt_wedged_reset),
168 SUBTEST(igt_atomic_reset),
169 SUBTEST(igt_atomic_engine_reset),
170 };
171 struct intel_gt *gt = &i915->gt;
172
173 if (!intel_has_gpu_reset(gt->i915))
174 return 0;
175
176 if (intel_gt_is_wedged(gt))
177 return -EIO; /* we're long past hope of a successful reset */
178
179 return intel_gt_live_subtests(tests, gt);
180}