blob: 438f874a2068dac12c5f98334a744a24832bd9cf [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>
Ingo Molnarae7e81c2017-02-01 18:07:51 +010026#include <uapi/linux/sched/types.h>
Chris Wilsonc81d4612016-07-01 17:23:25 +010027
Chris Wilson688e6c72016-07-01 17:23:15 +010028#include "i915_drv.h"
29
Chris Wilson67b807a82017-02-27 20:58:50 +000030static unsigned int __intel_breadcrumbs_wakeup(struct intel_breadcrumbs *b)
Chris Wilson8d769ea2017-02-27 20:58:47 +000031{
Chris Wilson56299fb2017-02-27 20:58:48 +000032 struct intel_wait *wait;
Chris Wilson8d769ea2017-02-27 20:58:47 +000033 unsigned int result = 0;
34
Chris Wilson61d3dc72017-03-03 19:08:24 +000035 lockdep_assert_held(&b->irq_lock);
36
37 wait = b->irq_wait;
Chris Wilson56299fb2017-02-27 20:58:48 +000038 if (wait) {
Chris Wilson8d769ea2017-02-27 20:58:47 +000039 result = ENGINE_WAKEUP_WAITER;
Chris Wilson67b807a82017-02-27 20:58:50 +000040 if (wake_up_process(wait->tsk))
41 result |= ENGINE_WAKEUP_ASLEEP;
Chris Wilson8d769ea2017-02-27 20:58:47 +000042 }
Chris Wilson67b807a82017-02-27 20:58:50 +000043
44 return result;
45}
46
47unsigned int intel_engine_wakeup(struct intel_engine_cs *engine)
48{
49 struct intel_breadcrumbs *b = &engine->breadcrumbs;
Chris Wilson67b807a82017-02-27 20:58:50 +000050 unsigned int result;
51
Tvrtko Ursulincdc3a452017-03-06 15:03:21 +000052 spin_lock_irq(&b->irq_lock);
Chris Wilson67b807a82017-02-27 20:58:50 +000053 result = __intel_breadcrumbs_wakeup(b);
Tvrtko Ursulincdc3a452017-03-06 15:03:21 +000054 spin_unlock_irq(&b->irq_lock);
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;
Chris Wilson688e6c72016-07-01 17:23:15 +0100112
113 /*
114 * The timer persists in case we cannot enable interrupts,
115 * or if we have previously seen seqno/interrupt incoherency
116 * ("missed interrupt" syndrome). Here the worker will wake up
117 * every jiffie in order to kick the oldest waiter to do the
118 * coherent seqno check.
119 */
Chris Wilson67b807a82017-02-27 20:58:50 +0000120
Tvrtko Ursulina9e64932017-03-06 15:03:20 +0000121 spin_lock_irq(&b->irq_lock);
Chris Wilson67b807a82017-02-27 20:58:50 +0000122 if (!__intel_breadcrumbs_wakeup(b))
123 __intel_engine_disarm_breadcrumbs(engine);
Tvrtko Ursulina9e64932017-03-06 15:03:20 +0000124 spin_unlock_irq(&b->irq_lock);
Chris Wilson67b807a82017-02-27 20:58:50 +0000125 if (!b->irq_armed)
Chris Wilson19d0a572017-02-27 20:58:49 +0000126 return;
127
Chris Wilson67b807a82017-02-27 20:58:50 +0000128 mod_timer(&b->fake_irq, jiffies + 1);
Chris Wilson19d0a572017-02-27 20:58:49 +0000129
130 /* Ensure that even if the GPU hangs, we get woken up.
131 *
132 * However, note that if no one is waiting, we never notice
133 * a gpu hang. Eventually, we will have to wait for a resource
134 * held by the GPU and so trigger a hangcheck. In the most
135 * pathological case, this will be upon memory starvation! To
136 * prevent this, we also queue the hangcheck from the retire
137 * worker.
138 */
139 i915_queue_hangcheck(engine->i915);
Chris Wilson688e6c72016-07-01 17:23:15 +0100140}
141
142static void irq_enable(struct intel_engine_cs *engine)
143{
Chris Wilson3d5564e2016-07-01 17:23:23 +0100144 /* Enabling the IRQ may miss the generation of the interrupt, but
145 * we still need to force the barrier before reading the seqno,
146 * just in case.
147 */
Chris Wilson538b2572017-01-24 15:18:05 +0000148 set_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted);
Chris Wilson31bb59c2016-07-01 17:23:27 +0100149
Chris Wilsonf6168e32016-10-28 13:58:55 +0100150 /* Caller disables interrupts */
151 spin_lock(&engine->i915->irq_lock);
Chris Wilson31bb59c2016-07-01 17:23:27 +0100152 engine->irq_enable(engine);
Chris Wilsonf6168e32016-10-28 13:58:55 +0100153 spin_unlock(&engine->i915->irq_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100154}
155
156static void irq_disable(struct intel_engine_cs *engine)
157{
Chris Wilsonf6168e32016-10-28 13:58:55 +0100158 /* Caller disables interrupts */
159 spin_lock(&engine->i915->irq_lock);
Chris Wilson31bb59c2016-07-01 17:23:27 +0100160 engine->irq_disable(engine);
Chris Wilsonf6168e32016-10-28 13:58:55 +0100161 spin_unlock(&engine->i915->irq_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100162}
163
Chris Wilson67b807a82017-02-27 20:58:50 +0000164void __intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine)
165{
166 struct intel_breadcrumbs *b = &engine->breadcrumbs;
167
Chris Wilson61d3dc72017-03-03 19:08:24 +0000168 lockdep_assert_held(&b->irq_lock);
Chris Wilsone1c0c912017-03-06 09:29:15 +0000169 GEM_BUG_ON(b->irq_wait);
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;
Chris Wilsone1c0c912017-03-06 09:29:15 +0000182 struct intel_wait *wait, *n;
Chris Wilson67b807a82017-02-27 20:58:50 +0000183
184 if (!b->irq_armed)
185 return;
186
Chris Wilson67b807a82017-02-27 20:58:50 +0000187 /* We only disarm the irq when we are idle (all requests completed),
Chris Wilsone1c0c912017-03-06 09:29:15 +0000188 * so if the bottom-half remains asleep, it missed the request
Chris Wilson67b807a82017-02-27 20:58:50 +0000189 * completion.
190 */
Chris Wilson67b807a82017-02-27 20:58:50 +0000191
Chris Wilsone1c0c912017-03-06 09:29:15 +0000192 spin_lock_irq(&b->rb_lock);
193 rbtree_postorder_for_each_entry_safe(wait, n, &b->waiters, node) {
194 RB_CLEAR_NODE(&wait->node);
195 if (wake_up_process(wait->tsk) && wait == b->irq_wait)
196 missed_breadcrumb(engine);
197 }
198 b->waiters = RB_ROOT;
199
200 spin_lock(&b->irq_lock);
201 b->irq_wait = NULL;
Chris Wilson67b807a82017-02-27 20:58:50 +0000202 __intel_engine_disarm_breadcrumbs(engine);
Chris Wilsone1c0c912017-03-06 09:29:15 +0000203 spin_unlock(&b->irq_lock);
Chris Wilson67b807a82017-02-27 20:58:50 +0000204
Chris Wilsone1c0c912017-03-06 09:29:15 +0000205 spin_unlock_irq(&b->rb_lock);
Chris Wilson67b807a82017-02-27 20:58:50 +0000206}
207
Chris Wilson6ef98ea2017-02-17 15:13:03 +0000208static bool use_fake_irq(const struct intel_breadcrumbs *b)
209{
210 const struct intel_engine_cs *engine =
211 container_of(b, struct intel_engine_cs, breadcrumbs);
212
213 if (!test_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings))
214 return false;
215
216 /* Only start with the heavy weight fake irq timer if we have not
217 * seen any interrupts since enabling it the first time. If the
218 * interrupts are still arriving, it means we made a mistake in our
219 * engine->seqno_barrier(), a timing error that should be transient
220 * and unlikely to reoccur.
221 */
222 return atomic_read(&engine->irq_count) == b->hangcheck_interrupts;
223}
224
Chris Wilson67b807a82017-02-27 20:58:50 +0000225static void enable_fake_irq(struct intel_breadcrumbs *b)
226{
227 /* Ensure we never sleep indefinitely */
228 if (!b->irq_enabled || use_fake_irq(b))
229 mod_timer(&b->fake_irq, jiffies + 1);
230 else
231 mod_timer(&b->hangcheck, wait_timeout());
232}
233
Chris Wilson04171312016-07-06 12:39:00 +0100234static void __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b)
Chris Wilson688e6c72016-07-01 17:23:15 +0100235{
236 struct intel_engine_cs *engine =
237 container_of(b, struct intel_engine_cs, breadcrumbs);
238 struct drm_i915_private *i915 = engine->i915;
Chris Wilson688e6c72016-07-01 17:23:15 +0100239
Chris Wilson61d3dc72017-03-03 19:08:24 +0000240 lockdep_assert_held(&b->irq_lock);
Chris Wilson67b807a82017-02-27 20:58:50 +0000241 if (b->irq_armed)
Chris Wilson04171312016-07-06 12:39:00 +0100242 return;
Chris Wilson688e6c72016-07-01 17:23:15 +0100243
Chris Wilson67b807a82017-02-27 20:58:50 +0000244 /* The breadcrumb irq will be disarmed on the interrupt after the
245 * waiters are signaled. This gives us a single interrupt window in
246 * which we can add a new waiter and avoid the cost of re-enabling
247 * the irq.
248 */
249 b->irq_armed = true;
250 GEM_BUG_ON(b->irq_enabled);
251
Chris Wilsonf97fbf92017-02-13 17:15:14 +0000252 if (I915_SELFTEST_ONLY(b->mock)) {
253 /* For our mock objects we want to avoid interaction
254 * with the real hardware (which is not set up). So
255 * we simply pretend we have enabled the powerwell
256 * and the irq, and leave it up to the mock
257 * implementation to call intel_engine_wakeup()
258 * itself when it wants to simulate a user interrupt,
259 */
Chris Wilsonf97fbf92017-02-13 17:15:14 +0000260 return;
261 }
262
Chris Wilson688e6c72016-07-01 17:23:15 +0100263 /* Since we are waiting on a request, the GPU should be busy
Chris Wilson67b807a82017-02-27 20:58:50 +0000264 * and should have its own rpm reference. This is tracked
265 * by i915->gt.awake, we can forgo holding our own wakref
266 * for the interrupt as before i915->gt.awake is released (when
267 * the driver is idle) we disarm the breadcrumbs.
Chris Wilson688e6c72016-07-01 17:23:15 +0100268 */
Chris Wilson688e6c72016-07-01 17:23:15 +0100269
270 /* No interrupts? Kick the waiter every jiffie! */
271 if (intel_irqs_enabled(i915)) {
Chris Wilson3d5564e2016-07-01 17:23:23 +0100272 if (!test_bit(engine->id, &i915->gpu_error.test_irq_rings))
Chris Wilson688e6c72016-07-01 17:23:15 +0100273 irq_enable(engine);
Chris Wilson688e6c72016-07-01 17:23:15 +0100274 b->irq_enabled = true;
275 }
276
Chris Wilson67b807a82017-02-27 20:58:50 +0000277 enable_fake_irq(b);
Chris Wilson688e6c72016-07-01 17:23:15 +0100278}
279
280static inline struct intel_wait *to_wait(struct rb_node *node)
281{
Chris Wilsond8567862016-12-20 10:40:03 +0000282 return rb_entry(node, struct intel_wait, node);
Chris Wilson688e6c72016-07-01 17:23:15 +0100283}
284
285static inline void __intel_breadcrumbs_finish(struct intel_breadcrumbs *b,
286 struct intel_wait *wait)
287{
Chris Wilson61d3dc72017-03-03 19:08:24 +0000288 lockdep_assert_held(&b->rb_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100289
290 /* This request is completed, so remove it from the tree, mark it as
291 * complete, and *then* wake up the associated task.
292 */
293 rb_erase(&wait->node, &b->waiters);
294 RB_CLEAR_NODE(&wait->node);
295
296 wake_up_process(wait->tsk); /* implicit smp_wmb() */
297}
298
Chris Wilsonb66255f2017-03-03 17:14:22 +0000299static inline void __intel_breadcrumbs_next(struct intel_engine_cs *engine,
300 struct rb_node *next)
301{
302 struct intel_breadcrumbs *b = &engine->breadcrumbs;
303
Chris Wilson61d3dc72017-03-03 19:08:24 +0000304 spin_lock(&b->irq_lock);
Chris Wilsonb66255f2017-03-03 17:14:22 +0000305 GEM_BUG_ON(!b->irq_armed);
Chris Wilson429732e2017-03-15 21:07:23 +0000306 GEM_BUG_ON(!b->irq_wait);
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
Chris Wilson688e6c72016-07-01 17:23:15 +0100382 if (first) {
Chris Wilson61d3dc72017-03-03 19:08:24 +0000383 spin_lock(&b->irq_lock);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000384 b->irq_wait = wait;
Chris Wilson04171312016-07-06 12:39:00 +0100385 /* After assigning ourselves as the new bottom-half, we must
386 * perform a cursory check to prevent a missed interrupt.
387 * Either we miss the interrupt whilst programming the hardware,
388 * or if there was a previous waiter (for a later seqno) they
389 * may be woken instead of us (due to the inherent race
Chris Wilsonaca34b62016-07-06 12:39:02 +0100390 * in the unlocked read of b->irq_seqno_bh in the irq handler)
391 * and so we miss the wake up.
Chris Wilson04171312016-07-06 12:39:00 +0100392 */
393 __intel_breadcrumbs_enable_irq(b);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000394 spin_unlock(&b->irq_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100395 }
Chris Wilson429732e2017-03-15 21:07:23 +0000396
397 if (completed) {
398 if (!first) {
399 struct rb_node *next = rb_next(completed);
400 GEM_BUG_ON(next == &wait->node);
401 __intel_breadcrumbs_next(engine, next);
402 }
403
404 do {
405 struct intel_wait *crumb = to_wait(completed);
406 completed = rb_prev(completed);
407 __intel_breadcrumbs_finish(b, crumb);
408 } while (completed);
409 }
410
Chris Wilson61d3dc72017-03-03 19:08:24 +0000411 GEM_BUG_ON(!b->irq_wait);
Chris Wilson429732e2017-03-15 21:07:23 +0000412 GEM_BUG_ON(!b->irq_armed);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000413 GEM_BUG_ON(rb_first(&b->waiters) != &b->irq_wait->node);
Chris Wilson688e6c72016-07-01 17:23:15 +0100414
415 return first;
416}
417
418bool intel_engine_add_wait(struct intel_engine_cs *engine,
419 struct intel_wait *wait)
420{
421 struct intel_breadcrumbs *b = &engine->breadcrumbs;
422 bool first;
423
Chris Wilson61d3dc72017-03-03 19:08:24 +0000424 spin_lock_irq(&b->rb_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100425 first = __intel_engine_add_wait(engine, wait);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000426 spin_unlock_irq(&b->rb_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100427
428 return first;
429}
430
Chris Wilson688e6c72016-07-01 17:23:15 +0100431static inline bool chain_wakeup(struct rb_node *rb, int priority)
432{
433 return rb && to_wait(rb)->tsk->prio <= priority;
434}
435
Chris Wilsonc81d4612016-07-01 17:23:25 +0100436static inline int wakeup_priority(struct intel_breadcrumbs *b,
437 struct task_struct *tsk)
438{
439 if (tsk == b->signaler)
440 return INT_MIN;
441 else
442 return tsk->prio;
443}
444
Chris Wilson9eb143b2017-02-23 07:44:16 +0000445static void __intel_engine_remove_wait(struct intel_engine_cs *engine,
446 struct intel_wait *wait)
Chris Wilson688e6c72016-07-01 17:23:15 +0100447{
448 struct intel_breadcrumbs *b = &engine->breadcrumbs;
449
Chris Wilson61d3dc72017-03-03 19:08:24 +0000450 lockdep_assert_held(&b->rb_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100451
452 if (RB_EMPTY_NODE(&wait->node))
Chris Wilson9eb143b2017-02-23 07:44:16 +0000453 goto out;
Chris Wilson688e6c72016-07-01 17:23:15 +0100454
Chris Wilson61d3dc72017-03-03 19:08:24 +0000455 if (b->irq_wait == wait) {
Chris Wilsonc81d4612016-07-01 17:23:25 +0100456 const int priority = wakeup_priority(b, wait->tsk);
Chris Wilson688e6c72016-07-01 17:23:15 +0100457 struct rb_node *next;
Chris Wilson688e6c72016-07-01 17:23:15 +0100458
Chris Wilson688e6c72016-07-01 17:23:15 +0100459 /* We are the current bottom-half. Find the next candidate,
460 * the first waiter in the queue on the remaining oldest
461 * request. As multiple seqnos may complete in the time it
462 * takes us to wake up and find the next waiter, we have to
463 * wake up that waiter for it to perform its own coherent
464 * completion check.
465 */
466 next = rb_next(&wait->node);
467 if (chain_wakeup(next, priority)) {
468 /* If the next waiter is already complete,
469 * wake it up and continue onto the next waiter. So
470 * if have a small herd, they will wake up in parallel
471 * rather than sequentially, which should reduce
472 * the overall latency in waking all the completed
473 * clients.
474 *
475 * However, waking up a chain adds extra latency to
476 * the first_waiter. This is undesirable if that
477 * waiter is a high priority task.
478 */
Chris Wilson1b7744e2016-07-01 17:23:17 +0100479 u32 seqno = intel_engine_get_seqno(engine);
Chris Wilson688e6c72016-07-01 17:23:15 +0100480
481 while (i915_seqno_passed(seqno, to_wait(next)->seqno)) {
482 struct rb_node *n = rb_next(next);
483
484 __intel_breadcrumbs_finish(b, to_wait(next));
485 next = n;
486 if (!chain_wakeup(next, priority))
487 break;
488 }
489 }
490
Chris Wilsonb66255f2017-03-03 17:14:22 +0000491 __intel_breadcrumbs_next(engine, next);
Chris Wilson688e6c72016-07-01 17:23:15 +0100492 } else {
493 GEM_BUG_ON(rb_first(&b->waiters) == &wait->node);
494 }
495
496 GEM_BUG_ON(RB_EMPTY_NODE(&wait->node));
497 rb_erase(&wait->node, &b->waiters);
498
Chris Wilson9eb143b2017-02-23 07:44:16 +0000499out:
Chris Wilson61d3dc72017-03-03 19:08:24 +0000500 GEM_BUG_ON(b->irq_wait == wait);
Chris Wilson688e6c72016-07-01 17:23:15 +0100501 GEM_BUG_ON(rb_first(&b->waiters) !=
Chris Wilson61d3dc72017-03-03 19:08:24 +0000502 (b->irq_wait ? &b->irq_wait->node : NULL));
Chris Wilson9eb143b2017-02-23 07:44:16 +0000503}
504
505void intel_engine_remove_wait(struct intel_engine_cs *engine,
506 struct intel_wait *wait)
507{
508 struct intel_breadcrumbs *b = &engine->breadcrumbs;
509
510 /* Quick check to see if this waiter was already decoupled from
511 * the tree by the bottom-half to avoid contention on the spinlock
512 * by the herd.
513 */
514 if (RB_EMPTY_NODE(&wait->node))
515 return;
516
Chris Wilson61d3dc72017-03-03 19:08:24 +0000517 spin_lock_irq(&b->rb_lock);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000518 __intel_engine_remove_wait(engine, wait);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000519 spin_unlock_irq(&b->rb_lock);
Chris Wilson688e6c72016-07-01 17:23:15 +0100520}
521
Chris Wilsond6a22892017-02-23 07:44:17 +0000522static bool signal_valid(const struct drm_i915_gem_request *request)
523{
524 return intel_wait_check_request(&request->signaling.wait, request);
525}
526
527static bool signal_complete(const struct drm_i915_gem_request *request)
Chris Wilsonc81d4612016-07-01 17:23:25 +0100528{
Chris Wilsonb3850852016-07-01 17:23:26 +0100529 if (!request)
Chris Wilsonc81d4612016-07-01 17:23:25 +0100530 return false;
531
532 /* If another process served as the bottom-half it may have already
533 * signalled that this wait is already completed.
534 */
Chris Wilsonb3850852016-07-01 17:23:26 +0100535 if (intel_wait_complete(&request->signaling.wait))
Chris Wilsond6a22892017-02-23 07:44:17 +0000536 return signal_valid(request);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100537
538 /* Carefully check if the request is complete, giving time for the
539 * seqno to be visible or if the GPU hung.
540 */
Chris Wilsonb3850852016-07-01 17:23:26 +0100541 if (__i915_request_irq_complete(request))
Chris Wilsonc81d4612016-07-01 17:23:25 +0100542 return true;
543
544 return false;
545}
546
Chris Wilsonb3850852016-07-01 17:23:26 +0100547static struct drm_i915_gem_request *to_signaler(struct rb_node *rb)
Chris Wilsonc81d4612016-07-01 17:23:25 +0100548{
Chris Wilsond8567862016-12-20 10:40:03 +0000549 return rb_entry(rb, struct drm_i915_gem_request, signaling.node);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100550}
551
552static void signaler_set_rtpriority(void)
553{
554 struct sched_param param = { .sched_priority = 1 };
555
556 sched_setscheduler_nocheck(current, SCHED_FIFO, &param);
557}
558
559static int intel_breadcrumbs_signaler(void *arg)
560{
561 struct intel_engine_cs *engine = arg;
562 struct intel_breadcrumbs *b = &engine->breadcrumbs;
Chris Wilsonb3850852016-07-01 17:23:26 +0100563 struct drm_i915_gem_request *request;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100564
565 /* Install ourselves with high priority to reduce signalling latency */
566 signaler_set_rtpriority();
567
568 do {
569 set_current_state(TASK_INTERRUPTIBLE);
570
571 /* We are either woken up by the interrupt bottom-half,
572 * or by a client adding a new signaller. In both cases,
573 * the GPU seqno may have advanced beyond our oldest signal.
574 * If it has, propagate the signal, remove the waiter and
575 * check again with the next oldest signal. Otherwise we
576 * need to wait for a new interrupt from the GPU or for
577 * a new client.
578 */
Chris Wilsoncced5e22017-02-23 07:44:15 +0000579 rcu_read_lock();
580 request = rcu_dereference(b->first_signal);
581 if (request)
582 request = i915_gem_request_get_rcu(request);
583 rcu_read_unlock();
Chris Wilsonb3850852016-07-01 17:23:26 +0100584 if (signal_complete(request)) {
Chris Wilson7c9e9342017-01-24 11:00:09 +0000585 local_bh_disable();
586 dma_fence_signal(&request->fence);
587 local_bh_enable(); /* kick start the tasklets */
588
Chris Wilson61d3dc72017-03-03 19:08:24 +0000589 spin_lock_irq(&b->rb_lock);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000590
Chris Wilsonc81d4612016-07-01 17:23:25 +0100591 /* Wake up all other completed waiters and select the
592 * next bottom-half for the next user interrupt.
593 */
Chris Wilson9eb143b2017-02-23 07:44:16 +0000594 __intel_engine_remove_wait(engine,
595 &request->signaling.wait);
Chris Wilson5590af32016-09-09 14:11:54 +0100596
Chris Wilsonc81d4612016-07-01 17:23:25 +0100597 /* Find the next oldest signal. Note that as we have
598 * not been holding the lock, another client may
599 * have installed an even older signal than the one
600 * we just completed - so double check we are still
601 * the oldest before picking the next one.
602 */
Chris Wilsoncced5e22017-02-23 07:44:15 +0000603 if (request == rcu_access_pointer(b->first_signal)) {
Chris Wilsonb3850852016-07-01 17:23:26 +0100604 struct rb_node *rb =
605 rb_next(&request->signaling.node);
Chris Wilsoncced5e22017-02-23 07:44:15 +0000606 rcu_assign_pointer(b->first_signal,
607 rb ? to_signaler(rb) : NULL);
Chris Wilsonb3850852016-07-01 17:23:26 +0100608 }
609 rb_erase(&request->signaling.node, &b->signals);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000610 RB_CLEAR_NODE(&request->signaling.node);
611
Chris Wilson61d3dc72017-03-03 19:08:24 +0000612 spin_unlock_irq(&b->rb_lock);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100613
Chris Wilsone8a261e2016-07-20 13:31:49 +0100614 i915_gem_request_put(request);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100615 } else {
Chris Wilsond6a22892017-02-23 07:44:17 +0000616 DEFINE_WAIT(exec);
617
Chris Wilsoncced5e22017-02-23 07:44:15 +0000618 if (kthread_should_stop()) {
619 GEM_BUG_ON(request);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100620 break;
Chris Wilsoncced5e22017-02-23 07:44:15 +0000621 }
Chris Wilsonc81d4612016-07-01 17:23:25 +0100622
Chris Wilsond6a22892017-02-23 07:44:17 +0000623 if (request)
624 add_wait_queue(&request->execute, &exec);
625
Chris Wilsonc81d4612016-07-01 17:23:25 +0100626 schedule();
Chris Wilsonfe3288b2017-02-12 17:20:01 +0000627
Chris Wilsond6a22892017-02-23 07:44:17 +0000628 if (request)
629 remove_wait_queue(&request->execute, &exec);
630
Chris Wilsonfe3288b2017-02-12 17:20:01 +0000631 if (kthread_should_park())
632 kthread_parkme();
Chris Wilsonc81d4612016-07-01 17:23:25 +0100633 }
Chris Wilsoncced5e22017-02-23 07:44:15 +0000634 i915_gem_request_put(request);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100635 } while (1);
636 __set_current_state(TASK_RUNNING);
637
638 return 0;
639}
640
Chris Wilsonb3850852016-07-01 17:23:26 +0100641void intel_engine_enable_signaling(struct drm_i915_gem_request *request)
Chris Wilsonc81d4612016-07-01 17:23:25 +0100642{
643 struct intel_engine_cs *engine = request->engine;
644 struct intel_breadcrumbs *b = &engine->breadcrumbs;
645 struct rb_node *parent, **p;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100646 bool first, wakeup;
Chris Wilson754c9fd2017-02-23 07:44:14 +0000647 u32 seqno;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100648
Chris Wilsonf6168e32016-10-28 13:58:55 +0100649 /* Note that we may be called from an interrupt handler on another
650 * device (e.g. nouveau signaling a fence completion causing us
651 * to submit a request, and so enable signaling). As such,
652 * we need to make sure that all other users of b->lock protect
653 * against interrupts, i.e. use spin_lock_irqsave.
654 */
655
656 /* locked by dma_fence_enable_sw_signaling() (irqsafe fence->lock) */
Chris Wilsone60a8702017-03-02 11:51:30 +0000657 GEM_BUG_ON(!irqs_disabled());
Chris Wilson67520412017-03-02 13:28:01 +0000658 lockdep_assert_held(&request->lock);
Chris Wilson754c9fd2017-02-23 07:44:14 +0000659
660 seqno = i915_gem_request_global_seqno(request);
661 if (!seqno)
Chris Wilson65e47602016-10-28 13:58:49 +0100662 return;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100663
Chris Wilsonb3850852016-07-01 17:23:26 +0100664 request->signaling.wait.tsk = b->signaler;
Chris Wilson56299fb2017-02-27 20:58:48 +0000665 request->signaling.wait.request = request;
Chris Wilson754c9fd2017-02-23 07:44:14 +0000666 request->signaling.wait.seqno = seqno;
Chris Wilsone8a261e2016-07-20 13:31:49 +0100667 i915_gem_request_get(request);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100668
Chris Wilson61d3dc72017-03-03 19:08:24 +0000669 spin_lock(&b->rb_lock);
Chris Wilson4a50d202016-07-26 12:01:50 +0100670
Chris Wilsonc81d4612016-07-01 17:23:25 +0100671 /* First add ourselves into the list of waiters, but register our
672 * bottom-half as the signaller thread. As per usual, only the oldest
673 * waiter (not just signaller) is tasked as the bottom-half waking
674 * up all completed waiters after the user interrupt.
675 *
676 * If we are the oldest waiter, enable the irq (after which we
677 * must double check that the seqno did not complete).
678 */
Chris Wilsonb3850852016-07-01 17:23:26 +0100679 wakeup = __intel_engine_add_wait(engine, &request->signaling.wait);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100680
681 /* Now insert ourselves into the retirement ordered list of signals
682 * on this engine. We track the oldest seqno as that will be the
683 * first signal to complete.
684 */
Chris Wilsonc81d4612016-07-01 17:23:25 +0100685 parent = NULL;
686 first = true;
687 p = &b->signals.rb_node;
688 while (*p) {
689 parent = *p;
Chris Wilson754c9fd2017-02-23 07:44:14 +0000690 if (i915_seqno_passed(seqno,
691 to_signaler(parent)->signaling.wait.seqno)) {
Chris Wilsonc81d4612016-07-01 17:23:25 +0100692 p = &parent->rb_right;
693 first = false;
694 } else {
695 p = &parent->rb_left;
696 }
697 }
Chris Wilsonb3850852016-07-01 17:23:26 +0100698 rb_link_node(&request->signaling.node, parent, p);
699 rb_insert_color(&request->signaling.node, &b->signals);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100700 if (first)
Chris Wilsoncced5e22017-02-23 07:44:15 +0000701 rcu_assign_pointer(b->first_signal, request);
Chris Wilsonb3850852016-07-01 17:23:26 +0100702
Chris Wilson61d3dc72017-03-03 19:08:24 +0000703 spin_unlock(&b->rb_lock);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100704
705 if (wakeup)
706 wake_up_process(b->signaler);
Chris Wilsonc81d4612016-07-01 17:23:25 +0100707}
708
Chris Wilson9eb143b2017-02-23 07:44:16 +0000709void intel_engine_cancel_signaling(struct drm_i915_gem_request *request)
710{
711 struct intel_engine_cs *engine = request->engine;
712 struct intel_breadcrumbs *b = &engine->breadcrumbs;
713
Chris Wilsone60a8702017-03-02 11:51:30 +0000714 GEM_BUG_ON(!irqs_disabled());
Chris Wilson67520412017-03-02 13:28:01 +0000715 lockdep_assert_held(&request->lock);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000716 GEM_BUG_ON(!request->signaling.wait.seqno);
717
Chris Wilson61d3dc72017-03-03 19:08:24 +0000718 spin_lock(&b->rb_lock);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000719
720 if (!RB_EMPTY_NODE(&request->signaling.node)) {
721 if (request == rcu_access_pointer(b->first_signal)) {
722 struct rb_node *rb =
723 rb_next(&request->signaling.node);
724 rcu_assign_pointer(b->first_signal,
725 rb ? to_signaler(rb) : NULL);
726 }
727 rb_erase(&request->signaling.node, &b->signals);
728 RB_CLEAR_NODE(&request->signaling.node);
729 i915_gem_request_put(request);
730 }
731
732 __intel_engine_remove_wait(engine, &request->signaling.wait);
733
Chris Wilson61d3dc72017-03-03 19:08:24 +0000734 spin_unlock(&b->rb_lock);
Chris Wilson9eb143b2017-02-23 07:44:16 +0000735
736 request->signaling.wait.seqno = 0;
737}
738
Chris Wilson688e6c72016-07-01 17:23:15 +0100739int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine)
740{
741 struct intel_breadcrumbs *b = &engine->breadcrumbs;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100742 struct task_struct *tsk;
Chris Wilson688e6c72016-07-01 17:23:15 +0100743
Chris Wilson61d3dc72017-03-03 19:08:24 +0000744 spin_lock_init(&b->rb_lock);
745 spin_lock_init(&b->irq_lock);
746
Chris Wilson688e6c72016-07-01 17:23:15 +0100747 setup_timer(&b->fake_irq,
748 intel_breadcrumbs_fake_irq,
749 (unsigned long)engine);
Chris Wilson83348ba2016-08-09 17:47:51 +0100750 setup_timer(&b->hangcheck,
751 intel_breadcrumbs_hangcheck,
752 (unsigned long)engine);
Chris Wilson688e6c72016-07-01 17:23:15 +0100753
Chris Wilsonc81d4612016-07-01 17:23:25 +0100754 /* Spawn a thread to provide a common bottom-half for all signals.
755 * As this is an asynchronous interface we cannot steal the current
756 * task for handling the bottom-half to the user interrupt, therefore
757 * we create a thread to do the coherent seqno dance after the
758 * interrupt and then signal the waitqueue (via the dma-buf/fence).
759 */
760 tsk = kthread_run(intel_breadcrumbs_signaler, engine,
761 "i915/signal:%d", engine->id);
762 if (IS_ERR(tsk))
763 return PTR_ERR(tsk);
764
765 b->signaler = tsk;
766
Chris Wilson688e6c72016-07-01 17:23:15 +0100767 return 0;
768}
769
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100770static void cancel_fake_irq(struct intel_engine_cs *engine)
771{
772 struct intel_breadcrumbs *b = &engine->breadcrumbs;
773
774 del_timer_sync(&b->hangcheck);
775 del_timer_sync(&b->fake_irq);
776 clear_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings);
777}
778
779void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine)
780{
781 struct intel_breadcrumbs *b = &engine->breadcrumbs;
782
783 cancel_fake_irq(engine);
Chris Wilson61d3dc72017-03-03 19:08:24 +0000784 spin_lock_irq(&b->irq_lock);
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100785
Chris Wilson67b807a82017-02-27 20:58:50 +0000786 if (b->irq_enabled)
787 irq_enable(engine);
788 else
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100789 irq_disable(engine);
Chris Wilson67b807a82017-02-27 20:58:50 +0000790
791 /* We set the IRQ_BREADCRUMB bit when we enable the irq presuming the
792 * GPU is active and may have already executed the MI_USER_INTERRUPT
793 * before the CPU is ready to receive. However, the engine is currently
794 * idle (we haven't started it yet), there is no possibility for a
795 * missed interrupt as we enabled the irq and so we can clear the
796 * immediate wakeup (until a real interrupt arrives for the waiter).
797 */
798 clear_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted);
799
800 if (b->irq_armed)
801 enable_fake_irq(b);
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100802
Chris Wilson61d3dc72017-03-03 19:08:24 +0000803 spin_unlock_irq(&b->irq_lock);
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100804}
805
Chris Wilson688e6c72016-07-01 17:23:15 +0100806void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine)
807{
808 struct intel_breadcrumbs *b = &engine->breadcrumbs;
809
Chris Wilson381744f2016-11-21 11:07:59 +0000810 /* The engines should be idle and all requests accounted for! */
Chris Wilson61d3dc72017-03-03 19:08:24 +0000811 WARN_ON(READ_ONCE(b->irq_wait));
Chris Wilson381744f2016-11-21 11:07:59 +0000812 WARN_ON(!RB_EMPTY_ROOT(&b->waiters));
Chris Wilsoncced5e22017-02-23 07:44:15 +0000813 WARN_ON(rcu_access_pointer(b->first_signal));
Chris Wilson381744f2016-11-21 11:07:59 +0000814 WARN_ON(!RB_EMPTY_ROOT(&b->signals));
815
Chris Wilsonc81d4612016-07-01 17:23:25 +0100816 if (!IS_ERR_OR_NULL(b->signaler))
817 kthread_stop(b->signaler);
818
Chris Wilsonad07dfc2016-10-07 07:53:26 +0100819 cancel_fake_irq(engine);
Chris Wilson688e6c72016-07-01 17:23:15 +0100820}
821
Chris Wilson9b6586a2017-02-23 07:44:08 +0000822bool intel_breadcrumbs_busy(struct intel_engine_cs *engine)
Chris Wilsonc81d4612016-07-01 17:23:25 +0100823{
Chris Wilson9b6586a2017-02-23 07:44:08 +0000824 struct intel_breadcrumbs *b = &engine->breadcrumbs;
825 bool busy = false;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100826
Chris Wilson61d3dc72017-03-03 19:08:24 +0000827 spin_lock_irq(&b->rb_lock);
Chris Wilson6a5d1db2016-11-08 14:37:19 +0000828
Chris Wilson61d3dc72017-03-03 19:08:24 +0000829 if (b->irq_wait) {
830 wake_up_process(b->irq_wait->tsk);
Chris Wilson4bd66392017-03-15 21:07:22 +0000831 busy = true;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100832 }
833
Chris Wilsoncced5e22017-02-23 07:44:15 +0000834 if (rcu_access_pointer(b->first_signal)) {
Chris Wilson9b6586a2017-02-23 07:44:08 +0000835 wake_up_process(b->signaler);
Chris Wilson4bd66392017-03-15 21:07:22 +0000836 busy = true;
Chris Wilson9b6586a2017-02-23 07:44:08 +0000837 }
838
Chris Wilson61d3dc72017-03-03 19:08:24 +0000839 spin_unlock_irq(&b->rb_lock);
Chris Wilson9b6586a2017-02-23 07:44:08 +0000840
841 return busy;
Chris Wilsonc81d4612016-07-01 17:23:25 +0100842}
Chris Wilsonf97fbf92017-02-13 17:15:14 +0000843
844#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
845#include "selftests/intel_breadcrumbs.c"
846#endif