1 /* 2 * SPDX-License-Identifier: MIT 3 * 4 * Copyright © 2018 Intel Corporation 5 */ 6 7 #include <linux/kref.h> 8 9 #include "gem/i915_gem_pm.h" 10 #include "gt/intel_gt.h" 11 12 #include "i915_selftest.h" 13 14 #include "igt_flush_test.h" 15 #include "lib_sw_fence.h" 16 17 struct live_active { 18 struct i915_active base; 19 struct kref ref; 20 bool retired; 21 }; 22 23 static void __live_get(struct live_active *active) 24 { 25 kref_get(&active->ref); 26 } 27 28 static void __live_free(struct live_active *active) 29 { 30 i915_active_fini(&active->base); 31 kfree(active); 32 } 33 34 static void __live_release(struct kref *ref) 35 { 36 struct live_active *active = container_of(ref, typeof(*active), ref); 37 38 __live_free(active); 39 } 40 41 static void __live_put(struct live_active *active) 42 { 43 kref_put(&active->ref, __live_release); 44 } 45 46 static int __live_active(struct i915_active *base) 47 { 48 struct live_active *active = container_of(base, typeof(*active), base); 49 50 __live_get(active); 51 return 0; 52 } 53 54 static void __live_retire(struct i915_active *base) 55 { 56 struct live_active *active = container_of(base, typeof(*active), base); 57 58 active->retired = true; 59 __live_put(active); 60 } 61 62 static struct live_active *__live_alloc(struct drm_i915_private *i915) 63 { 64 struct live_active *active; 65 66 active = kzalloc(sizeof(*active), GFP_KERNEL); 67 if (!active) 68 return NULL; 69 70 kref_init(&active->ref); 71 i915_active_init(&active->base, __live_active, __live_retire); 72 73 return active; 74 } 75 76 static struct live_active * 77 __live_active_setup(struct drm_i915_private *i915) 78 { 79 struct intel_engine_cs *engine; 80 struct i915_sw_fence *submit; 81 struct live_active *active; 82 unsigned int count = 0; 83 int err = 0; 84 85 active = __live_alloc(i915); 86 if (!active) 87 return ERR_PTR(-ENOMEM); 88 89 submit = heap_fence_create(GFP_KERNEL); 90 if (!submit) { 91 kfree(active); 92 return ERR_PTR(-ENOMEM); 93 } 94 95 err = i915_active_acquire(&active->base); 96 if (err) 97 goto out; 98 99 for_each_uabi_engine(engine, i915) { 100 struct i915_request *rq; 101 102 rq = intel_engine_create_kernel_request(engine); 103 if (IS_ERR(rq)) { 104 err = PTR_ERR(rq); 105 break; 106 } 107 108 err = i915_sw_fence_await_sw_fence_gfp(&rq->submit, 109 submit, 110 GFP_KERNEL); 111 if (err >= 0) 112 err = i915_active_add_request(&active->base, rq); 113 i915_request_add(rq); 114 if (err) { 115 pr_err("Failed to track active ref!\n"); 116 break; 117 } 118 119 count++; 120 } 121 122 i915_active_release(&active->base); 123 if (READ_ONCE(active->retired) && count) { 124 pr_err("i915_active retired before submission!\n"); 125 err = -EINVAL; 126 } 127 if (atomic_read(&active->base.count) != count) { 128 pr_err("i915_active not tracking all requests, found %d, expected %d\n", 129 atomic_read(&active->base.count), count); 130 err = -EINVAL; 131 } 132 133 out: 134 i915_sw_fence_commit(submit); 135 heap_fence_put(submit); 136 if (err) { 137 __live_put(active); 138 active = ERR_PTR(err); 139 } 140 141 return active; 142 } 143 144 static int live_active_wait(void *arg) 145 { 146 struct drm_i915_private *i915 = arg; 147 struct live_active *active; 148 int err = 0; 149 150 /* Check that we get a callback when requests retire upon waiting */ 151 152 active = __live_active_setup(i915); 153 if (IS_ERR(active)) 154 return PTR_ERR(active); 155 156 i915_active_wait(&active->base); 157 if (!READ_ONCE(active->retired)) { 158 struct drm_printer p = drm_err_printer(__func__); 159 160 pr_err("i915_active not retired after waiting!\n"); 161 i915_active_print(&active->base, &p); 162 163 err = -EINVAL; 164 } 165 166 __live_put(active); 167 168 if (igt_flush_test(i915)) 169 err = -EIO; 170 171 return err; 172 } 173 174 static int live_active_retire(void *arg) 175 { 176 struct drm_i915_private *i915 = arg; 177 struct live_active *active; 178 int err = 0; 179 180 /* Check that we get a callback when requests are indirectly retired */ 181 182 active = __live_active_setup(i915); 183 if (IS_ERR(active)) 184 return PTR_ERR(active); 185 186 /* waits for & retires all requests */ 187 if (igt_flush_test(i915)) 188 err = -EIO; 189 190 if (!READ_ONCE(active->retired)) { 191 struct drm_printer p = drm_err_printer(__func__); 192 193 pr_err("i915_active not retired after flushing!\n"); 194 i915_active_print(&active->base, &p); 195 196 err = -EINVAL; 197 } 198 199 __live_put(active); 200 201 return err; 202 } 203 204 int i915_active_live_selftests(struct drm_i915_private *i915) 205 { 206 static const struct i915_subtest tests[] = { 207 SUBTEST(live_active_wait), 208 SUBTEST(live_active_retire), 209 }; 210 211 if (intel_gt_is_wedged(&i915->gt)) 212 return 0; 213 214 return i915_subtests(tests, i915); 215 } 216 217 static struct intel_engine_cs *node_to_barrier(struct active_node *it) 218 { 219 struct intel_engine_cs *engine; 220 221 if (!is_barrier(&it->base)) 222 return NULL; 223 224 engine = __barrier_to_engine(it); 225 smp_rmb(); /* serialise with add_active_barriers */ 226 if (!is_barrier(&it->base)) 227 return NULL; 228 229 return engine; 230 } 231 232 void i915_active_print(struct i915_active *ref, struct drm_printer *m) 233 { 234 drm_printf(m, "active %pS:%pS\n", ref->active, ref->retire); 235 drm_printf(m, "\tcount: %d\n", atomic_read(&ref->count)); 236 drm_printf(m, "\tpreallocated barriers? %s\n", 237 yesno(!llist_empty(&ref->preallocated_barriers))); 238 239 if (i915_active_acquire_if_busy(ref)) { 240 struct active_node *it, *n; 241 242 rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) { 243 struct intel_engine_cs *engine; 244 245 engine = node_to_barrier(it); 246 if (engine) { 247 drm_printf(m, "\tbarrier: %s\n", engine->name); 248 continue; 249 } 250 251 if (i915_active_fence_isset(&it->base)) { 252 drm_printf(m, 253 "\ttimeline: %llx\n", it->timeline); 254 continue; 255 } 256 } 257 258 i915_active_release(ref); 259 } 260 } 261 262 static void spin_unlock_wait(spinlock_t *lock) 263 { 264 spin_lock_irq(lock); 265 spin_unlock_irq(lock); 266 } 267 268 void i915_active_unlock_wait(struct i915_active *ref) 269 { 270 if (i915_active_acquire_if_busy(ref)) { 271 struct active_node *it, *n; 272 273 rcu_read_lock(); 274 rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) { 275 struct dma_fence *f; 276 277 /* Wait for all active callbacks */ 278 f = rcu_dereference(it->base.fence); 279 if (f) 280 spin_unlock_wait(f->lock); 281 } 282 rcu_read_unlock(); 283 284 i915_active_release(ref); 285 } 286 287 /* And wait for the retire callback */ 288 spin_lock_irq(&ref->tree_lock); 289 spin_unlock_irq(&ref->tree_lock); 290 291 /* ... which may have been on a thread instead */ 292 flush_work(&ref->work); 293 } 294