blob: ba73dc5b03283d4140d4d7d8143709fe24abcd10 [file] [log] [blame]
Chris Wilson688e6c72016-07-01 17:23:15 +01001/*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
Chris Wilsonc81d4612016-07-01 17:23:25 +010025#include <linux/kthread.h>
26
Chris Wilson688e6c72016-07-01 17:23:15 +010027#include "i915_drv.h"
28
Chris Wilson67b807a82017-02-27 20:58:50 +000029static unsigned int __intel_breadcrumbs_wakeup(struct intel_breadcrumbs *b)
Chris Wilson8d769ea2017-02-27 20:58:47 +000030{
Chris Wilson56299fb2017-02-27 20:58:48 +000031 struct intel_wait *wait;
Chris Wilson8d769ea2017-02-27 20:58:47 +000032 unsigned int result = 0;
33
Chris Wilson61d3dc72017-03-03 19:08:24 +000034 lockdep_assert_held(&b->irq_lock);
35
36 wait = b->irq_wait;
Chris Wilson56299fb2017-02-27 20:58:48 +000037 if (wait) {
Chris Wilson8d769ea2017-02-27 20:58:47 +000038 result = ENGINE_WAKEUP_WAITER;
Chris Wilson67b807a82017-02-27 20:58:50 +000039 if (wake_up_process(wait->tsk))
40 result |= ENGINE_WAKEUP_ASLEEP;
Chris Wilson8d769ea2017-02-27 20:58:47 +000041 }
Chris Wilson67b807a82017-02-27 20:58:50 +000042
43 return result;
44}
45
46unsigned int intel_engine_wakeup(struct intel_engine_cs *engine)
47{
48 struct intel_breadcrumbs *b = &engine->breadcrumbs;
49 unsigned long flags;
50 unsigned int result;
51
Chris Wilson61d3dc72017-03-03 19:08:24 +000052 spin_lock_irqsave(&b->irq_lock, flags);
Chris Wilson67b807a82017-02-27 20:58:50 +000053 result = __intel_breadcrumbs_wakeup(b);
Chris Wilson61d3dc72017-03-03 19:08:24 +000054 spin_unlock_irqrestore(&b->irq_lock, flags);
Chris Wilson8d769ea2017-02-27 20:58:47 +000055
56 return result;
57}
58
Chris Wilson2246bea2017-02-17 15:13:00 +000059static unsigned long wait_timeout(void)
60{
61 return round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES);
62}
63
Chris Wilson80166e402017-02-28 08:50:18 +000064static noinline void missed_breadcrumb(struct intel_engine_cs *engine)
65{
66 DRM_DEBUG_DRIVER("%s missed breadcrumb at %pF, irq posted? %s\n",
67 engine->name, __builtin_return_address(0),
68 yesno(test_bit(ENGINE_IRQ_BREADCRUMB,
69 &engine->irq_posted)));
70
71 set_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings);
72}
73
Chris Wilson83348ba2016-08-09 17:47:51 +010074static void intel_breadcrumbs_hangcheck(unsigned long data)
75{
76 struct intel_engine_cs *engine = (struct intel_engine_cs *)data;
77 struct intel_breadcrumbs *b = &engine->breadcrumbs;
78
Chris Wilson67b807a82017-02-27 20:58:50 +000079 if (!b->irq_armed)
Chris Wilson83348ba2016-08-09 17:47:51 +010080 return;
81
Chris Wilson2246bea2017-02-17 15:13:00 +000082 if (b->hangcheck_interrupts != atomic_read(&engine->irq_count)) {
83 b->hangcheck_interrupts = atomic_read(&engine->irq_count);
84 mod_timer(&b->hangcheck, wait_timeout());
Chris Wilson83348ba2016-08-09 17:47:51 +010085 return;
86 }
87
Chris Wilson67b807a82017-02-27 20:58:50 +000088 /* We keep the hangcheck time alive until we disarm the irq, even
89 * if there are no waiters at present.
90 *
91 * If the waiter was currently running, assume it hasn't had a chance
Chris Wilson89985672017-02-17 15:13:02 +000092 * to process the pending interrupt (e.g, low priority task on a loaded
93 * system) and wait until it sleeps before declaring a missed interrupt.
Chris Wilson67b807a82017-02-27 20:58:50 +000094 *
95 * If the waiter was asleep (and not even pending a wakeup), then we
96 * must have missed an interrupt as the GPU has stopped advancing
97 * but we still have a waiter. Assuming all batches complete within
98 * DRM_I915_HANGCHECK_JIFFIES [1.5s]!
Chris Wilson89985672017-02-17 15:13:02 +000099 */
Chris Wilson67b807a82017-02-27 20:58:50 +0000100 if (intel_engine_wakeup(engine) & ENGINE_WAKEUP_ASLEEP) {
Chris Wilson80166e402017-02-28 08:50:18 +0000101 missed_breadcrumb(engine);
Chris Wilson67b807a82017-02-27 20:58:50 +0000102 mod_timer(&engine->breadcrumbs.fake_irq, jiffies + 1);
103 } else {
Chris Wilson89985672017-02-17 15:13:02 +0000104 mod_timer(&b->hangcheck, wait_timeout());
Chris Wilson89985672017-02-17 15:13:02 +0000105 }
Chris Wilson83348ba2016-08-09 17:47:51 +0100106}
107
Chris Wilson688e6c72016-07-01 17:23:15 +0100108static void intel_breadcrumbs_fake_irq(unsigned long data)
109{
110 struct intel_engine_cs *engine = (struct intel_engine_cs *)data;
Chris Wilson67b807a82017-02-27 20:58:50 +0000111 struct intel_breadcrumbs *b = &engine->breadcrumbs;
112 unsigned long flags;
Chris Wilson688e6c72016-07-01 17:23:15 +0100113
114 /*
115 * The timer persists in case we cannot enable interrupts,
116 * or if we have previously seen seqno/interrupt incoherency
117 * ("missed interrupt" syndrome). Here the worker will wake up
118 * every jiffie in order to kick the oldest waiter to do the
119 * coherent seqno check.
120 */
Chris Wilson67b807a82017-02-27 20:58:50 +0000121
Chris Wilson61d3dc72017-03-03 19:08:24 +0000122 spin_lock_irqsave(&b->irq_lock, flags);
Chris Wilson67b807a82017-02-27 20:58:50 +0000123 if (!__intel_breadcrumbs_wakeup(b))
124 __intel_engine_disarm_breadcrumbs(engine);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000125 spin_unlock_irqrestore(&b->irq_lock, flags);
Chris Wilson67b807a82017-02-27 20:58:50 +0000126 if (!b->irq_armed)
Chris Wilson19d0a572017-02-27 20:58:49 +0000127 return;
128
Chris Wilson67b807a82017-02-27 20:58:50 +0000129 mod_timer(&b->fake_irq, jiffies + 1);
Chris Wilson19d0a572017-02-27 20:58:49 +0000130
131 /* Ensure that even if the GPU hangs, we get woken up.
132 *
133 * However, note that if no one is waiting, we never notice
134 * a gpu hang. Eventually, we will have to wait for a resource
135 * held by the GPU and so trigger a hangcheck. In the most
136 * pathological case, this will be upon memory starvation! To
137 * prevent this, we also queue the hangcheck from the retire
138 * worker.
139 */
140 i915_queue_hangcheck(engine->i915);
Chris Wilson688e6c72016-07-01 17:23:15 +0100141}
142
143static void irq_enable(struct intel_engine_cs *engine)
144{
Chris Wilson3d5564e2016-07-01 17:23:23 +0100145 /* Enabling the IRQ may miss the generation of the interrupt, but
146 * we still need to force the barrier before reading the seqno,
147 * just in case.
148 */
Chris Wilson538b2572017-01-24 15:18:05 +0000149 set_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted);
Chris Wilson31bb59c2016-07-01 17:23:27 +0100150
Chris Wilsonf6168e32016-10-28 13:58:55 +0100151 /* Caller disables interrupts */
152 spin_lock(&engine->i915->irq_lock);
Chris Wilson31bb59c2016-07-01 17:23:27 +0100153 engine->irq_enable(engine);
Chris Wilsonf6168e32016-10-28 13:58:55 +0100154 spin_unlock(&engine->i915->irq_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100155}
156
157static void irq_disable(struct intel_engine_cs *engine)
158{
Chris Wilsonf6168e32016-10-28 13:58:55 +0100159 /* Caller disables interrupts */
160 spin_lock(&engine->i915->irq_lock);
Chris Wilson31bb59c2016-07-01 17:23:27 +0100161 engine->irq_disable(engine);
Chris Wilsonf6168e32016-10-28 13:58:55 +0100162 spin_unlock(&engine->i915->irq_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100163}
164
Chris Wilson67b807a82017-02-27 20:58:50 +0000165void __intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine)
166{
167 struct intel_breadcrumbs *b = &engine->breadcrumbs;
168
Chris Wilson61d3dc72017-03-03 19:08:24 +0000169 lockdep_assert_held(&b->irq_lock);
Chris Wilsone1c0c912017-03-06 09:29:15 +0000170 GEM_BUG_ON(b->irq_wait);
Chris Wilson67b807a82017-02-27 20:58:50 +0000171
172 if (b->irq_enabled) {
173 irq_disable(engine);
174 b->irq_enabled = false;
175 }
176
177 b->irq_armed = false;
178}
179
180void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine)
181{
182 struct intel_breadcrumbs *b = &engine->breadcrumbs;
Chris Wilsone1c0c912017-03-06 09:29:15 +0000183 struct intel_wait *wait, *n;
Chris Wilson67b807a82017-02-27 20:58:50 +0000184
185 if (!b->irq_armed)
186 return;
187
Chris Wilson67b807a82017-02-27 20:58:50 +0000188 /* We only disarm the irq when we are idle (all requests completed),
Chris Wilsone1c0c912017-03-06 09:29:15 +0000189 * so if the bottom-half remains asleep, it missed the request
Chris Wilson67b807a82017-02-27 20:58:50 +0000190 * completion.
191 */
Chris Wilson67b807a82017-02-27 20:58:50 +0000192
Chris Wilsone1c0c912017-03-06 09:29:15 +0000193 spin_lock_irq(&b->rb_lock);
194 rbtree_postorder_for_each_entry_safe(wait, n, &b->waiters, node) {
195 RB_CLEAR_NODE(&wait->node);
196 if (wake_up_process(wait->tsk) && wait == b->irq_wait)
197 missed_breadcrumb(engine);
198 }
199 b->waiters = RB_ROOT;
200
201 spin_lock(&b->irq_lock);
202 b->irq_wait = NULL;
Chris Wilson67b807a82017-02-27 20:58:50 +0000203 __intel_engine_disarm_breadcrumbs(engine);
Chris Wilsone1c0c912017-03-06 09:29:15 +0000204 spin_unlock(&b->irq_lock);
Chris Wilson67b807a82017-02-27 20:58:50 +0000205
Chris Wilsone1c0c912017-03-06 09:29:15 +0000206 spin_unlock_irq(&b->rb_lock);
Chris Wilson67b807a82017-02-27 20:58:50 +0000207}
208
Chris Wilson6ef98ea2017-02-17 15:13:03 +0000209static bool use_fake_irq(const struct intel_breadcrumbs *b)
210{
211 const struct intel_engine_cs *engine =
212 container_of(b, struct intel_engine_cs, breadcrumbs);
213
214 if (!test_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings))
215 return false;
216
217 /* Only start with the heavy weight fake irq timer if we have not
218 * seen any interrupts since enabling it the first time. If the
219 * interrupts are still arriving, it means we made a mistake in our
220 * engine->seqno_barrier(), a timing error that should be transient
221 * and unlikely to reoccur.
222 */
223 return atomic_read(&engine->irq_count) == b->hangcheck_interrupts;
224}
225
Chris Wilson67b807a82017-02-27 20:58:50 +0000226static void enable_fake_irq(struct intel_breadcrumbs *b)
227{
228 /* Ensure we never sleep indefinitely */
229 if (!b->irq_enabled || use_fake_irq(b))
230 mod_timer(&b->fake_irq, jiffies + 1);
231 else
232 mod_timer(&b->hangcheck, wait_timeout());
233}
234
Chris Wilson04171312016-07-06 12:39:00 +0100235static void __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b)
Chris Wilson688e6c72016-07-01 17:23:15 +0100236{
237 struct intel_engine_cs *engine =
238 container_of(b, struct intel_engine_cs, breadcrumbs);
239 struct drm_i915_private *i915 = engine->i915;
Chris Wilson688e6c72016-07-01 17:23:15 +0100240
Chris Wilson61d3dc72017-03-03 19:08:24 +0000241 lockdep_assert_held(&b->irq_lock);
Chris Wilson67b807a82017-02-27 20:58:50 +0000242 if (b->irq_armed)
Chris Wilson04171312016-07-06 12:39:00 +0100243 return;
Chris Wilson688e6c72016-07-01 17:23:15 +0100244
Chris Wilson67b807a82017-02-27 20:58:50 +0000245 /* The breadcrumb irq will be disarmed on the interrupt after the
246 * waiters are signaled. This gives us a single interrupt window in
247 * which we can add a new waiter and avoid the cost of re-enabling
248 * the irq.
249 */
250 b->irq_armed = true;
251 GEM_BUG_ON(b->irq_enabled);
252
Chris Wilsonf97fbf92017-02-13 17:15:14 +0000253 if (I915_SELFTEST_ONLY(b->mock)) {
254 /* For our mock objects we want to avoid interaction
255 * with the real hardware (which is not set up). So
256 * we simply pretend we have enabled the powerwell
257 * and the irq, and leave it up to the mock
258 * implementation to call intel_engine_wakeup()
259 * itself when it wants to simulate a user interrupt,
260 */
Chris Wilsonf97fbf92017-02-13 17:15:14 +0000261 return;
262 }
263
Chris Wilson688e6c72016-07-01 17:23:15 +0100264 /* Since we are waiting on a request, the GPU should be busy
Chris Wilson67b807a82017-02-27 20:58:50 +0000265 * and should have its own rpm reference. This is tracked
266 * by i915->gt.awake, we can forgo holding our own wakref
267 * for the interrupt as before i915->gt.awake is released (when
268 * the driver is idle) we disarm the breadcrumbs.
Chris Wilson688e6c72016-07-01 17:23:15 +0100269 */
Chris Wilson688e6c72016-07-01 17:23:15 +0100270
271 /* No interrupts? Kick the waiter every jiffie! */
272 if (intel_irqs_enabled(i915)) {
Chris Wilson3d5564e2016-07-01 17:23:23 +0100273 if (!test_bit(engine->id, &i915->gpu_error.test_irq_rings))
Chris Wilson688e6c72016-07-01 17:23:15 +0100274 irq_enable(engine);
Chris Wilson688e6c72016-07-01 17:23:15 +0100275 b->irq_enabled = true;
276 }
277
Chris Wilson67b807a82017-02-27 20:58:50 +0000278 enable_fake_irq(b);
Chris Wilson688e6c72016-07-01 17:23:15 +0100279}
280
281static inline struct intel_wait *to_wait(struct rb_node *node)
282{
Chris Wilsond8567862016-12-20 10:40:03 +0000283 return rb_entry(node, struct intel_wait, node);
Chris Wilson688e6c72016-07-01 17:23:15 +0100284}
285
286static inline void __intel_breadcrumbs_finish(struct intel_breadcrumbs *b,
287 struct intel_wait *wait)
288{
Chris Wilson61d3dc72017-03-03 19:08:24 +0000289 lockdep_assert_held(&b->rb_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100290
291 /* This request is completed, so remove it from the tree, mark it as
292 * complete, and *then* wake up the associated task.
293 */
294 rb_erase(&wait->node, &b->waiters);
295 RB_CLEAR_NODE(&wait->node);
296
297 wake_up_process(wait->tsk); /* implicit smp_wmb() */
298}
299
Chris Wilsonb66255f2017-03-03 17:14:22 +0000300static inline void __intel_breadcrumbs_next(struct intel_engine_cs *engine,
301 struct rb_node *next)
302{
303 struct intel_breadcrumbs *b = &engine->breadcrumbs;
304
Chris Wilson61d3dc72017-03-03 19:08:24 +0000305 spin_lock(&b->irq_lock);
Chris Wilsonb66255f2017-03-03 17:14:22 +0000306 GEM_BUG_ON(!b->irq_armed);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000307 b->irq_wait = to_wait(next);
308 spin_unlock(&b->irq_lock);
Chris Wilsonb66255f2017-03-03 17:14:22 +0000309
310 /* We always wake up the next waiter that takes over as the bottom-half
311 * as we may delegate not only the irq-seqno barrier to the next waiter
312 * but also the task of waking up concurrent waiters.
313 */
314 if (next)
315 wake_up_process(to_wait(next)->tsk);
316}
317
Chris Wilson688e6c72016-07-01 17:23:15 +0100318static bool __intel_engine_add_wait(struct intel_engine_cs *engine,
319 struct intel_wait *wait)
320{
321 struct intel_breadcrumbs *b = &engine->breadcrumbs;
322 struct rb_node **p, *parent, *completed;
323 bool first;
324 u32 seqno;
325
326 /* Insert the request into the retirement ordered list
327 * of waiters by walking the rbtree. If we are the oldest
328 * seqno in the tree (the first to be retired), then
329 * set ourselves as the bottom-half.
330 *
331 * As we descend the tree, prune completed branches since we hold the
332 * spinlock we know that the first_waiter must be delayed and can
333 * reduce some of the sequential wake up latency if we take action
334 * ourselves and wake up the completed tasks in parallel. Also, by
335 * removing stale elements in the tree, we may be able to reduce the
336 * ping-pong between the old bottom-half and ourselves as first-waiter.
337 */
338 first = true;
339 parent = NULL;
340 completed = NULL;
Chris Wilson1b7744e2016-07-01 17:23:17 +0100341 seqno = intel_engine_get_seqno(engine);
Chris Wilson688e6c72016-07-01 17:23:15 +0100342
343 /* If the request completed before we managed to grab the spinlock,
344 * return now before adding ourselves to the rbtree. We let the
345 * current bottom-half handle any pending wakeups and instead
346 * try and get out of the way quickly.
347 */
348 if (i915_seqno_passed(seqno, wait->seqno)) {
349 RB_CLEAR_NODE(&wait->node);
350 return first;
351 }
352
353 p = &b->waiters.rb_node;
354 while (*p) {
355 parent = *p;
356 if (wait->seqno == to_wait(parent)->seqno) {
357 /* We have multiple waiters on the same seqno, select
358 * the highest priority task (that with the smallest
359 * task->prio) to serve as the bottom-half for this
360 * group.
361 */
362 if (wait->tsk->prio > to_wait(parent)->tsk->prio) {
363 p = &parent->rb_right;
364 first = false;
365 } else {
366 p = &parent->rb_left;
367 }
368 } else if (i915_seqno_passed(wait->seqno,
369 to_wait(parent)->seqno)) {
370 p = &parent->rb_right;
371 if (i915_seqno_passed(seqno, to_wait(parent)->seqno))
372 completed = parent;
373 else
374 first = false;
375 } else {
376 p = &parent->rb_left;
377 }
378 }
379 rb_link_node(&wait->node, parent, p);
380 rb_insert_color(&wait->node, &b->waiters);
Chris Wilson688e6c72016-07-01 17:23:15 +0100381
382 if (completed) {
383 struct rb_node *next = rb_next(completed);
384
385 GEM_BUG_ON(!next && !first);
386 if (next && next != &wait->node) {
387 GEM_BUG_ON(first);
Chris Wilsonb66255f2017-03-03 17:14:22 +0000388 __intel_breadcrumbs_next(engine, next);
Chris Wilson688e6c72016-07-01 17:23:15 +0100389 }
390
391 do {
392 struct intel_wait *crumb = to_wait(completed);
393 completed = rb_prev(completed);
394 __intel_breadcrumbs_finish(b, crumb);
395 } while (completed);
396 }
397
398 if (first) {
Chris Wilson61d3dc72017-03-03 19:08:24 +0000399 spin_lock(&b->irq_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100400 GEM_BUG_ON(rb_first(&b->waiters) != &wait->node);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000401 b->irq_wait = wait;
Chris Wilson04171312016-07-06 12:39:00 +0100402 /* After assigning ourselves as the new bottom-half, we must
403 * perform a cursory check to prevent a missed interrupt.
404 * Either we miss the interrupt whilst programming the hardware,
405 * or if there was a previous waiter (for a later seqno) they
406 * may be woken instead of us (due to the inherent race
Chris Wilsonaca34b62016-07-06 12:39:02 +0100407 * in the unlocked read of b->irq_seqno_bh in the irq handler)
408 * and so we miss the wake up.
Chris Wilson04171312016-07-06 12:39:00 +0100409 */
410 __intel_breadcrumbs_enable_irq(b);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000411 spin_unlock(&b->irq_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100412 }
Chris Wilson61d3dc72017-03-03 19:08:24 +0000413 GEM_BUG_ON(!b->irq_wait);
414 GEM_BUG_ON(rb_first(&b->waiters) != &b->irq_wait->node);
Chris Wilson688e6c72016-07-01 17:23:15 +0100415
416 return first;
417}
418
419bool intel_engine_add_wait(struct intel_engine_cs *engine,
420 struct intel_wait *wait)
421{
422 struct intel_breadcrumbs *b = &engine->breadcrumbs;
423 bool first;
424
Chris Wilson61d3dc72017-03-03 19:08:24 +0000425 spin_lock_irq(&b->rb_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100426 first = __intel_engine_add_wait(engine, wait);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000427 spin_unlock_irq(&b->rb_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100428
429 return first;
430}
431
Chris Wilson688e6c72016-07-01 17:23:15 +0100432static inline bool chain_wakeup(struct rb_node *rb, int priority)
433{
434 return rb && to_wait(rb)->tsk->prio <= priority;
435}
436
Chris Wilsonc81d4612016-07-01 17:23:25 +0100437static inline int wakeup_priority(struct intel_breadcrumbs *b,
438 struct task_struct *tsk)
439{
440 if (tsk == b->signaler)
441 return INT_MIN;
442 else
443 return tsk->prio;
444}
445
Chris Wilson9eb143b2017-02-23 07:44:16 +0000446static void __intel_engine_remove_wait(struct intel_engine_cs *engine,
447 struct intel_wait *wait)
Chris Wilson688e6c72016-07-01 17:23:15 +0100448{
449 struct intel_breadcrumbs *b = &engine->breadcrumbs;
450
Chris Wilson61d3dc72017-03-03 19:08:24 +0000451 lockdep_assert_held(&b->rb_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100452
453 if (RB_EMPTY_NODE(&wait->node))
Chris Wilson9eb143b2017-02-23 07:44:16 +0000454 goto out;
Chris Wilson688e6c72016-07-01 17:23:15 +0100455
Chris Wilson61d3dc72017-03-03 19:08:24 +0000456 if (b->irq_wait == wait) {
Chris Wilsonc81d4612016-07-01 17:23:25 +0100457 const int priority = wakeup_priority(b, wait->tsk);
Chris Wilson688e6c72016-07-01 17:23:15 +0100458 struct rb_node *next;
Chris Wilson688e6c72016-07-01 17:23:15 +0100459
Chris Wilson688e6c72016-07-01 17:23:15 +0100460 /* We are the current bottom-half. Find the next candidate,
461 * the first waiter in the queue on the remaining oldest
462 * request. As multiple seqnos may complete in the time it
463 * takes us to wake up and find the next waiter, we have to
464 * wake up that waiter for it to perform its own coherent
465 * completion check.
466 */
467 next = rb_next(&wait->node);
468 if (chain_wakeup(next, priority)) {
469 /* If the next waiter is already complete,
470 * wake it up and continue onto the next waiter. So
471 * if have a small herd, they will wake up in parallel
472 * rather than sequentially, which should reduce
473 * the overall latency in waking all the completed
474 * clients.
475 *
476 * However, waking up a chain adds extra latency to
477 * the first_waiter. This is undesirable if that
478 * waiter is a high priority task.
479 */
Chris Wilson1b7744e2016-07-01 17:23:17 +0100480 u32 seqno = intel_engine_get_seqno(engine);
Chris Wilson688e6c72016-07-01 17:23:15 +0100481
482 while (i915_seqno_passed(seqno, to_wait(next)->seqno)) {
483 struct rb_node *n = rb_next(next);
484
485 __intel_breadcrumbs_finish(b, to_wait(next));
486 next = n;
487 if (!chain_wakeup(next, priority))
488 break;
489 }
490 }
491
Chris Wilsonb66255f2017-03-03 17:14:22 +0000492 __intel_breadcrumbs_next(engine, next);
Chris Wilson688e6c72016-07-01 17:23:15 +0100493 } else {
494 GEM_BUG_ON(rb_first(&b->waiters) == &wait->node);
495 }
496
497 GEM_BUG_ON(RB_EMPTY_NODE(&wait->node));
498 rb_erase(&wait->node, &b->waiters);
499
Chris Wilson9eb143b2017-02-23 07:44:16 +0000500out:
Chris Wilson61d3dc72017-03-03 19:08:24 +0000501 GEM_BUG_ON(b->irq_wait == wait);
Chris Wilson688e6c72016-07-01 17:23:15 +0100502 GEM_BUG_ON(rb_first(&b->waiters) !=
Chris Wilson61d3dc72017-03-03 19:08:24 +0000503 (b->irq_wait ? &b->irq_wait->node : NULL));
Chris Wilson9eb143b2017-02-23 07:44:16 +0000504}
505
506void intel_engine_remove_wait(struct intel_engine_cs *engine,
507 struct intel_wait *wait)
508{
509 struct intel_breadcrumbs *b = &engine->breadcrumbs;
510
511 /* Quick check to see if this waiter was already decoupled from
512 * the tree by the bottom-half to avoid contention on the spinlock
513 * by the herd.
514 */
515 if (RB_EMPTY_NODE(&wait->node))
516 return;
517
Chris Wilson61d3dc72017-03-03 19:08:24 +0000518 spin_lock_irq(&b->rb_lock);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000519 __intel_engine_remove_wait(engine, wait);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000520 spin_unlock_irq(&b->rb_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100521}
522
Chris Wilsond6a22892017-02-23 07:44:17 +0000523static bool signal_valid(const struct drm_i915_gem_request *request)
524{
525 return intel_wait_check_request(&request->signaling.wait, request);
526}
527
528static bool signal_complete(const struct drm_i915_gem_request *request)
Chris Wilsonc81d4612016-07-01 17:23:25 +0100529{
Chris Wilsonb3850852016-07-01 17:23:26 +0100530 if (!request)
Chris Wilsonc81d4612016-07-01 17:23:25 +0100531 return false;
532
533 /* If another process served as the bottom-half it may have already
534 * signalled that this wait is already completed.
535 */
Chris Wilsonb3850852016-07-01 17:23:26 +0100536 if (intel_wait_complete(&request->signaling.wait))
Chris Wilsond6a22892017-02-23 07:44:17 +0000537 return signal_valid(request);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100538
539 /* Carefully check if the request is complete, giving time for the
540 * seqno to be visible or if the GPU hung.
541 */
Chris Wilsonb3850852016-07-01 17:23:26 +0100542 if (__i915_request_irq_complete(request))
Chris Wilsonc81d4612016-07-01 17:23:25 +0100543 return true;
544
545 return false;
546}
547
Chris Wilsonb3850852016-07-01 17:23:26 +0100548static struct drm_i915_gem_request *to_signaler(struct rb_node *rb)
Chris Wilsonc81d4612016-07-01 17:23:25 +0100549{
Chris Wilsond8567862016-12-20 10:40:03 +0000550 return rb_entry(rb, struct drm_i915_gem_request, signaling.node);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100551}
552
553static void signaler_set_rtpriority(void)
554{
555 struct sched_param param = { .sched_priority = 1 };
556
557 sched_setscheduler_nocheck(current, SCHED_FIFO, &param);
558}
559
560static int intel_breadcrumbs_signaler(void *arg)
561{
562 struct intel_engine_cs *engine = arg;
563 struct intel_breadcrumbs *b = &engine->breadcrumbs;
Chris Wilsonb3850852016-07-01 17:23:26 +0100564 struct drm_i915_gem_request *request;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100565
566 /* Install ourselves with high priority to reduce signalling latency */
567 signaler_set_rtpriority();
568
569 do {
570 set_current_state(TASK_INTERRUPTIBLE);
571
572 /* We are either woken up by the interrupt bottom-half,
573 * or by a client adding a new signaller. In both cases,
574 * the GPU seqno may have advanced beyond our oldest signal.
575 * If it has, propagate the signal, remove the waiter and
576 * check again with the next oldest signal. Otherwise we
577 * need to wait for a new interrupt from the GPU or for
578 * a new client.
579 */
Chris Wilsoncced5e22017-02-23 07:44:15 +0000580 rcu_read_lock();
581 request = rcu_dereference(b->first_signal);
582 if (request)
583 request = i915_gem_request_get_rcu(request);
584 rcu_read_unlock();
Chris Wilsonb3850852016-07-01 17:23:26 +0100585 if (signal_complete(request)) {
Chris Wilson7c9e9342017-01-24 11:00:09 +0000586 local_bh_disable();
587 dma_fence_signal(&request->fence);
588 local_bh_enable(); /* kick start the tasklets */
589
Chris Wilson61d3dc72017-03-03 19:08:24 +0000590 spin_lock_irq(&b->rb_lock);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000591
Chris Wilsonc81d4612016-07-01 17:23:25 +0100592 /* Wake up all other completed waiters and select the
593 * next bottom-half for the next user interrupt.
594 */
Chris Wilson9eb143b2017-02-23 07:44:16 +0000595 __intel_engine_remove_wait(engine,
596 &request->signaling.wait);
Chris Wilson5590af32016-09-09 14:11:54 +0100597
Chris Wilsonc81d4612016-07-01 17:23:25 +0100598 /* Find the next oldest signal. Note that as we have
599 * not been holding the lock, another client may
600 * have installed an even older signal than the one
601 * we just completed - so double check we are still
602 * the oldest before picking the next one.
603 */
Chris Wilsoncced5e22017-02-23 07:44:15 +0000604 if (request == rcu_access_pointer(b->first_signal)) {
Chris Wilsonb3850852016-07-01 17:23:26 +0100605 struct rb_node *rb =
606 rb_next(&request->signaling.node);
Chris Wilsoncced5e22017-02-23 07:44:15 +0000607 rcu_assign_pointer(b->first_signal,
608 rb ? to_signaler(rb) : NULL);
Chris Wilsonb3850852016-07-01 17:23:26 +0100609 }
610 rb_erase(&request->signaling.node, &b->signals);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000611 RB_CLEAR_NODE(&request->signaling.node);
612
Chris Wilson61d3dc72017-03-03 19:08:24 +0000613 spin_unlock_irq(&b->rb_lock);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100614
Chris Wilsone8a261e2016-07-20 13:31:49 +0100615 i915_gem_request_put(request);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100616 } else {
Chris Wilsond6a22892017-02-23 07:44:17 +0000617 DEFINE_WAIT(exec);
618
Chris Wilsoncced5e22017-02-23 07:44:15 +0000619 if (kthread_should_stop()) {
620 GEM_BUG_ON(request);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100621 break;
Chris Wilsoncced5e22017-02-23 07:44:15 +0000622 }
Chris Wilsonc81d4612016-07-01 17:23:25 +0100623
Chris Wilsond6a22892017-02-23 07:44:17 +0000624 if (request)
625 add_wait_queue(&request->execute, &exec);
626
Chris Wilsonc81d4612016-07-01 17:23:25 +0100627 schedule();
Chris Wilsonfe3288b2017-02-12 17:20:01 +0000628
Chris Wilsond6a22892017-02-23 07:44:17 +0000629 if (request)
630 remove_wait_queue(&request->execute, &exec);
631
Chris Wilsonfe3288b2017-02-12 17:20:01 +0000632 if (kthread_should_park())
633 kthread_parkme();
Chris Wilsonc81d4612016-07-01 17:23:25 +0100634 }
Chris Wilsoncced5e22017-02-23 07:44:15 +0000635 i915_gem_request_put(request);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100636 } while (1);
637 __set_current_state(TASK_RUNNING);
638
639 return 0;
640}
641
Chris Wilsonb3850852016-07-01 17:23:26 +0100642void intel_engine_enable_signaling(struct drm_i915_gem_request *request)
Chris Wilsonc81d4612016-07-01 17:23:25 +0100643{
644 struct intel_engine_cs *engine = request->engine;
645 struct intel_breadcrumbs *b = &engine->breadcrumbs;
646 struct rb_node *parent, **p;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100647 bool first, wakeup;
Chris Wilson754c9fd2017-02-23 07:44:14 +0000648 u32 seqno;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100649
Chris Wilsonf6168e32016-10-28 13:58:55 +0100650 /* Note that we may be called from an interrupt handler on another
651 * device (e.g. nouveau signaling a fence completion causing us
652 * to submit a request, and so enable signaling). As such,
653 * we need to make sure that all other users of b->lock protect
654 * against interrupts, i.e. use spin_lock_irqsave.
655 */
656
657 /* locked by dma_fence_enable_sw_signaling() (irqsafe fence->lock) */
Chris Wilsone60a8702017-03-02 11:51:30 +0000658 GEM_BUG_ON(!irqs_disabled());
Chris Wilson67520412017-03-02 13:28:01 +0000659 lockdep_assert_held(&request->lock);
Chris Wilson754c9fd2017-02-23 07:44:14 +0000660
661 seqno = i915_gem_request_global_seqno(request);
662 if (!seqno)
Chris Wilson65e47602016-10-28 13:58:49 +0100663 return;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100664
Chris Wilsonb3850852016-07-01 17:23:26 +0100665 request->signaling.wait.tsk = b->signaler;
Chris Wilson56299fb2017-02-27 20:58:48 +0000666 request->signaling.wait.request = request;
Chris Wilson754c9fd2017-02-23 07:44:14 +0000667 request->signaling.wait.seqno = seqno;
Chris Wilsone8a261e2016-07-20 13:31:49 +0100668 i915_gem_request_get(request);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100669
Chris Wilson61d3dc72017-03-03 19:08:24 +0000670 spin_lock(&b->rb_lock);
Chris Wilson4a50d202016-07-26 12:01:50 +0100671
Chris Wilsonc81d4612016-07-01 17:23:25 +0100672 /* First add ourselves into the list of waiters, but register our
673 * bottom-half as the signaller thread. As per usual, only the oldest
674 * waiter (not just signaller) is tasked as the bottom-half waking
675 * up all completed waiters after the user interrupt.
676 *
677 * If we are the oldest waiter, enable the irq (after which we
678 * must double check that the seqno did not complete).
679 */
Chris Wilsonb3850852016-07-01 17:23:26 +0100680 wakeup = __intel_engine_add_wait(engine, &request->signaling.wait);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100681
682 /* Now insert ourselves into the retirement ordered list of signals
683 * on this engine. We track the oldest seqno as that will be the
684 * first signal to complete.
685 */
Chris Wilsonc81d4612016-07-01 17:23:25 +0100686 parent = NULL;
687 first = true;
688 p = &b->signals.rb_node;
689 while (*p) {
690 parent = *p;
Chris Wilson754c9fd2017-02-23 07:44:14 +0000691 if (i915_seqno_passed(seqno,
692 to_signaler(parent)->signaling.wait.seqno)) {
Chris Wilsonc81d4612016-07-01 17:23:25 +0100693 p = &parent->rb_right;
694 first = false;
695 } else {
696 p = &parent->rb_left;
697 }
698 }
Chris Wilsonb3850852016-07-01 17:23:26 +0100699 rb_link_node(&request->signaling.node, parent, p);
700 rb_insert_color(&request->signaling.node, &b->signals);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100701 if (first)
Chris Wilsoncced5e22017-02-23 07:44:15 +0000702 rcu_assign_pointer(b->first_signal, request);
Chris Wilsonb3850852016-07-01 17:23:26 +0100703
Chris Wilson61d3dc72017-03-03 19:08:24 +0000704 spin_unlock(&b->rb_lock);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100705
706 if (wakeup)
707 wake_up_process(b->signaler);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100708}
709
Chris Wilson9eb143b2017-02-23 07:44:16 +0000710void intel_engine_cancel_signaling(struct drm_i915_gem_request *request)
711{
712 struct intel_engine_cs *engine = request->engine;
713 struct intel_breadcrumbs *b = &engine->breadcrumbs;
714
Chris Wilsone60a8702017-03-02 11:51:30 +0000715 GEM_BUG_ON(!irqs_disabled());
Chris Wilson67520412017-03-02 13:28:01 +0000716 lockdep_assert_held(&request->lock);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000717 GEM_BUG_ON(!request->signaling.wait.seqno);
718
Chris Wilson61d3dc72017-03-03 19:08:24 +0000719 spin_lock(&b->rb_lock);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000720
721 if (!RB_EMPTY_NODE(&request->signaling.node)) {
722 if (request == rcu_access_pointer(b->first_signal)) {
723 struct rb_node *rb =
724 rb_next(&request->signaling.node);
725 rcu_assign_pointer(b->first_signal,
726 rb ? to_signaler(rb) : NULL);
727 }
728 rb_erase(&request->signaling.node, &b->signals);
729 RB_CLEAR_NODE(&request->signaling.node);
730 i915_gem_request_put(request);
731 }
732
733 __intel_engine_remove_wait(engine, &request->signaling.wait);
734
Chris Wilson61d3dc72017-03-03 19:08:24 +0000735 spin_unlock(&b->rb_lock);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000736
737 request->signaling.wait.seqno = 0;
738}
739
Chris Wilson688e6c72016-07-01 17:23:15 +0100740int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine)
741{
742 struct intel_breadcrumbs *b = &engine->breadcrumbs;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100743 struct task_struct *tsk;
Chris Wilson688e6c72016-07-01 17:23:15 +0100744
Chris Wilson61d3dc72017-03-03 19:08:24 +0000745 spin_lock_init(&b->rb_lock);
746 spin_lock_init(&b->irq_lock);
747
Chris Wilson688e6c72016-07-01 17:23:15 +0100748 setup_timer(&b->fake_irq,
749 intel_breadcrumbs_fake_irq,
750 (unsigned long)engine);
Chris Wilson83348ba2016-08-09 17:47:51 +0100751 setup_timer(&b->hangcheck,
752 intel_breadcrumbs_hangcheck,
753 (unsigned long)engine);
Chris Wilson688e6c72016-07-01 17:23:15 +0100754
Chris Wilsonc81d4612016-07-01 17:23:25 +0100755 /* Spawn a thread to provide a common bottom-half for all signals.
756 * As this is an asynchronous interface we cannot steal the current
757 * task for handling the bottom-half to the user interrupt, therefore
758 * we create a thread to do the coherent seqno dance after the
759 * interrupt and then signal the waitqueue (via the dma-buf/fence).
760 */
761 tsk = kthread_run(intel_breadcrumbs_signaler, engine,
762 "i915/signal:%d", engine->id);
763 if (IS_ERR(tsk))
764 return PTR_ERR(tsk);
765
766 b->signaler = tsk;
767
Chris Wilson688e6c72016-07-01 17:23:15 +0100768 return 0;
769}
770
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100771static void cancel_fake_irq(struct intel_engine_cs *engine)
772{
773 struct intel_breadcrumbs *b = &engine->breadcrumbs;
774
775 del_timer_sync(&b->hangcheck);
776 del_timer_sync(&b->fake_irq);
777 clear_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings);
778}
779
780void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine)
781{
782 struct intel_breadcrumbs *b = &engine->breadcrumbs;
783
784 cancel_fake_irq(engine);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000785 spin_lock_irq(&b->irq_lock);
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100786
Chris Wilson67b807a82017-02-27 20:58:50 +0000787 if (b->irq_enabled)
788 irq_enable(engine);
789 else
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100790 irq_disable(engine);
Chris Wilson67b807a82017-02-27 20:58:50 +0000791
792 /* We set the IRQ_BREADCRUMB bit when we enable the irq presuming the
793 * GPU is active and may have already executed the MI_USER_INTERRUPT
794 * before the CPU is ready to receive. However, the engine is currently
795 * idle (we haven't started it yet), there is no possibility for a
796 * missed interrupt as we enabled the irq and so we can clear the
797 * immediate wakeup (until a real interrupt arrives for the waiter).
798 */
799 clear_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted);
800
801 if (b->irq_armed)
802 enable_fake_irq(b);
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100803
Chris Wilson61d3dc72017-03-03 19:08:24 +0000804 spin_unlock_irq(&b->irq_lock);
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100805}
806
Chris Wilson688e6c72016-07-01 17:23:15 +0100807void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine)
808{
809 struct intel_breadcrumbs *b = &engine->breadcrumbs;
810
Chris Wilson381744f2016-11-21 11:07:59 +0000811 /* The engines should be idle and all requests accounted for! */
Chris Wilson61d3dc72017-03-03 19:08:24 +0000812 WARN_ON(READ_ONCE(b->irq_wait));
Chris Wilson381744f2016-11-21 11:07:59 +0000813 WARN_ON(!RB_EMPTY_ROOT(&b->waiters));
Chris Wilsoncced5e22017-02-23 07:44:15 +0000814 WARN_ON(rcu_access_pointer(b->first_signal));
Chris Wilson381744f2016-11-21 11:07:59 +0000815 WARN_ON(!RB_EMPTY_ROOT(&b->signals));
816
Chris Wilsonc81d4612016-07-01 17:23:25 +0100817 if (!IS_ERR_OR_NULL(b->signaler))
818 kthread_stop(b->signaler);
819
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100820 cancel_fake_irq(engine);
Chris Wilson688e6c72016-07-01 17:23:15 +0100821}
822
Chris Wilson9b6586a2017-02-23 07:44:08 +0000823bool intel_breadcrumbs_busy(struct intel_engine_cs *engine)
Chris Wilsonc81d4612016-07-01 17:23:25 +0100824{
Chris Wilson9b6586a2017-02-23 07:44:08 +0000825 struct intel_breadcrumbs *b = &engine->breadcrumbs;
826 bool busy = false;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100827
Chris Wilson61d3dc72017-03-03 19:08:24 +0000828 spin_lock_irq(&b->rb_lock);
Chris Wilson6a5d1db2016-11-08 14:37:19 +0000829
Chris Wilson61d3dc72017-03-03 19:08:24 +0000830 if (b->irq_wait) {
831 wake_up_process(b->irq_wait->tsk);
Chris Wilson9b6586a2017-02-23 07:44:08 +0000832 busy |= intel_engine_flag(engine);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100833 }
834
Chris Wilsoncced5e22017-02-23 07:44:15 +0000835 if (rcu_access_pointer(b->first_signal)) {
Chris Wilson9b6586a2017-02-23 07:44:08 +0000836 wake_up_process(b->signaler);
837 busy |= intel_engine_flag(engine);
838 }
839
Chris Wilson61d3dc72017-03-03 19:08:24 +0000840 spin_unlock_irq(&b->rb_lock);
Chris Wilson9b6586a2017-02-23 07:44:08 +0000841
842 return busy;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100843}
Chris Wilsonf97fbf92017-02-13 17:15:14 +0000844
845#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
846#include "selftests/intel_breadcrumbs.c"
847#endif