selftest_guc_multi_lrc.c (3947B)
1// SPDX-License-Identifier: MIT 2/* 3 * Copyright �� 2019 Intel Corporation 4 */ 5 6#include "selftests/igt_spinner.h" 7#include "selftests/igt_reset.h" 8#include "selftests/intel_scheduler_helpers.h" 9#include "gt/intel_engine_heartbeat.h" 10#include "gem/selftests/mock_context.h" 11 12static void logical_sort(struct intel_engine_cs **engines, int num_engines) 13{ 14 struct intel_engine_cs *sorted[MAX_ENGINE_INSTANCE + 1]; 15 int i, j; 16 17 for (i = 0; i < num_engines; ++i) 18 for (j = 0; j < MAX_ENGINE_INSTANCE + 1; ++j) { 19 if (engines[j]->logical_mask & BIT(i)) { 20 sorted[i] = engines[j]; 21 break; 22 } 23 } 24 25 memcpy(*engines, *sorted, 26 sizeof(struct intel_engine_cs *) * num_engines); 27} 28 29static struct intel_context * 30multi_lrc_create_parent(struct intel_gt *gt, u8 class, 31 unsigned long flags) 32{ 33 struct intel_engine_cs *siblings[MAX_ENGINE_INSTANCE + 1]; 34 struct intel_engine_cs *engine; 35 enum intel_engine_id id; 36 int i = 0; 37 38 for_each_engine(engine, gt, id) { 39 if (engine->class != class) 40 continue; 41 42 siblings[i++] = engine; 43 } 44 45 if (i <= 1) 46 return ERR_PTR(0); 47 48 logical_sort(siblings, i); 49 50 return intel_engine_create_parallel(siblings, 1, i); 51} 52 53static void multi_lrc_context_unpin(struct intel_context *ce) 54{ 55 struct intel_context *child; 56 57 GEM_BUG_ON(!intel_context_is_parent(ce)); 58 59 for_each_child(ce, child) 60 intel_context_unpin(child); 61 intel_context_unpin(ce); 62} 63 64static void multi_lrc_context_put(struct intel_context *ce) 65{ 66 GEM_BUG_ON(!intel_context_is_parent(ce)); 67 68 /* 69 * Only the parent gets the creation ref put in the uAPI, the parent 70 * itself is responsible for creation ref put on the children. 71 */ 72 intel_context_put(ce); 73} 74 75static struct i915_request * 76multi_lrc_nop_request(struct intel_context *ce) 77{ 78 struct intel_context *child; 79 struct i915_request *rq, *child_rq; 80 int i = 0; 81 82 GEM_BUG_ON(!intel_context_is_parent(ce)); 83 84 rq = intel_context_create_request(ce); 85 if (IS_ERR(rq)) 86 return rq; 87 88 i915_request_get(rq); 89 i915_request_add(rq); 90 91 for_each_child(ce, child) { 92 child_rq = intel_context_create_request(child); 93 if (IS_ERR(child_rq)) 94 goto child_error; 95 96 if (++i == ce->parallel.number_children) 97 set_bit(I915_FENCE_FLAG_SUBMIT_PARALLEL, 98 &child_rq->fence.flags); 99 i915_request_add(child_rq); 100 } 101 102 return rq; 103 104child_error: 105 i915_request_put(rq); 106 107 return ERR_PTR(-ENOMEM); 108} 109 110static int __intel_guc_multi_lrc_basic(struct intel_gt *gt, unsigned int class) 111{ 112 struct intel_context *parent; 113 struct i915_request *rq; 114 int ret; 115 116 parent = multi_lrc_create_parent(gt, class, 0); 117 if (IS_ERR(parent)) { 118 pr_err("Failed creating contexts: %ld", PTR_ERR(parent)); 119 return PTR_ERR(parent); 120 } else if (!parent) { 121 pr_debug("Not enough engines in class: %d", class); 122 return 0; 123 } 124 125 rq = multi_lrc_nop_request(parent); 126 if (IS_ERR(rq)) { 127 ret = PTR_ERR(rq); 128 pr_err("Failed creating requests: %d", ret); 129 goto out; 130 } 131 132 ret = intel_selftest_wait_for_rq(rq); 133 if (ret) 134 pr_err("Failed waiting on request: %d", ret); 135 136 i915_request_put(rq); 137 138 if (ret >= 0) { 139 ret = intel_gt_wait_for_idle(gt, HZ * 5); 140 if (ret < 0) 141 pr_err("GT failed to idle: %d\n", ret); 142 } 143 144out: 145 multi_lrc_context_unpin(parent); 146 multi_lrc_context_put(parent); 147 return ret; 148} 149 150static int intel_guc_multi_lrc_basic(void *arg) 151{ 152 struct intel_gt *gt = arg; 153 unsigned int class; 154 int ret; 155 156 for (class = 0; class < MAX_ENGINE_CLASS + 1; ++class) { 157 /* We don't support breadcrumb handshake on these classes */ 158 if (class == COMPUTE_CLASS || class == RENDER_CLASS) 159 continue; 160 161 ret = __intel_guc_multi_lrc_basic(gt, class); 162 if (ret) 163 return ret; 164 } 165 166 return 0; 167} 168 169int intel_guc_multi_lrc_live_selftests(struct drm_i915_private *i915) 170{ 171 static const struct i915_subtest tests[] = { 172 SUBTEST(intel_guc_multi_lrc_basic), 173 }; 174 struct intel_gt *gt = to_gt(i915); 175 176 if (intel_gt_is_wedged(gt)) 177 return 0; 178 179 if (!intel_uc_uses_guc_submission(>->uc)) 180 return 0; 181 182 return intel_gt_live_subtests(tests, gt); 183}