1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright �� 2021 Intel Corporation 4 */ 5 6 #include "selftests/intel_scheduler_helpers.h" 7 8 static struct i915_request *nop_user_request(struct intel_context *ce, 9 struct i915_request *from) 10 { 11 struct i915_request *rq; 12 int ret; 13 14 rq = intel_context_create_request(ce); 15 if (IS_ERR(rq)) 16 return rq; 17 18 if (from) { 19 ret = i915_sw_fence_await_dma_fence(&rq->submit, 20 &from->fence, 0, 21 I915_FENCE_GFP); 22 if (ret < 0) { 23 i915_request_put(rq); 24 return ERR_PTR(ret); 25 } 26 } 27 28 i915_request_get(rq); 29 i915_request_add(rq); 30 31 return rq; 32 } 33 34 static int intel_guc_scrub_ctbs(void *arg) 35 { 36 struct intel_gt *gt = arg; 37 int ret = 0; 38 int i; 39 struct i915_request *last[3] = {NULL, NULL, NULL}, *rq; 40 intel_wakeref_t wakeref; 41 struct intel_engine_cs *engine; 42 struct intel_context *ce; 43 44 wakeref = intel_runtime_pm_get(gt->uncore->rpm); 45 engine = intel_selftest_find_any_engine(gt); 46 47 /* Submit requests and inject errors forcing G2H to be dropped */ 48 for (i = 0; i < 3; ++i) { 49 ce = intel_context_create(engine); 50 if (IS_ERR(ce)) { 51 ret = PTR_ERR(ce); 52 pr_err("Failed to create context, %d: %d\n", i, ret); 53 goto err; 54 } 55 56 switch (i) { 57 case 0: 58 ce->drop_schedule_enable = true; 59 break; 60 case 1: 61 ce->drop_schedule_disable = true; 62 break; 63 case 2: 64 ce->drop_deregister = true; 65 break; 66 } 67 68 rq = nop_user_request(ce, NULL); 69 intel_context_put(ce); 70 71 if (IS_ERR(rq)) { 72 ret = PTR_ERR(rq); 73 pr_err("Failed to create request, %d: %d\n", i, ret); 74 goto err; 75 } 76 77 last[i] = rq; 78 } 79 80 for (i = 0; i < 3; ++i) { 81 ret = i915_request_wait(last[i], 0, HZ); 82 if (ret < 0) { 83 pr_err("Last request failed to complete: %d\n", ret); 84 goto err; 85 } 86 i915_request_put(last[i]); 87 last[i] = NULL; 88 } 89 90 /* Force all H2G / G2H to be submitted / processed */ 91 intel_gt_retire_requests(gt); 92 msleep(500); 93 94 /* Scrub missing G2H */ 95 intel_gt_handle_error(engine->gt, -1, 0, "selftest reset"); 96 97 /* GT will not idle if G2H are lost */ 98 ret = intel_gt_wait_for_idle(gt, HZ); 99 if (ret < 0) { 100 pr_err("GT failed to idle: %d\n", ret); 101 goto err; 102 } 103 104 err: 105 for (i = 0; i < 3; ++i) 106 if (last[i]) 107 i915_request_put(last[i]); 108 intel_runtime_pm_put(gt->uncore->rpm, wakeref); 109 110 return ret; 111 } 112 113 int intel_guc_live_selftests(struct drm_i915_private *i915) 114 { 115 static const struct i915_subtest tests[] = { 116 SUBTEST(intel_guc_scrub_ctbs), 117 }; 118 struct intel_gt *gt = &i915->gt; 119 120 if (intel_gt_is_wedged(gt)) 121 return 0; 122 123 if (!intel_uc_uses_guc_submission(>->uc)) 124 return 0; 125 126 return intel_gt_live_subtests(tests, gt); 127 } 128