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 10 static int igt_global_reset(void *arg) 11 { 12 struct drm_i915_private *i915 = arg; 13 unsigned int reset_count; 14 int err = 0; 15 16 /* Check that we can issue a global GPU reset */ 17 18 igt_global_reset_lock(i915); 19 20 reset_count = i915_reset_count(&i915->gpu_error); 21 22 i915_reset(i915, ALL_ENGINES, NULL); 23 24 if (i915_reset_count(&i915->gpu_error) == reset_count) { 25 pr_err("No GPU reset recorded!\n"); 26 err = -EINVAL; 27 } 28 29 igt_global_reset_unlock(i915); 30 31 if (i915_reset_failed(i915)) 32 err = -EIO; 33 34 return err; 35 } 36 37 static int igt_wedged_reset(void *arg) 38 { 39 struct drm_i915_private *i915 = arg; 40 intel_wakeref_t wakeref; 41 42 /* Check that we can recover a wedged device with a GPU reset */ 43 44 igt_global_reset_lock(i915); 45 wakeref = intel_runtime_pm_get(&i915->runtime_pm); 46 47 i915_gem_set_wedged(i915); 48 49 GEM_BUG_ON(!i915_reset_failed(i915)); 50 i915_reset(i915, ALL_ENGINES, NULL); 51 52 intel_runtime_pm_put(&i915->runtime_pm, wakeref); 53 igt_global_reset_unlock(i915); 54 55 return i915_reset_failed(i915) ? -EIO : 0; 56 } 57 58 static int igt_atomic_reset(void *arg) 59 { 60 struct drm_i915_private *i915 = arg; 61 const typeof(*igt_atomic_phases) *p; 62 int err = 0; 63 64 /* Check that the resets are usable from atomic context */ 65 66 igt_global_reset_lock(i915); 67 mutex_lock(&i915->drm.struct_mutex); 68 69 /* Flush any requests before we get started and check basics */ 70 if (!igt_force_reset(i915)) 71 goto unlock; 72 73 for (p = igt_atomic_phases; p->name; p++) { 74 intel_engine_mask_t awake; 75 76 GEM_TRACE("intel_gpu_reset under %s\n", p->name); 77 78 awake = reset_prepare(i915); 79 p->critical_section_begin(); 80 reset_prepare(i915); 81 err = intel_gpu_reset(i915, ALL_ENGINES); 82 p->critical_section_end(); 83 reset_finish(i915, awake); 84 85 if (err) { 86 pr_err("intel_gpu_reset failed under %s\n", p->name); 87 break; 88 } 89 } 90 91 /* As we poke around the guts, do a full reset before continuing. */ 92 igt_force_reset(i915); 93 94 unlock: 95 mutex_unlock(&i915->drm.struct_mutex); 96 igt_global_reset_unlock(i915); 97 98 return err; 99 } 100 101 int intel_reset_live_selftests(struct drm_i915_private *i915) 102 { 103 static const struct i915_subtest tests[] = { 104 SUBTEST(igt_global_reset), /* attempt to recover GPU first */ 105 SUBTEST(igt_wedged_reset), 106 SUBTEST(igt_atomic_reset), 107 }; 108 intel_wakeref_t wakeref; 109 int err = 0; 110 111 if (!intel_has_gpu_reset(i915)) 112 return 0; 113 114 if (i915_terminally_wedged(i915)) 115 return -EIO; /* we're long past hope of a successful reset */ 116 117 with_intel_runtime_pm(&i915->runtime_pm, wakeref) 118 err = i915_subtests(tests, i915); 119 120 return err; 121 } 122