1 // SPDX-License-Identifier: MIT
3 * Copyright © 2018 Intel Corporation
6 #include "i915_selftest.h"
7 #include "selftests/igt_reset.h"
8 #include "selftests/igt_atomic.h"
10 static int igt_global_reset(void *arg
)
12 struct intel_gt
*gt
= arg
;
13 unsigned int reset_count
;
14 intel_wakeref_t wakeref
;
17 /* Check that we can issue a global GPU reset */
19 igt_global_reset_lock(gt
);
20 wakeref
= intel_runtime_pm_get(gt
->uncore
->rpm
);
22 reset_count
= i915_reset_count(>
->i915
->gpu_error
);
24 intel_gt_reset(gt
, ALL_ENGINES
, NULL
);
26 if (i915_reset_count(>
->i915
->gpu_error
) == reset_count
) {
27 pr_err("No GPU reset recorded!\n");
31 intel_runtime_pm_put(gt
->uncore
->rpm
, wakeref
);
32 igt_global_reset_unlock(gt
);
34 if (intel_gt_is_wedged(gt
))
40 static int igt_wedged_reset(void *arg
)
42 struct intel_gt
*gt
= arg
;
43 intel_wakeref_t wakeref
;
45 /* Check that we can recover a wedged device with a GPU reset */
47 igt_global_reset_lock(gt
);
48 wakeref
= intel_runtime_pm_get(gt
->uncore
->rpm
);
50 intel_gt_set_wedged(gt
);
52 GEM_BUG_ON(!intel_gt_is_wedged(gt
));
53 intel_gt_reset(gt
, ALL_ENGINES
, NULL
);
55 intel_runtime_pm_put(gt
->uncore
->rpm
, wakeref
);
56 igt_global_reset_unlock(gt
);
58 return intel_gt_is_wedged(gt
) ? -EIO
: 0;
61 static int igt_atomic_reset(void *arg
)
63 struct intel_gt
*gt
= arg
;
64 const typeof(*igt_atomic_phases
) *p
;
67 /* Check that the resets are usable from atomic context */
70 igt_global_reset_lock(gt
);
72 /* Flush any requests before we get started and check basics */
73 if (!igt_force_reset(gt
))
76 for (p
= igt_atomic_phases
; p
->name
; p
++) {
77 intel_engine_mask_t awake
;
79 GEM_TRACE("__intel_gt_reset under %s\n", p
->name
);
81 awake
= reset_prepare(gt
);
82 p
->critical_section_begin();
84 err
= __intel_gt_reset(gt
, ALL_ENGINES
);
86 p
->critical_section_end();
87 reset_finish(gt
, awake
);
90 pr_err("__intel_gt_reset failed under %s\n", p
->name
);
95 /* As we poke around the guts, do a full reset before continuing. */
99 igt_global_reset_unlock(gt
);
105 static int igt_atomic_engine_reset(void *arg
)
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
;
113 /* Check that the resets are usable from atomic context */
115 if (!intel_has_reset_engine(gt
))
118 if (USES_GUC_SUBMISSION(gt
->i915
))
122 igt_global_reset_lock(gt
);
124 /* Flush any requests before we get started and check basics */
125 if (!igt_force_reset(gt
))
128 for_each_engine(engine
, gt
, id
) {
129 tasklet_disable(&engine
->execlists
.tasklet
);
130 intel_engine_pm_get(engine
);
132 for (p
= igt_atomic_phases
; p
->name
; p
++) {
133 GEM_TRACE("intel_engine_reset(%s) under %s\n",
134 engine
->name
, p
->name
);
136 p
->critical_section_begin();
137 err
= intel_engine_reset(engine
, NULL
);
138 p
->critical_section_end();
141 pr_err("intel_engine_reset(%s) failed under %s\n",
142 engine
->name
, p
->name
);
147 intel_engine_pm_put(engine
);
148 tasklet_enable(&engine
->execlists
.tasklet
);
153 /* As we poke around the guts, do a full reset before continuing. */
157 igt_global_reset_unlock(gt
);
163 int intel_reset_live_selftests(struct drm_i915_private
*i915
)
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
),
171 struct intel_gt
*gt
= &i915
->gt
;
173 if (!intel_has_gpu_reset(gt
))
176 if (intel_gt_is_wedged(gt
))
177 return -EIO
; /* we're long past hope of a successful reset */
179 return intel_gt_live_subtests(tests
, gt
);