aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-10-28 08:58:58 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2016-10-28 15:53:57 -0400
commit80b204bce8f27b52cd65839e0e6144b4452ae3de (patch)
tree081a0a9a239818514c977fe00e469e9a3d0adf42 /drivers/gpu/drm
parentf2d13290e3275df34c0cd625fbc665965af08c67 (diff)
drm/i915: Enable multiple timelines
With the infrastructure converted over to tracking multiple timelines in the GEM API whilst preserving the efficiency of using a single execution timeline internally, we can now assign a separate timeline to every context with full-ppgtt. v2: Add a comment to indicate the xfer between timelines upon submission. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20161028125858.23563-35-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h10
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c10
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c4
-rw-r--r--drivers/gpu/drm/i915/i915_gem_evict.c11
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c19
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.h4
-rw-r--r--drivers/gpu/drm/i915/i915_gem_request.c61
-rw-r--r--drivers/gpu/drm/i915/i915_gem_timeline.c1
-rw-r--r--drivers/gpu/drm/i915/i915_gem_timeline.h3
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h5
10 files changed, 77 insertions, 51 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index eacb144af29e..42a499681966 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3549,6 +3549,16 @@ static inline void i915_gem_context_put(struct i915_gem_context *ctx)
3549 kref_put(&ctx->ref, i915_gem_context_free); 3549 kref_put(&ctx->ref, i915_gem_context_free);
3550} 3550}
3551 3551
3552static inline struct intel_timeline *
3553i915_gem_context_lookup_timeline(struct i915_gem_context *ctx,
3554 struct intel_engine_cs *engine)
3555{
3556 struct i915_address_space *vm;
3557
3558 vm = ctx->ppgtt ? &ctx->ppgtt->base : &ctx->i915->ggtt.base;
3559 return &vm->timeline.engine[engine->id];
3560}
3561
3552static inline bool i915_gem_context_is_default(const struct i915_gem_context *c) 3562static inline bool i915_gem_context_is_default(const struct i915_gem_context *c)
3553{ 3563{
3554 return c->user_handle == DEFAULT_CONTEXT_HANDLE; 3564 return c->user_handle == DEFAULT_CONTEXT_HANDLE;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 8a5d20715e5f..1e5d2bf777e4 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2564,12 +2564,9 @@ i915_gem_find_active_request(struct intel_engine_cs *engine)
2564 * not need an engine->irq_seqno_barrier() before the seqno reads. 2564 * not need an engine->irq_seqno_barrier() before the seqno reads.
2565 */ 2565 */
2566 list_for_each_entry(request, &engine->timeline->requests, link) { 2566 list_for_each_entry(request, &engine->timeline->requests, link) {
2567 if (i915_gem_request_completed(request)) 2567 if (__i915_gem_request_completed(request))
2568 continue; 2568 continue;
2569 2569
2570 if (!i915_sw_fence_done(&request->submit))
2571 break;
2572
2573 return request; 2570 return request;
2574 } 2571 }
2575 2572
@@ -2597,6 +2594,7 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
2597{ 2594{
2598 struct drm_i915_gem_request *request; 2595 struct drm_i915_gem_request *request;
2599 struct i915_gem_context *incomplete_ctx; 2596 struct i915_gem_context *incomplete_ctx;
2597 struct intel_timeline *timeline;
2600 bool ring_hung; 2598 bool ring_hung;
2601 2599
2602 if (engine->irq_seqno_barrier) 2600 if (engine->irq_seqno_barrier)
@@ -2635,6 +2633,10 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
2635 list_for_each_entry_continue(request, &engine->timeline->requests, link) 2633 list_for_each_entry_continue(request, &engine->timeline->requests, link)
2636 if (request->ctx == incomplete_ctx) 2634 if (request->ctx == incomplete_ctx)
2637 reset_request(request); 2635 reset_request(request);
2636
2637 timeline = i915_gem_context_lookup_timeline(incomplete_ctx, engine);
2638 list_for_each_entry(request, &timeline->requests, link)
2639 reset_request(request);
2638} 2640}
2639 2641
2640void i915_gem_reset(struct drm_i915_private *dev_priv) 2642void i915_gem_reset(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index d3118db244c4..461aece6c5bd 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -365,9 +365,9 @@ i915_gem_create_context(struct drm_device *dev,
365 return ctx; 365 return ctx;
366 366
367 if (USES_FULL_PPGTT(dev)) { 367 if (USES_FULL_PPGTT(dev)) {
368 struct i915_hw_ppgtt *ppgtt = 368 struct i915_hw_ppgtt *ppgtt;
369 i915_ppgtt_create(to_i915(dev), file_priv);
370 369
370 ppgtt = i915_ppgtt_create(to_i915(dev), file_priv, ctx->name);
371 if (IS_ERR(ppgtt)) { 371 if (IS_ERR(ppgtt)) {
372 DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n", 372 DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n",
373 PTR_ERR(ppgtt)); 373 PTR_ERR(ppgtt));
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index 79b964152cd9..bd08814b015c 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -33,14 +33,17 @@
33#include "intel_drv.h" 33#include "intel_drv.h"
34#include "i915_trace.h" 34#include "i915_trace.h"
35 35
36static bool 36static bool ggtt_is_idle(struct drm_i915_private *dev_priv)
37gpu_is_idle(struct drm_i915_private *dev_priv)
38{ 37{
38 struct i915_ggtt *ggtt = &dev_priv->ggtt;
39 struct intel_engine_cs *engine; 39 struct intel_engine_cs *engine;
40 enum intel_engine_id id; 40 enum intel_engine_id id;
41 41
42 for_each_engine(engine, dev_priv, id) { 42 for_each_engine(engine, dev_priv, id) {
43 if (intel_engine_is_active(engine)) 43 struct intel_timeline *tl;
44
45 tl = &ggtt->base.timeline.engine[engine->id];
46 if (i915_gem_active_isset(&tl->last_request))
44 return false; 47 return false;
45 } 48 }
46 49
@@ -154,7 +157,7 @@ search_again:
154 if (!i915_is_ggtt(vm) || flags & PIN_NONBLOCK) 157 if (!i915_is_ggtt(vm) || flags & PIN_NONBLOCK)
155 return -ENOSPC; 158 return -ENOSPC;
156 159
157 if (gpu_is_idle(dev_priv)) { 160 if (ggtt_is_idle(dev_priv)) {
158 /* If we still have pending pageflip completions, drop 161 /* If we still have pending pageflip completions, drop
159 * back to userspace to give our workqueues time to 162 * back to userspace to give our workqueues time to
160 * acquire our locks and unpin the old scanouts. 163 * acquire our locks and unpin the old scanouts.
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 1b1a459e2b68..e7afad585929 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2185,8 +2185,10 @@ static int __hw_ppgtt_init(struct i915_hw_ppgtt *ppgtt,
2185} 2185}
2186 2186
2187static void i915_address_space_init(struct i915_address_space *vm, 2187static void i915_address_space_init(struct i915_address_space *vm,
2188 struct drm_i915_private *dev_priv) 2188 struct drm_i915_private *dev_priv,
2189 const char *name)
2189{ 2190{
2191 i915_gem_timeline_init(dev_priv, &vm->timeline, name);
2190 drm_mm_init(&vm->mm, vm->start, vm->total); 2192 drm_mm_init(&vm->mm, vm->start, vm->total);
2191 INIT_LIST_HEAD(&vm->active_list); 2193 INIT_LIST_HEAD(&vm->active_list);
2192 INIT_LIST_HEAD(&vm->inactive_list); 2194 INIT_LIST_HEAD(&vm->inactive_list);
@@ -2215,14 +2217,15 @@ static void gtt_write_workarounds(struct drm_device *dev)
2215 2217
2216static int i915_ppgtt_init(struct i915_hw_ppgtt *ppgtt, 2218static int i915_ppgtt_init(struct i915_hw_ppgtt *ppgtt,
2217 struct drm_i915_private *dev_priv, 2219 struct drm_i915_private *dev_priv,
2218 struct drm_i915_file_private *file_priv) 2220 struct drm_i915_file_private *file_priv,
2221 const char *name)
2219{ 2222{
2220 int ret; 2223 int ret;
2221 2224
2222 ret = __hw_ppgtt_init(ppgtt, dev_priv); 2225 ret = __hw_ppgtt_init(ppgtt, dev_priv);
2223 if (ret == 0) { 2226 if (ret == 0) {
2224 kref_init(&ppgtt->ref); 2227 kref_init(&ppgtt->ref);
2225 i915_address_space_init(&ppgtt->base, dev_priv); 2228 i915_address_space_init(&ppgtt->base, dev_priv, name);
2226 ppgtt->base.file = file_priv; 2229 ppgtt->base.file = file_priv;
2227 } 2230 }
2228 2231
@@ -2258,7 +2261,8 @@ int i915_ppgtt_init_hw(struct drm_device *dev)
2258 2261
2259struct i915_hw_ppgtt * 2262struct i915_hw_ppgtt *
2260i915_ppgtt_create(struct drm_i915_private *dev_priv, 2263i915_ppgtt_create(struct drm_i915_private *dev_priv,
2261 struct drm_i915_file_private *fpriv) 2264 struct drm_i915_file_private *fpriv,
2265 const char *name)
2262{ 2266{
2263 struct i915_hw_ppgtt *ppgtt; 2267 struct i915_hw_ppgtt *ppgtt;
2264 int ret; 2268 int ret;
@@ -2267,7 +2271,7 @@ i915_ppgtt_create(struct drm_i915_private *dev_priv,
2267 if (!ppgtt) 2271 if (!ppgtt)
2268 return ERR_PTR(-ENOMEM); 2272 return ERR_PTR(-ENOMEM);
2269 2273
2270 ret = i915_ppgtt_init(ppgtt, dev_priv, fpriv); 2274 ret = i915_ppgtt_init(ppgtt, dev_priv, fpriv, name);
2271 if (ret) { 2275 if (ret) {
2272 kfree(ppgtt); 2276 kfree(ppgtt);
2273 return ERR_PTR(ret); 2277 return ERR_PTR(ret);
@@ -2290,6 +2294,7 @@ void i915_ppgtt_release(struct kref *kref)
2290 WARN_ON(!list_empty(&ppgtt->base.inactive_list)); 2294 WARN_ON(!list_empty(&ppgtt->base.inactive_list));
2291 WARN_ON(!list_empty(&ppgtt->base.unbound_list)); 2295 WARN_ON(!list_empty(&ppgtt->base.unbound_list));
2292 2296
2297 i915_gem_timeline_fini(&ppgtt->base.timeline);
2293 list_del(&ppgtt->base.global_link); 2298 list_del(&ppgtt->base.global_link);
2294 drm_mm_takedown(&ppgtt->base.mm); 2299 drm_mm_takedown(&ppgtt->base.mm);
2295 2300
@@ -3232,11 +3237,13 @@ int i915_ggtt_init_hw(struct drm_i915_private *dev_priv)
3232 /* Subtract the guard page before address space initialization to 3237 /* Subtract the guard page before address space initialization to
3233 * shrink the range used by drm_mm. 3238 * shrink the range used by drm_mm.
3234 */ 3239 */
3240 mutex_lock(&dev_priv->drm.struct_mutex);
3235 ggtt->base.total -= PAGE_SIZE; 3241 ggtt->base.total -= PAGE_SIZE;
3236 i915_address_space_init(&ggtt->base, dev_priv); 3242 i915_address_space_init(&ggtt->base, dev_priv, "[global]");
3237 ggtt->base.total += PAGE_SIZE; 3243 ggtt->base.total += PAGE_SIZE;
3238 if (!HAS_LLC(dev_priv)) 3244 if (!HAS_LLC(dev_priv))
3239 ggtt->base.mm.color_adjust = i915_gtt_color_adjust; 3245 ggtt->base.mm.color_adjust = i915_gtt_color_adjust;
3246 mutex_unlock(&dev_priv->drm.struct_mutex);
3240 3247
3241 if (!io_mapping_init_wc(&dev_priv->ggtt.mappable, 3248 if (!io_mapping_init_wc(&dev_priv->ggtt.mappable,
3242 dev_priv->ggtt.mappable_base, 3249 dev_priv->ggtt.mappable_base,
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 9f0327e5176a..518e75b64290 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -342,6 +342,7 @@ struct i915_pml4 {
342 342
343struct i915_address_space { 343struct i915_address_space {
344 struct drm_mm mm; 344 struct drm_mm mm;
345 struct i915_gem_timeline timeline;
345 struct drm_device *dev; 346 struct drm_device *dev;
346 /* Every address space belongs to a struct file - except for the global 347 /* Every address space belongs to a struct file - except for the global
347 * GTT that is owned by the driver (and so @file is set to NULL). In 348 * GTT that is owned by the driver (and so @file is set to NULL). In
@@ -613,7 +614,8 @@ void i915_ggtt_cleanup_hw(struct drm_i915_private *dev_priv);
613int i915_ppgtt_init_hw(struct drm_device *dev); 614int i915_ppgtt_init_hw(struct drm_device *dev);
614void i915_ppgtt_release(struct kref *kref); 615void i915_ppgtt_release(struct kref *kref);
615struct i915_hw_ppgtt *i915_ppgtt_create(struct drm_i915_private *dev_priv, 616struct i915_hw_ppgtt *i915_ppgtt_create(struct drm_i915_private *dev_priv,
616 struct drm_i915_file_private *fpriv); 617 struct drm_i915_file_private *fpriv,
618 const char *name);
617static inline void i915_ppgtt_get(struct i915_hw_ppgtt *ppgtt) 619static inline void i915_ppgtt_get(struct i915_hw_ppgtt *ppgtt)
618{ 620{
619 if (ppgtt) 621 if (ppgtt)
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 7499e3b205c6..79b0046d9a57 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -34,12 +34,6 @@ static const char *i915_fence_get_driver_name(struct dma_fence *fence)
34 34
35static const char *i915_fence_get_timeline_name(struct dma_fence *fence) 35static const char *i915_fence_get_timeline_name(struct dma_fence *fence)
36{ 36{
37 /* Timelines are bound by eviction to a VM. However, since
38 * we only have a global seqno at the moment, we only have
39 * a single timeline. Note that each timeline will have
40 * multiple execution contexts (fence contexts) as we allow
41 * engines within a single timeline to execute in parallel.
42 */
43 return to_request(fence)->timeline->common->name; 37 return to_request(fence)->timeline->common->name;
44} 38}
45 39
@@ -64,18 +58,6 @@ static signed long i915_fence_wait(struct dma_fence *fence,
64 return i915_wait_request(to_request(fence), interruptible, timeout); 58 return i915_wait_request(to_request(fence), interruptible, timeout);
65} 59}
66 60
67static void i915_fence_value_str(struct dma_fence *fence, char *str, int size)
68{
69 snprintf(str, size, "%u", fence->seqno);
70}
71
72static void i915_fence_timeline_value_str(struct dma_fence *fence, char *str,
73 int size)
74{
75 snprintf(str, size, "%u",
76 intel_engine_get_seqno(to_request(fence)->engine));
77}
78
79static void i915_fence_release(struct dma_fence *fence) 61static void i915_fence_release(struct dma_fence *fence)
80{ 62{
81 struct drm_i915_gem_request *req = to_request(fence); 63 struct drm_i915_gem_request *req = to_request(fence);
@@ -90,8 +72,6 @@ const struct dma_fence_ops i915_fence_ops = {
90 .signaled = i915_fence_signaled, 72 .signaled = i915_fence_signaled,
91 .wait = i915_fence_wait, 73 .wait = i915_fence_wait,
92 .release = i915_fence_release, 74 .release = i915_fence_release,
93 .fence_value_str = i915_fence_value_str,
94 .timeline_value_str = i915_fence_timeline_value_str,
95}; 75};
96 76
97int i915_gem_request_add_to_client(struct drm_i915_gem_request *req, 77int i915_gem_request_add_to_client(struct drm_i915_gem_request *req,
@@ -147,7 +127,10 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
147 GEM_BUG_ON(!i915_gem_request_completed(request)); 127 GEM_BUG_ON(!i915_gem_request_completed(request));
148 128
149 trace_i915_gem_request_retire(request); 129 trace_i915_gem_request_retire(request);
130
131 spin_lock_irq(&request->engine->timeline->lock);
150 list_del_init(&request->link); 132 list_del_init(&request->link);
133 spin_unlock_irq(&request->engine->timeline->lock);
151 134
152 /* We know the GPU must have read the request to have 135 /* We know the GPU must have read the request to have
153 * sent us the seqno + interrupt, so use the position 136 * sent us the seqno + interrupt, so use the position
@@ -313,6 +296,12 @@ static int reserve_global_seqno(struct drm_i915_private *i915)
313 return 0; 296 return 0;
314} 297}
315 298
299static u32 __timeline_get_seqno(struct i915_gem_timeline *tl)
300{
301 /* next_seqno only incremented under a mutex */
302 return ++tl->next_seqno.counter;
303}
304
316static u32 timeline_get_seqno(struct i915_gem_timeline *tl) 305static u32 timeline_get_seqno(struct i915_gem_timeline *tl)
317{ 306{
318 return atomic_inc_return(&tl->next_seqno); 307 return atomic_inc_return(&tl->next_seqno);
@@ -325,16 +314,20 @@ submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
325 container_of(fence, typeof(*request), submit); 314 container_of(fence, typeof(*request), submit);
326 struct intel_engine_cs *engine = request->engine; 315 struct intel_engine_cs *engine = request->engine;
327 struct intel_timeline *timeline; 316 struct intel_timeline *timeline;
317 unsigned long flags;
328 u32 seqno; 318 u32 seqno;
329 319
330 if (state != FENCE_COMPLETE) 320 if (state != FENCE_COMPLETE)
331 return NOTIFY_DONE; 321 return NOTIFY_DONE;
332 322
333 /* Will be called from irq-context when using foreign DMA fences */ 323 /* Transfer from per-context onto the global per-engine timeline */
324 timeline = engine->timeline;
325 GEM_BUG_ON(timeline == request->timeline);
334 326
335 timeline = request->timeline; 327 /* Will be called from irq-context when using foreign DMA fences */
328 spin_lock_irqsave(&timeline->lock, flags);
336 329
337 seqno = request->fence.seqno; 330 seqno = timeline_get_seqno(timeline->common);
338 GEM_BUG_ON(!seqno); 331 GEM_BUG_ON(!seqno);
339 GEM_BUG_ON(i915_seqno_passed(intel_engine_get_seqno(engine), seqno)); 332 GEM_BUG_ON(i915_seqno_passed(intel_engine_get_seqno(engine), seqno));
340 333
@@ -354,6 +347,12 @@ submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
354 request->ring->vaddr + request->postfix); 347 request->ring->vaddr + request->postfix);
355 engine->submit_request(request); 348 engine->submit_request(request);
356 349
350 spin_lock_nested(&request->timeline->lock, SINGLE_DEPTH_NESTING);
351 list_move_tail(&request->link, &timeline->requests);
352 spin_unlock(&request->timeline->lock);
353
354 spin_unlock_irqrestore(&timeline->lock, flags);
355
357 return NOTIFY_DONE; 356 return NOTIFY_DONE;
358} 357}
359 358
@@ -394,7 +393,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
394 /* Move the oldest request to the slab-cache (if not in use!) */ 393 /* Move the oldest request to the slab-cache (if not in use!) */
395 req = list_first_entry_or_null(&engine->timeline->requests, 394 req = list_first_entry_or_null(&engine->timeline->requests,
396 typeof(*req), link); 395 typeof(*req), link);
397 if (req && i915_gem_request_completed(req)) 396 if (req && __i915_gem_request_completed(req))
398 i915_gem_request_retire(req); 397 i915_gem_request_retire(req);
399 398
400 /* Beware: Dragons be flying overhead. 399 /* Beware: Dragons be flying overhead.
@@ -431,14 +430,15 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
431 goto err_unreserve; 430 goto err_unreserve;
432 } 431 }
433 432
434 req->timeline = engine->timeline; 433 req->timeline = i915_gem_context_lookup_timeline(ctx, engine);
434 GEM_BUG_ON(req->timeline == engine->timeline);
435 435
436 spin_lock_init(&req->lock); 436 spin_lock_init(&req->lock);
437 dma_fence_init(&req->fence, 437 dma_fence_init(&req->fence,
438 &i915_fence_ops, 438 &i915_fence_ops,
439 &req->lock, 439 &req->lock,
440 req->timeline->fence_context, 440 req->timeline->fence_context,
441 timeline_get_seqno(req->timeline->common)); 441 __timeline_get_seqno(req->timeline->common));
442 442
443 i915_sw_fence_init(&req->submit, submit_notify); 443 i915_sw_fence_init(&req->submit, submit_notify);
444 444
@@ -722,9 +722,14 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
722 i915_sw_fence_await_sw_fence(&request->submit, &prev->submit, 722 i915_sw_fence_await_sw_fence(&request->submit, &prev->submit,
723 &request->submitq); 723 &request->submitq);
724 724
725 spin_lock_irq(&timeline->lock);
725 list_add_tail(&request->link, &timeline->requests); 726 list_add_tail(&request->link, &timeline->requests);
727 spin_unlock_irq(&timeline->lock);
728
729 GEM_BUG_ON(i915_seqno_passed(timeline->last_submitted_seqno,
730 request->fence.seqno));
726 731
727 timeline->last_pending_seqno = request->fence.seqno; 732 timeline->last_submitted_seqno = request->fence.seqno;
728 i915_gem_active_set(&timeline->last_request, request); 733 i915_gem_active_set(&timeline->last_request, request);
729 734
730 list_add_tail(&request->ring_link, &ring->request_list); 735 list_add_tail(&request->ring_link, &ring->request_list);
@@ -991,7 +996,7 @@ static void engine_retire_requests(struct intel_engine_cs *engine)
991 996
992 list_for_each_entry_safe(request, next, 997 list_for_each_entry_safe(request, next,
993 &engine->timeline->requests, link) { 998 &engine->timeline->requests, link) {
994 if (!i915_gem_request_completed(request)) 999 if (!__i915_gem_request_completed(request))
995 return; 1000 return;
996 1001
997 i915_gem_request_retire(request); 1002 i915_gem_request_retire(request);
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.c b/drivers/gpu/drm/i915/i915_gem_timeline.c
index a1bd03d10852..fc8f13a79f8f 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.c
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.c
@@ -48,6 +48,7 @@ int i915_gem_timeline_init(struct drm_i915_private *i915,
48 tl->fence_context = fences++; 48 tl->fence_context = fences++;
49 tl->common = timeline; 49 tl->common = timeline;
50 50
51 spin_lock_init(&tl->lock);
51 init_request_active(&tl->last_request, NULL); 52 init_request_active(&tl->last_request, NULL);
52 INIT_LIST_HEAD(&tl->requests); 53 INIT_LIST_HEAD(&tl->requests);
53 } 54 }
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_gem_timeline.h
index 18e603980dd9..f2bf7b1d49a1 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.h
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.h
@@ -34,7 +34,8 @@ struct i915_gem_timeline;
34struct intel_timeline { 34struct intel_timeline {
35 u64 fence_context; 35 u64 fence_context;
36 u32 last_submitted_seqno; 36 u32 last_submitted_seqno;
37 u32 last_pending_seqno; 37
38 spinlock_t lock;
38 39
39 /** 40 /**
40 * List of breadcrumbs associated with GPU requests currently 41 * List of breadcrumbs associated with GPU requests currently
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index d16c74ae8f54..43f61aa24ed7 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -569,9 +569,4 @@ void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine);
569unsigned int intel_kick_waiters(struct drm_i915_private *i915); 569unsigned int intel_kick_waiters(struct drm_i915_private *i915);
570unsigned int intel_kick_signalers(struct drm_i915_private *i915); 570unsigned int intel_kick_signalers(struct drm_i915_private *i915);
571 571
572static inline bool intel_engine_is_active(struct intel_engine_cs *engine)
573{
574 return i915_gem_active_isset(&engine->timeline->last_request);
575}
576
577#endif /* _INTEL_RINGBUFFER_H_ */ 572#endif /* _INTEL_RINGBUFFER_H_ */