1932309fbSMichal Wajdeczko // SPDX-License-Identifier: MIT 2932309fbSMichal Wajdeczko /* 3932309fbSMichal Wajdeczko * Copyright © 2018 Intel Corporation 4932309fbSMichal Wajdeczko */ 5932309fbSMichal Wajdeczko 6932309fbSMichal Wajdeczko #include "i915_selftest.h" 7932309fbSMichal Wajdeczko #include "selftests/igt_reset.h" 8f6470c9bSMichal Wajdeczko #include "selftests/igt_atomic.h" 9932309fbSMichal Wajdeczko 10932309fbSMichal Wajdeczko static int igt_global_reset(void *arg) 11932309fbSMichal Wajdeczko { 12932309fbSMichal Wajdeczko struct drm_i915_private *i915 = arg; 13932309fbSMichal Wajdeczko unsigned int reset_count; 14932309fbSMichal Wajdeczko int err = 0; 15932309fbSMichal Wajdeczko 16932309fbSMichal Wajdeczko /* Check that we can issue a global GPU reset */ 17932309fbSMichal Wajdeczko 18932309fbSMichal Wajdeczko igt_global_reset_lock(i915); 19932309fbSMichal Wajdeczko 20932309fbSMichal Wajdeczko reset_count = i915_reset_count(&i915->gpu_error); 21932309fbSMichal Wajdeczko 22932309fbSMichal Wajdeczko i915_reset(i915, ALL_ENGINES, NULL); 23932309fbSMichal Wajdeczko 24932309fbSMichal Wajdeczko if (i915_reset_count(&i915->gpu_error) == reset_count) { 25932309fbSMichal Wajdeczko pr_err("No GPU reset recorded!\n"); 26932309fbSMichal Wajdeczko err = -EINVAL; 27932309fbSMichal Wajdeczko } 28932309fbSMichal Wajdeczko 29932309fbSMichal Wajdeczko igt_global_reset_unlock(i915); 30932309fbSMichal Wajdeczko 31932309fbSMichal Wajdeczko if (i915_reset_failed(i915)) 32932309fbSMichal Wajdeczko err = -EIO; 33932309fbSMichal Wajdeczko 34932309fbSMichal Wajdeczko return err; 35932309fbSMichal Wajdeczko } 36932309fbSMichal Wajdeczko 37932309fbSMichal Wajdeczko static int igt_wedged_reset(void *arg) 38932309fbSMichal Wajdeczko { 39932309fbSMichal Wajdeczko struct drm_i915_private *i915 = arg; 40932309fbSMichal Wajdeczko intel_wakeref_t wakeref; 41932309fbSMichal Wajdeczko 42932309fbSMichal Wajdeczko /* Check that we can recover a wedged device with a GPU reset */ 43932309fbSMichal Wajdeczko 44932309fbSMichal Wajdeczko igt_global_reset_lock(i915); 45932309fbSMichal Wajdeczko wakeref = intel_runtime_pm_get(i915); 46932309fbSMichal Wajdeczko 47932309fbSMichal Wajdeczko i915_gem_set_wedged(i915); 48932309fbSMichal Wajdeczko 49932309fbSMichal Wajdeczko GEM_BUG_ON(!i915_reset_failed(i915)); 50932309fbSMichal Wajdeczko i915_reset(i915, ALL_ENGINES, NULL); 51932309fbSMichal Wajdeczko 52932309fbSMichal Wajdeczko intel_runtime_pm_put(i915, wakeref); 53932309fbSMichal Wajdeczko igt_global_reset_unlock(i915); 54932309fbSMichal Wajdeczko 55932309fbSMichal Wajdeczko return i915_reset_failed(i915) ? -EIO : 0; 56932309fbSMichal Wajdeczko } 57932309fbSMichal Wajdeczko 58f6470c9bSMichal Wajdeczko static int igt_atomic_reset(void *arg) 59f6470c9bSMichal Wajdeczko { 60f6470c9bSMichal Wajdeczko struct drm_i915_private *i915 = arg; 61f6470c9bSMichal Wajdeczko const typeof(*igt_atomic_phases) *p; 62f6470c9bSMichal Wajdeczko int err = 0; 63f6470c9bSMichal Wajdeczko 64f6470c9bSMichal Wajdeczko /* Check that the resets are usable from atomic context */ 65f6470c9bSMichal Wajdeczko 66f6470c9bSMichal Wajdeczko igt_global_reset_lock(i915); 67f6470c9bSMichal Wajdeczko mutex_lock(&i915->drm.struct_mutex); 68f6470c9bSMichal Wajdeczko 69f6470c9bSMichal Wajdeczko /* Flush any requests before we get started and check basics */ 70f6470c9bSMichal Wajdeczko if (!igt_force_reset(i915)) 71f6470c9bSMichal Wajdeczko goto unlock; 72f6470c9bSMichal Wajdeczko 73f6470c9bSMichal Wajdeczko for (p = igt_atomic_phases; p->name; p++) { 74f6470c9bSMichal Wajdeczko GEM_TRACE("intel_gpu_reset under %s\n", p->name); 75f6470c9bSMichal Wajdeczko 76f6470c9bSMichal Wajdeczko p->critical_section_begin(); 77f6470c9bSMichal Wajdeczko err = intel_gpu_reset(i915, ALL_ENGINES); 78f6470c9bSMichal Wajdeczko p->critical_section_end(); 79f6470c9bSMichal Wajdeczko 80f6470c9bSMichal Wajdeczko if (err) { 81f6470c9bSMichal Wajdeczko pr_err("intel_gpu_reset failed under %s\n", p->name); 82f6470c9bSMichal Wajdeczko break; 83f6470c9bSMichal Wajdeczko } 84f6470c9bSMichal Wajdeczko } 85f6470c9bSMichal Wajdeczko 86f6470c9bSMichal Wajdeczko /* As we poke around the guts, do a full reset before continuing. */ 87f6470c9bSMichal Wajdeczko igt_force_reset(i915); 88f6470c9bSMichal Wajdeczko 89f6470c9bSMichal Wajdeczko unlock: 90f6470c9bSMichal Wajdeczko mutex_unlock(&i915->drm.struct_mutex); 91f6470c9bSMichal Wajdeczko igt_global_reset_unlock(i915); 92f6470c9bSMichal Wajdeczko 93f6470c9bSMichal Wajdeczko return err; 94f6470c9bSMichal Wajdeczko } 95f6470c9bSMichal Wajdeczko 96932309fbSMichal Wajdeczko int intel_reset_live_selftests(struct drm_i915_private *i915) 97932309fbSMichal Wajdeczko { 98932309fbSMichal Wajdeczko static const struct i915_subtest tests[] = { 99932309fbSMichal Wajdeczko SUBTEST(igt_global_reset), /* attempt to recover GPU first */ 100932309fbSMichal Wajdeczko SUBTEST(igt_wedged_reset), 101f6470c9bSMichal Wajdeczko SUBTEST(igt_atomic_reset), 102932309fbSMichal Wajdeczko }; 103932309fbSMichal Wajdeczko intel_wakeref_t wakeref; 104932309fbSMichal Wajdeczko int err = 0; 105932309fbSMichal Wajdeczko 106932309fbSMichal Wajdeczko if (!intel_has_gpu_reset(i915)) 107932309fbSMichal Wajdeczko return 0; 108932309fbSMichal Wajdeczko 109932309fbSMichal Wajdeczko if (i915_terminally_wedged(i915)) 110932309fbSMichal Wajdeczko return -EIO; /* we're long past hope of a successful reset */ 111932309fbSMichal Wajdeczko 112932309fbSMichal Wajdeczko with_intel_runtime_pm(i915, wakeref) 113932309fbSMichal Wajdeczko err = i915_subtests(tests, i915); 114932309fbSMichal Wajdeczko 115932309fbSMichal Wajdeczko return err; 116932309fbSMichal Wajdeczko } 117