1 /* 2 * SPDX-License-Identifier: MIT 3 * 4 * Copyright © 2018 Intel Corporation 5 */ 6 7 #include "../i915_drv.h" 8 9 #include "../i915_selftest.h" 10 #include "igt_flush_test.h" 11 12 struct wedge_me { 13 struct delayed_work work; 14 struct drm_i915_private *i915; 15 const void *symbol; 16 }; 17 18 static void wedge_me(struct work_struct *work) 19 { 20 struct wedge_me *w = container_of(work, typeof(*w), work.work); 21 22 pr_err("%pS timed out, cancelling all further testing.\n", w->symbol); 23 24 GEM_TRACE("%pS timed out.\n", w->symbol); 25 GEM_TRACE_DUMP(); 26 27 i915_gem_set_wedged(w->i915); 28 } 29 30 static void __init_wedge(struct wedge_me *w, 31 struct drm_i915_private *i915, 32 long timeout, 33 const void *symbol) 34 { 35 w->i915 = i915; 36 w->symbol = symbol; 37 38 INIT_DELAYED_WORK_ONSTACK(&w->work, wedge_me); 39 schedule_delayed_work(&w->work, timeout); 40 } 41 42 static void __fini_wedge(struct wedge_me *w) 43 { 44 cancel_delayed_work_sync(&w->work); 45 destroy_delayed_work_on_stack(&w->work); 46 w->i915 = NULL; 47 } 48 49 #define wedge_on_timeout(W, DEV, TIMEOUT) \ 50 for (__init_wedge((W), (DEV), (TIMEOUT), __builtin_return_address(0)); \ 51 (W)->i915; \ 52 __fini_wedge((W))) 53 54 int igt_flush_test(struct drm_i915_private *i915, unsigned int flags) 55 { 56 struct wedge_me w; 57 58 cond_resched(); 59 60 if (flags & I915_WAIT_LOCKED && 61 i915_gem_switch_to_kernel_context(i915)) { 62 pr_err("Failed to switch back to kernel context; declaring wedged\n"); 63 i915_gem_set_wedged(i915); 64 } 65 66 wedge_on_timeout(&w, i915, HZ) 67 i915_gem_wait_for_idle(i915, flags); 68 69 return i915_terminally_wedged(&i915->gpu_error) ? -EIO : 0; 70 } 71