blob: 6032d2a937d58dbe53896d71a9e29f4b2522fcff [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 Wilson67b807a82017-02-27 20:58:50 +0000170
171 if (b->irq_enabled) {
172 irq_disable(engine);
173 b->irq_enabled = false;
174 }
175
176 b->irq_armed = false;
177}
178
179void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine)
180{
181 struct intel_breadcrumbs *b = &engine->breadcrumbs;
182 unsigned long flags;
183
184 if (!b->irq_armed)
185 return;
186
Chris Wilson61d3dc72017-03-03 19:08:24 +0000187 spin_lock_irqsave(&b->irq_lock, flags);
Chris Wilson67b807a82017-02-27 20:58:50 +0000188
189 /* We only disarm the irq when we are idle (all requests completed),
190 * so if there remains a sleeping waiter, it missed the request
191 * completion.
192 */
193 if (__intel_breadcrumbs_wakeup(b) & ENGINE_WAKEUP_ASLEEP)
Chris Wilson80166e402017-02-28 08:50:18 +0000194 missed_breadcrumb(engine);
Chris Wilson67b807a82017-02-27 20:58:50 +0000195
196 __intel_engine_disarm_breadcrumbs(engine);
197
Chris Wilson61d3dc72017-03-03 19:08:24 +0000198 spin_unlock_irqrestore(&b->irq_lock, flags);
Chris Wilson67b807a82017-02-27 20:58:50 +0000199}
200
Chris Wilson6ef98ea2017-02-17 15:13:03 +0000201static bool use_fake_irq(const struct intel_breadcrumbs *b)
202{
203 const struct intel_engine_cs *engine =
204 container_of(b, struct intel_engine_cs, breadcrumbs);
205
206 if (!test_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings))
207 return false;
208
209 /* Only start with the heavy weight fake irq timer if we have not
210 * seen any interrupts since enabling it the first time. If the
211 * interrupts are still arriving, it means we made a mistake in our
212 * engine->seqno_barrier(), a timing error that should be transient
213 * and unlikely to reoccur.
214 */
215 return atomic_read(&engine->irq_count) == b->hangcheck_interrupts;
216}
217
Chris Wilson67b807a82017-02-27 20:58:50 +0000218static void enable_fake_irq(struct intel_breadcrumbs *b)
219{
220 /* Ensure we never sleep indefinitely */
221 if (!b->irq_enabled || use_fake_irq(b))
222 mod_timer(&b->fake_irq, jiffies + 1);
223 else
224 mod_timer(&b->hangcheck, wait_timeout());
225}
226
Chris Wilson04171312016-07-06 12:39:00 +0100227static void __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b)
Chris Wilson688e6c72016-07-01 17:23:15 +0100228{
229 struct intel_engine_cs *engine =
230 container_of(b, struct intel_engine_cs, breadcrumbs);
231 struct drm_i915_private *i915 = engine->i915;
Chris Wilson688e6c72016-07-01 17:23:15 +0100232
Chris Wilson61d3dc72017-03-03 19:08:24 +0000233 lockdep_assert_held(&b->irq_lock);
Chris Wilson67b807a82017-02-27 20:58:50 +0000234 if (b->irq_armed)
Chris Wilson04171312016-07-06 12:39:00 +0100235 return;
Chris Wilson688e6c72016-07-01 17:23:15 +0100236
Chris Wilson67b807a82017-02-27 20:58:50 +0000237 /* The breadcrumb irq will be disarmed on the interrupt after the
238 * waiters are signaled. This gives us a single interrupt window in
239 * which we can add a new waiter and avoid the cost of re-enabling
240 * the irq.
241 */
242 b->irq_armed = true;
243 GEM_BUG_ON(b->irq_enabled);
244
Chris Wilsonf97fbf92017-02-13 17:15:14 +0000245 if (I915_SELFTEST_ONLY(b->mock)) {
246 /* For our mock objects we want to avoid interaction
247 * with the real hardware (which is not set up). So
248 * we simply pretend we have enabled the powerwell
249 * and the irq, and leave it up to the mock
250 * implementation to call intel_engine_wakeup()
251 * itself when it wants to simulate a user interrupt,
252 */
Chris Wilsonf97fbf92017-02-13 17:15:14 +0000253 return;
254 }
255
Chris Wilson688e6c72016-07-01 17:23:15 +0100256 /* Since we are waiting on a request, the GPU should be busy
Chris Wilson67b807a82017-02-27 20:58:50 +0000257 * and should have its own rpm reference. This is tracked
258 * by i915->gt.awake, we can forgo holding our own wakref
259 * for the interrupt as before i915->gt.awake is released (when
260 * the driver is idle) we disarm the breadcrumbs.
Chris Wilson688e6c72016-07-01 17:23:15 +0100261 */
Chris Wilson688e6c72016-07-01 17:23:15 +0100262
263 /* No interrupts? Kick the waiter every jiffie! */
264 if (intel_irqs_enabled(i915)) {
Chris Wilson3d5564e2016-07-01 17:23:23 +0100265 if (!test_bit(engine->id, &i915->gpu_error.test_irq_rings))
Chris Wilson688e6c72016-07-01 17:23:15 +0100266 irq_enable(engine);
Chris Wilson688e6c72016-07-01 17:23:15 +0100267 b->irq_enabled = true;
268 }
269
Chris Wilson67b807a82017-02-27 20:58:50 +0000270 enable_fake_irq(b);
Chris Wilson688e6c72016-07-01 17:23:15 +0100271}
272
273static inline struct intel_wait *to_wait(struct rb_node *node)
274{
Chris Wilsond8567862016-12-20 10:40:03 +0000275 return rb_entry(node, struct intel_wait, node);
Chris Wilson688e6c72016-07-01 17:23:15 +0100276}
277
278static inline void __intel_breadcrumbs_finish(struct intel_breadcrumbs *b,
279 struct intel_wait *wait)
280{
Chris Wilson61d3dc72017-03-03 19:08:24 +0000281 lockdep_assert_held(&b->rb_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100282
283 /* This request is completed, so remove it from the tree, mark it as
284 * complete, and *then* wake up the associated task.
285 */
286 rb_erase(&wait->node, &b->waiters);
287 RB_CLEAR_NODE(&wait->node);
288
289 wake_up_process(wait->tsk); /* implicit smp_wmb() */
290}
291
Chris Wilsonb66255f2017-03-03 17:14:22 +0000292static inline void __intel_breadcrumbs_next(struct intel_engine_cs *engine,
293 struct rb_node *next)
294{
295 struct intel_breadcrumbs *b = &engine->breadcrumbs;
296
Chris Wilson61d3dc72017-03-03 19:08:24 +0000297 spin_lock(&b->irq_lock);
Chris Wilsonb66255f2017-03-03 17:14:22 +0000298 GEM_BUG_ON(!b->irq_armed);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000299 b->irq_wait = to_wait(next);
300 spin_unlock(&b->irq_lock);
Chris Wilsonb66255f2017-03-03 17:14:22 +0000301
302 /* We always wake up the next waiter that takes over as the bottom-half
303 * as we may delegate not only the irq-seqno barrier to the next waiter
304 * but also the task of waking up concurrent waiters.
305 */
306 if (next)
307 wake_up_process(to_wait(next)->tsk);
308}
309
Chris Wilson688e6c72016-07-01 17:23:15 +0100310static bool __intel_engine_add_wait(struct intel_engine_cs *engine,
311 struct intel_wait *wait)
312{
313 struct intel_breadcrumbs *b = &engine->breadcrumbs;
314 struct rb_node **p, *parent, *completed;
315 bool first;
316 u32 seqno;
317
318 /* Insert the request into the retirement ordered list
319 * of waiters by walking the rbtree. If we are the oldest
320 * seqno in the tree (the first to be retired), then
321 * set ourselves as the bottom-half.
322 *
323 * As we descend the tree, prune completed branches since we hold the
324 * spinlock we know that the first_waiter must be delayed and can
325 * reduce some of the sequential wake up latency if we take action
326 * ourselves and wake up the completed tasks in parallel. Also, by
327 * removing stale elements in the tree, we may be able to reduce the
328 * ping-pong between the old bottom-half and ourselves as first-waiter.
329 */
330 first = true;
331 parent = NULL;
332 completed = NULL;
Chris Wilson1b7744e2016-07-01 17:23:17 +0100333 seqno = intel_engine_get_seqno(engine);
Chris Wilson688e6c72016-07-01 17:23:15 +0100334
335 /* If the request completed before we managed to grab the spinlock,
336 * return now before adding ourselves to the rbtree. We let the
337 * current bottom-half handle any pending wakeups and instead
338 * try and get out of the way quickly.
339 */
340 if (i915_seqno_passed(seqno, wait->seqno)) {
341 RB_CLEAR_NODE(&wait->node);
342 return first;
343 }
344
345 p = &b->waiters.rb_node;
346 while (*p) {
347 parent = *p;
348 if (wait->seqno == to_wait(parent)->seqno) {
349 /* We have multiple waiters on the same seqno, select
350 * the highest priority task (that with the smallest
351 * task->prio) to serve as the bottom-half for this
352 * group.
353 */
354 if (wait->tsk->prio > to_wait(parent)->tsk->prio) {
355 p = &parent->rb_right;
356 first = false;
357 } else {
358 p = &parent->rb_left;
359 }
360 } else if (i915_seqno_passed(wait->seqno,
361 to_wait(parent)->seqno)) {
362 p = &parent->rb_right;
363 if (i915_seqno_passed(seqno, to_wait(parent)->seqno))
364 completed = parent;
365 else
366 first = false;
367 } else {
368 p = &parent->rb_left;
369 }
370 }
371 rb_link_node(&wait->node, parent, p);
372 rb_insert_color(&wait->node, &b->waiters);
Chris Wilson688e6c72016-07-01 17:23:15 +0100373
374 if (completed) {
375 struct rb_node *next = rb_next(completed);
376
377 GEM_BUG_ON(!next && !first);
378 if (next && next != &wait->node) {
379 GEM_BUG_ON(first);
Chris Wilsonb66255f2017-03-03 17:14:22 +0000380 __intel_breadcrumbs_next(engine, next);
Chris Wilson688e6c72016-07-01 17:23:15 +0100381 }
382
383 do {
384 struct intel_wait *crumb = to_wait(completed);
385 completed = rb_prev(completed);
386 __intel_breadcrumbs_finish(b, crumb);
387 } while (completed);
388 }
389
390 if (first) {
Chris Wilson61d3dc72017-03-03 19:08:24 +0000391 spin_lock(&b->irq_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100392 GEM_BUG_ON(rb_first(&b->waiters) != &wait->node);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000393 b->irq_wait = wait;
Chris Wilson04171312016-07-06 12:39:00 +0100394 /* After assigning ourselves as the new bottom-half, we must
395 * perform a cursory check to prevent a missed interrupt.
396 * Either we miss the interrupt whilst programming the hardware,
397 * or if there was a previous waiter (for a later seqno) they
398 * may be woken instead of us (due to the inherent race
Chris Wilsonaca34b62016-07-06 12:39:02 +0100399 * in the unlocked read of b->irq_seqno_bh in the irq handler)
400 * and so we miss the wake up.
Chris Wilson04171312016-07-06 12:39:00 +0100401 */
402 __intel_breadcrumbs_enable_irq(b);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000403 spin_unlock(&b->irq_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100404 }
Chris Wilson61d3dc72017-03-03 19:08:24 +0000405 GEM_BUG_ON(!b->irq_wait);
406 GEM_BUG_ON(rb_first(&b->waiters) != &b->irq_wait->node);
Chris Wilson688e6c72016-07-01 17:23:15 +0100407
408 return first;
409}
410
411bool intel_engine_add_wait(struct intel_engine_cs *engine,
412 struct intel_wait *wait)
413{
414 struct intel_breadcrumbs *b = &engine->breadcrumbs;
415 bool first;
416
Chris Wilson61d3dc72017-03-03 19:08:24 +0000417 spin_lock_irq(&b->rb_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100418 first = __intel_engine_add_wait(engine, wait);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000419 spin_unlock_irq(&b->rb_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100420
421 return first;
422}
423
Chris Wilson688e6c72016-07-01 17:23:15 +0100424static inline bool chain_wakeup(struct rb_node *rb, int priority)
425{
426 return rb && to_wait(rb)->tsk->prio <= priority;
427}
428
Chris Wilsonc81d4612016-07-01 17:23:25 +0100429static inline int wakeup_priority(struct intel_breadcrumbs *b,
430 struct task_struct *tsk)
431{
432 if (tsk == b->signaler)
433 return INT_MIN;
434 else
435 return tsk->prio;
436}
437
Chris Wilson9eb143b2017-02-23 07:44:16 +0000438static void __intel_engine_remove_wait(struct intel_engine_cs *engine,
439 struct intel_wait *wait)
Chris Wilson688e6c72016-07-01 17:23:15 +0100440{
441 struct intel_breadcrumbs *b = &engine->breadcrumbs;
442
Chris Wilson61d3dc72017-03-03 19:08:24 +0000443 lockdep_assert_held(&b->rb_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100444
445 if (RB_EMPTY_NODE(&wait->node))
Chris Wilson9eb143b2017-02-23 07:44:16 +0000446 goto out;
Chris Wilson688e6c72016-07-01 17:23:15 +0100447
Chris Wilson61d3dc72017-03-03 19:08:24 +0000448 if (b->irq_wait == wait) {
Chris Wilsonc81d4612016-07-01 17:23:25 +0100449 const int priority = wakeup_priority(b, wait->tsk);
Chris Wilson688e6c72016-07-01 17:23:15 +0100450 struct rb_node *next;
Chris Wilson688e6c72016-07-01 17:23:15 +0100451
Chris Wilson688e6c72016-07-01 17:23:15 +0100452 /* We are the current bottom-half. Find the next candidate,
453 * the first waiter in the queue on the remaining oldest
454 * request. As multiple seqnos may complete in the time it
455 * takes us to wake up and find the next waiter, we have to
456 * wake up that waiter for it to perform its own coherent
457 * completion check.
458 */
459 next = rb_next(&wait->node);
460 if (chain_wakeup(next, priority)) {
461 /* If the next waiter is already complete,
462 * wake it up and continue onto the next waiter. So
463 * if have a small herd, they will wake up in parallel
464 * rather than sequentially, which should reduce
465 * the overall latency in waking all the completed
466 * clients.
467 *
468 * However, waking up a chain adds extra latency to
469 * the first_waiter. This is undesirable if that
470 * waiter is a high priority task.
471 */
Chris Wilson1b7744e2016-07-01 17:23:17 +0100472 u32 seqno = intel_engine_get_seqno(engine);
Chris Wilson688e6c72016-07-01 17:23:15 +0100473
474 while (i915_seqno_passed(seqno, to_wait(next)->seqno)) {
475 struct rb_node *n = rb_next(next);
476
477 __intel_breadcrumbs_finish(b, to_wait(next));
478 next = n;
479 if (!chain_wakeup(next, priority))
480 break;
481 }
482 }
483
Chris Wilsonb66255f2017-03-03 17:14:22 +0000484 __intel_breadcrumbs_next(engine, next);
Chris Wilson688e6c72016-07-01 17:23:15 +0100485 } else {
486 GEM_BUG_ON(rb_first(&b->waiters) == &wait->node);
487 }
488
489 GEM_BUG_ON(RB_EMPTY_NODE(&wait->node));
490 rb_erase(&wait->node, &b->waiters);
491
Chris Wilson9eb143b2017-02-23 07:44:16 +0000492out:
Chris Wilson61d3dc72017-03-03 19:08:24 +0000493 GEM_BUG_ON(b->irq_wait == wait);
Chris Wilson688e6c72016-07-01 17:23:15 +0100494 GEM_BUG_ON(rb_first(&b->waiters) !=
Chris Wilson61d3dc72017-03-03 19:08:24 +0000495 (b->irq_wait ? &b->irq_wait->node : NULL));
Chris Wilson9eb143b2017-02-23 07:44:16 +0000496}
497
498void intel_engine_remove_wait(struct intel_engine_cs *engine,
499 struct intel_wait *wait)
500{
501 struct intel_breadcrumbs *b = &engine->breadcrumbs;
502
503 /* Quick check to see if this waiter was already decoupled from
504 * the tree by the bottom-half to avoid contention on the spinlock
505 * by the herd.
506 */
507 if (RB_EMPTY_NODE(&wait->node))
508 return;
509
Chris Wilson61d3dc72017-03-03 19:08:24 +0000510 spin_lock_irq(&b->rb_lock);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000511 __intel_engine_remove_wait(engine, wait);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000512 spin_unlock_irq(&b->rb_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100513}
514
Chris Wilsond6a22892017-02-23 07:44:17 +0000515static bool signal_valid(const struct drm_i915_gem_request *request)
516{
517 return intel_wait_check_request(&request->signaling.wait, request);
518}
519
520static bool signal_complete(const struct drm_i915_gem_request *request)
Chris Wilsonc81d4612016-07-01 17:23:25 +0100521{
Chris Wilsonb3850852016-07-01 17:23:26 +0100522 if (!request)
Chris Wilsonc81d4612016-07-01 17:23:25 +0100523 return false;
524
525 /* If another process served as the bottom-half it may have already
526 * signalled that this wait is already completed.
527 */
Chris Wilsonb3850852016-07-01 17:23:26 +0100528 if (intel_wait_complete(&request->signaling.wait))
Chris Wilsond6a22892017-02-23 07:44:17 +0000529 return signal_valid(request);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100530
531 /* Carefully check if the request is complete, giving time for the
532 * seqno to be visible or if the GPU hung.
533 */
Chris Wilsonb3850852016-07-01 17:23:26 +0100534 if (__i915_request_irq_complete(request))
Chris Wilsonc81d4612016-07-01 17:23:25 +0100535 return true;
536
537 return false;
538}
539
Chris Wilsonb3850852016-07-01 17:23:26 +0100540static struct drm_i915_gem_request *to_signaler(struct rb_node *rb)
Chris Wilsonc81d4612016-07-01 17:23:25 +0100541{
Chris Wilsond8567862016-12-20 10:40:03 +0000542 return rb_entry(rb, struct drm_i915_gem_request, signaling.node);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100543}
544
545static void signaler_set_rtpriority(void)
546{
547 struct sched_param param = { .sched_priority = 1 };
548
549 sched_setscheduler_nocheck(current, SCHED_FIFO, &param);
550}
551
552static int intel_breadcrumbs_signaler(void *arg)
553{
554 struct intel_engine_cs *engine = arg;
555 struct intel_breadcrumbs *b = &engine->breadcrumbs;
Chris Wilsonb3850852016-07-01 17:23:26 +0100556 struct drm_i915_gem_request *request;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100557
558 /* Install ourselves with high priority to reduce signalling latency */
559 signaler_set_rtpriority();
560
561 do {
562 set_current_state(TASK_INTERRUPTIBLE);
563
564 /* We are either woken up by the interrupt bottom-half,
565 * or by a client adding a new signaller. In both cases,
566 * the GPU seqno may have advanced beyond our oldest signal.
567 * If it has, propagate the signal, remove the waiter and
568 * check again with the next oldest signal. Otherwise we
569 * need to wait for a new interrupt from the GPU or for
570 * a new client.
571 */
Chris Wilsoncced5e22017-02-23 07:44:15 +0000572 rcu_read_lock();
573 request = rcu_dereference(b->first_signal);
574 if (request)
575 request = i915_gem_request_get_rcu(request);
576 rcu_read_unlock();
Chris Wilsonb3850852016-07-01 17:23:26 +0100577 if (signal_complete(request)) {
Chris Wilson7c9e9342017-01-24 11:00:09 +0000578 local_bh_disable();
579 dma_fence_signal(&request->fence);
580 local_bh_enable(); /* kick start the tasklets */
581
Chris Wilson61d3dc72017-03-03 19:08:24 +0000582 spin_lock_irq(&b->rb_lock);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000583
Chris Wilsonc81d4612016-07-01 17:23:25 +0100584 /* Wake up all other completed waiters and select the
585 * next bottom-half for the next user interrupt.
586 */
Chris Wilson9eb143b2017-02-23 07:44:16 +0000587 __intel_engine_remove_wait(engine,
588 &request->signaling.wait);
Chris Wilson5590af32016-09-09 14:11:54 +0100589
Chris Wilsonc81d4612016-07-01 17:23:25 +0100590 /* Find the next oldest signal. Note that as we have
591 * not been holding the lock, another client may
592 * have installed an even older signal than the one
593 * we just completed - so double check we are still
594 * the oldest before picking the next one.
595 */
Chris Wilsoncced5e22017-02-23 07:44:15 +0000596 if (request == rcu_access_pointer(b->first_signal)) {
Chris Wilsonb3850852016-07-01 17:23:26 +0100597 struct rb_node *rb =
598 rb_next(&request->signaling.node);
Chris Wilsoncced5e22017-02-23 07:44:15 +0000599 rcu_assign_pointer(b->first_signal,
600 rb ? to_signaler(rb) : NULL);
Chris Wilsonb3850852016-07-01 17:23:26 +0100601 }
602 rb_erase(&request->signaling.node, &b->signals);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000603 RB_CLEAR_NODE(&request->signaling.node);
604
Chris Wilson61d3dc72017-03-03 19:08:24 +0000605 spin_unlock_irq(&b->rb_lock);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100606
Chris Wilsone8a261e2016-07-20 13:31:49 +0100607 i915_gem_request_put(request);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100608 } else {
Chris Wilsond6a22892017-02-23 07:44:17 +0000609 DEFINE_WAIT(exec);
610
Chris Wilsoncced5e22017-02-23 07:44:15 +0000611 if (kthread_should_stop()) {
612 GEM_BUG_ON(request);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100613 break;
Chris Wilsoncced5e22017-02-23 07:44:15 +0000614 }
Chris Wilsonc81d4612016-07-01 17:23:25 +0100615
Chris Wilsond6a22892017-02-23 07:44:17 +0000616 if (request)
617 add_wait_queue(&request->execute, &exec);
618
Chris Wilsonc81d4612016-07-01 17:23:25 +0100619 schedule();
Chris Wilsonfe3288b2017-02-12 17:20:01 +0000620
Chris Wilsond6a22892017-02-23 07:44:17 +0000621 if (request)
622 remove_wait_queue(&request->execute, &exec);
623
Chris Wilsonfe3288b2017-02-12 17:20:01 +0000624 if (kthread_should_park())
625 kthread_parkme();
Chris Wilsonc81d4612016-07-01 17:23:25 +0100626 }
Chris Wilsoncced5e22017-02-23 07:44:15 +0000627 i915_gem_request_put(request);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100628 } while (1);
629 __set_current_state(TASK_RUNNING);
630
631 return 0;
632}
633
Chris Wilsonb3850852016-07-01 17:23:26 +0100634void intel_engine_enable_signaling(struct drm_i915_gem_request *request)
Chris Wilsonc81d4612016-07-01 17:23:25 +0100635{
636 struct intel_engine_cs *engine = request->engine;
637 struct intel_breadcrumbs *b = &engine->breadcrumbs;
638 struct rb_node *parent, **p;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100639 bool first, wakeup;
Chris Wilson754c9fd2017-02-23 07:44:14 +0000640 u32 seqno;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100641
Chris Wilsonf6168e32016-10-28 13:58:55 +0100642 /* Note that we may be called from an interrupt handler on another
643 * device (e.g. nouveau signaling a fence completion causing us
644 * to submit a request, and so enable signaling). As such,
645 * we need to make sure that all other users of b->lock protect
646 * against interrupts, i.e. use spin_lock_irqsave.
647 */
648
649 /* locked by dma_fence_enable_sw_signaling() (irqsafe fence->lock) */
Chris Wilsone60a8702017-03-02 11:51:30 +0000650 GEM_BUG_ON(!irqs_disabled());
Chris Wilson67520412017-03-02 13:28:01 +0000651 lockdep_assert_held(&request->lock);
Chris Wilson754c9fd2017-02-23 07:44:14 +0000652
653 seqno = i915_gem_request_global_seqno(request);
654 if (!seqno)
Chris Wilson65e47602016-10-28 13:58:49 +0100655 return;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100656
Chris Wilsonb3850852016-07-01 17:23:26 +0100657 request->signaling.wait.tsk = b->signaler;
Chris Wilson56299fb2017-02-27 20:58:48 +0000658 request->signaling.wait.request = request;
Chris Wilson754c9fd2017-02-23 07:44:14 +0000659 request->signaling.wait.seqno = seqno;
Chris Wilsone8a261e2016-07-20 13:31:49 +0100660 i915_gem_request_get(request);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100661
Chris Wilson61d3dc72017-03-03 19:08:24 +0000662 spin_lock(&b->rb_lock);
Chris Wilson4a50d202016-07-26 12:01:50 +0100663
Chris Wilsonc81d4612016-07-01 17:23:25 +0100664 /* First add ourselves into the list of waiters, but register our
665 * bottom-half as the signaller thread. As per usual, only the oldest
666 * waiter (not just signaller) is tasked as the bottom-half waking
667 * up all completed waiters after the user interrupt.
668 *
669 * If we are the oldest waiter, enable the irq (after which we
670 * must double check that the seqno did not complete).
671 */
Chris Wilsonb3850852016-07-01 17:23:26 +0100672 wakeup = __intel_engine_add_wait(engine, &request->signaling.wait);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100673
674 /* Now insert ourselves into the retirement ordered list of signals
675 * on this engine. We track the oldest seqno as that will be the
676 * first signal to complete.
677 */
Chris Wilsonc81d4612016-07-01 17:23:25 +0100678 parent = NULL;
679 first = true;
680 p = &b->signals.rb_node;
681 while (*p) {
682 parent = *p;
Chris Wilson754c9fd2017-02-23 07:44:14 +0000683 if (i915_seqno_passed(seqno,
684 to_signaler(parent)->signaling.wait.seqno)) {
Chris Wilsonc81d4612016-07-01 17:23:25 +0100685 p = &parent->rb_right;
686 first = false;
687 } else {
688 p = &parent->rb_left;
689 }
690 }
Chris Wilsonb3850852016-07-01 17:23:26 +0100691 rb_link_node(&request->signaling.node, parent, p);
692 rb_insert_color(&request->signaling.node, &b->signals);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100693 if (first)
Chris Wilsoncced5e22017-02-23 07:44:15 +0000694 rcu_assign_pointer(b->first_signal, request);
Chris Wilsonb3850852016-07-01 17:23:26 +0100695
Chris Wilson61d3dc72017-03-03 19:08:24 +0000696 spin_unlock(&b->rb_lock);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100697
698 if (wakeup)
699 wake_up_process(b->signaler);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100700}
701
Chris Wilson9eb143b2017-02-23 07:44:16 +0000702void intel_engine_cancel_signaling(struct drm_i915_gem_request *request)
703{
704 struct intel_engine_cs *engine = request->engine;
705 struct intel_breadcrumbs *b = &engine->breadcrumbs;
706
Chris Wilsone60a8702017-03-02 11:51:30 +0000707 GEM_BUG_ON(!irqs_disabled());
Chris Wilson67520412017-03-02 13:28:01 +0000708 lockdep_assert_held(&request->lock);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000709 GEM_BUG_ON(!request->signaling.wait.seqno);
710
Chris Wilson61d3dc72017-03-03 19:08:24 +0000711 spin_lock(&b->rb_lock);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000712
713 if (!RB_EMPTY_NODE(&request->signaling.node)) {
714 if (request == rcu_access_pointer(b->first_signal)) {
715 struct rb_node *rb =
716 rb_next(&request->signaling.node);
717 rcu_assign_pointer(b->first_signal,
718 rb ? to_signaler(rb) : NULL);
719 }
720 rb_erase(&request->signaling.node, &b->signals);
721 RB_CLEAR_NODE(&request->signaling.node);
722 i915_gem_request_put(request);
723 }
724
725 __intel_engine_remove_wait(engine, &request->signaling.wait);
726
Chris Wilson61d3dc72017-03-03 19:08:24 +0000727 spin_unlock(&b->rb_lock);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000728
729 request->signaling.wait.seqno = 0;
730}
731
Chris Wilson688e6c72016-07-01 17:23:15 +0100732int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine)
733{
734 struct intel_breadcrumbs *b = &engine->breadcrumbs;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100735 struct task_struct *tsk;
Chris Wilson688e6c72016-07-01 17:23:15 +0100736
Chris Wilson61d3dc72017-03-03 19:08:24 +0000737 spin_lock_init(&b->rb_lock);
738 spin_lock_init(&b->irq_lock);
739
Chris Wilson688e6c72016-07-01 17:23:15 +0100740 setup_timer(&b->fake_irq,
741 intel_breadcrumbs_fake_irq,
742 (unsigned long)engine);
Chris Wilson83348ba2016-08-09 17:47:51 +0100743 setup_timer(&b->hangcheck,
744 intel_breadcrumbs_hangcheck,
745 (unsigned long)engine);
Chris Wilson688e6c72016-07-01 17:23:15 +0100746
Chris Wilsonc81d4612016-07-01 17:23:25 +0100747 /* Spawn a thread to provide a common bottom-half for all signals.
748 * As this is an asynchronous interface we cannot steal the current
749 * task for handling the bottom-half to the user interrupt, therefore
750 * we create a thread to do the coherent seqno dance after the
751 * interrupt and then signal the waitqueue (via the dma-buf/fence).
752 */
753 tsk = kthread_run(intel_breadcrumbs_signaler, engine,
754 "i915/signal:%d", engine->id);
755 if (IS_ERR(tsk))
756 return PTR_ERR(tsk);
757
758 b->signaler = tsk;
759
Chris Wilson688e6c72016-07-01 17:23:15 +0100760 return 0;
761}
762
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100763static void cancel_fake_irq(struct intel_engine_cs *engine)
764{
765 struct intel_breadcrumbs *b = &engine->breadcrumbs;
766
767 del_timer_sync(&b->hangcheck);
768 del_timer_sync(&b->fake_irq);
769 clear_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings);
770}
771
772void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine)
773{
774 struct intel_breadcrumbs *b = &engine->breadcrumbs;
775
776 cancel_fake_irq(engine);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000777 spin_lock_irq(&b->irq_lock);
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100778
Chris Wilson67b807a82017-02-27 20:58:50 +0000779 if (b->irq_enabled)
780 irq_enable(engine);
781 else
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100782 irq_disable(engine);
Chris Wilson67b807a82017-02-27 20:58:50 +0000783
784 /* We set the IRQ_BREADCRUMB bit when we enable the irq presuming the
785 * GPU is active and may have already executed the MI_USER_INTERRUPT
786 * before the CPU is ready to receive. However, the engine is currently
787 * idle (we haven't started it yet), there is no possibility for a
788 * missed interrupt as we enabled the irq and so we can clear the
789 * immediate wakeup (until a real interrupt arrives for the waiter).
790 */
791 clear_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted);
792
793 if (b->irq_armed)
794 enable_fake_irq(b);
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100795
Chris Wilson61d3dc72017-03-03 19:08:24 +0000796 spin_unlock_irq(&b->irq_lock);
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100797}
798
Chris Wilson688e6c72016-07-01 17:23:15 +0100799void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine)
800{
801 struct intel_breadcrumbs *b = &engine->breadcrumbs;
802
Chris Wilson381744f2016-11-21 11:07:59 +0000803 /* The engines should be idle and all requests accounted for! */
Chris Wilson61d3dc72017-03-03 19:08:24 +0000804 WARN_ON(READ_ONCE(b->irq_wait));
Chris Wilson381744f2016-11-21 11:07:59 +0000805 WARN_ON(!RB_EMPTY_ROOT(&b->waiters));
Chris Wilsoncced5e22017-02-23 07:44:15 +0000806 WARN_ON(rcu_access_pointer(b->first_signal));
Chris Wilson381744f2016-11-21 11:07:59 +0000807 WARN_ON(!RB_EMPTY_ROOT(&b->signals));
808
Chris Wilsonc81d4612016-07-01 17:23:25 +0100809 if (!IS_ERR_OR_NULL(b->signaler))
810 kthread_stop(b->signaler);
811
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100812 cancel_fake_irq(engine);
Chris Wilson688e6c72016-07-01 17:23:15 +0100813}
814
Chris Wilson9b6586a2017-02-23 07:44:08 +0000815bool intel_breadcrumbs_busy(struct intel_engine_cs *engine)
Chris Wilsonc81d4612016-07-01 17:23:25 +0100816{
Chris Wilson9b6586a2017-02-23 07:44:08 +0000817 struct intel_breadcrumbs *b = &engine->breadcrumbs;
818 bool busy = false;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100819
Chris Wilson61d3dc72017-03-03 19:08:24 +0000820 spin_lock_irq(&b->rb_lock);
Chris Wilson6a5d1db2016-11-08 14:37:19 +0000821
Chris Wilson61d3dc72017-03-03 19:08:24 +0000822 if (b->irq_wait) {
823 wake_up_process(b->irq_wait->tsk);
Chris Wilson9b6586a2017-02-23 07:44:08 +0000824 busy |= intel_engine_flag(engine);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100825 }
826
Chris Wilsoncced5e22017-02-23 07:44:15 +0000827 if (rcu_access_pointer(b->first_signal)) {
Chris Wilson9b6586a2017-02-23 07:44:08 +0000828 wake_up_process(b->signaler);
829 busy |= intel_engine_flag(engine);
830 }
831
Chris Wilson61d3dc72017-03-03 19:08:24 +0000832 spin_unlock_irq(&b->rb_lock);
Chris Wilson9b6586a2017-02-23 07:44:08 +0000833
834 return busy;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100835}
Chris Wilsonf97fbf92017-02-13 17:15:14 +0000836
837#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
838#include "selftests/intel_breadcrumbs.c"
839#endif