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 GEM_TRACE("intel_gpu_reset under %s\n", p->name); 75 76 p->critical_section_begin(); 77 reset_prepare(i915); 78 err = intel_gpu_reset(i915, ALL_ENGINES); 79 reset_finish(i915); 80 p->critical_section_end(); 81 82 if (err) { 83 pr_err("intel_gpu_reset failed under %s\n", p->name); 84 break; 85 } 86 } 87 88 /* As we poke around the guts, do a full reset before continuing. */ 89 igt_force_reset(i915); 90 91 unlock: 92 mutex_unlock(&i915->drm.struct_mutex); 93 igt_global_reset_unlock(i915); 94 95 return err; 96 } 97 98 int intel_reset_live_selftests(struct drm_i915_private *i915) 99 { 100 static const struct i915_subtest tests[] = { 101 SUBTEST(igt_global_reset), /* attempt to recover GPU first */ 102 SUBTEST(igt_wedged_reset), 103 SUBTEST(igt_atomic_reset), 104 }; 105 intel_wakeref_t wakeref; 106 int err = 0; 107 108 if (!intel_has_gpu_reset(i915)) 109 return 0; 110 111 if (i915_terminally_wedged(i915)) 112 return -EIO; /* we're long past hope of a successful reset */ 113 114 with_intel_runtime_pm(&i915->runtime_pm, wakeref) 115 err = i915_subtests(tests, i915); 116 117 return err; 118 } 119