Skip to content

Commit 7810858

Browse files
committed
drm/i915: Add timeline barrier support
Timeline barrier allows serialization between different timelines. After calling i915_timeline_set_barrier with a request, all following submissions on this timeline will be set up as depending on this request, or barrier. Once the barrier has been completed it automatically gets cleared and things continue as normal. This facility will be used by the upcoming context SSEU code. v2: * Assert barrier has been retired on timeline_fini. (Chris Wilson) * Fix mock_timeline. v3: * Improved comment language. (Chris Wilson) v4: * Maintain ordering with previous barriers set on the timeline. v5: * Rebase. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Suggested-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: https://patchwork.freedesktop.org/patch/msgid/20190205095032.22673-3-tvrtko.ursulin@linux.intel.com
1 parent ec431ea commit 7810858

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

drivers/gpu/drm/i915/i915_request.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,19 @@ i915_request_alloc_slow(struct intel_context *ce)
526526
return kmem_cache_alloc(ce->gem_context->i915->requests, GFP_KERNEL);
527527
}
528528

529+
static int add_barrier(struct i915_request *rq, struct i915_gem_active *active)
530+
{
531+
struct i915_request *barrier =
532+
i915_gem_active_raw(active, &rq->i915->drm.struct_mutex);
533+
534+
return barrier ? i915_request_await_dma_fence(rq, &barrier->fence) : 0;
535+
}
536+
537+
static int add_timeline_barrier(struct i915_request *rq)
538+
{
539+
return add_barrier(rq, &rq->timeline->barrier);
540+
}
541+
529542
/**
530543
* i915_request_alloc - allocate a request structure
531544
*
@@ -668,6 +681,10 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
668681
*/
669682
rq->head = rq->ring->emit;
670683

684+
ret = add_timeline_barrier(rq);
685+
if (ret)
686+
goto err_unwind;
687+
671688
ret = engine->request_alloc(rq);
672689
if (ret)
673690
goto err_unwind;

drivers/gpu/drm/i915/i915_timeline.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ int i915_timeline_init(struct drm_i915_private *i915,
163163

164164
spin_lock_init(&timeline->lock);
165165

166+
init_request_active(&timeline->barrier, NULL);
166167
init_request_active(&timeline->last_request, NULL);
167168
INIT_LIST_HEAD(&timeline->requests);
168169

@@ -235,6 +236,7 @@ void i915_timeline_fini(struct i915_timeline *timeline)
235236
{
236237
GEM_BUG_ON(timeline->pin_count);
237238
GEM_BUG_ON(!list_empty(&timeline->requests));
239+
GEM_BUG_ON(i915_gem_active_isset(&timeline->barrier));
238240

239241
i915_syncmap_free(&timeline->sync);
240242
hwsp_free(timeline);
@@ -309,6 +311,25 @@ void i915_timeline_unpin(struct i915_timeline *tl)
309311
__i915_vma_unpin(tl->hwsp_ggtt);
310312
}
311313

314+
int i915_timeline_set_barrier(struct i915_timeline *tl, struct i915_request *rq)
315+
{
316+
struct i915_request *old;
317+
int err;
318+
319+
lockdep_assert_held(&rq->i915->drm.struct_mutex);
320+
321+
/* Must maintain ordering wrt existing barriers */
322+
old = i915_gem_active_raw(&tl->barrier, &rq->i915->drm.struct_mutex);
323+
if (old) {
324+
err = i915_request_await_dma_fence(rq, &old->fence);
325+
if (err)
326+
return err;
327+
}
328+
329+
i915_gem_active_set(&tl->barrier, rq);
330+
return 0;
331+
}
332+
312333
void __i915_timeline_free(struct kref *kref)
313334
{
314335
struct i915_timeline *timeline =

drivers/gpu/drm/i915/i915_timeline.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,16 @@ struct i915_timeline {
7474
*/
7575
struct i915_syncmap *sync;
7676

77+
/**
78+
* Barrier provides the ability to serialize ordering between different
79+
* timelines.
80+
*
81+
* Users can call i915_timeline_set_barrier which will make all
82+
* subsequent submissions to this timeline be executed only after the
83+
* barrier has been completed.
84+
*/
85+
struct i915_gem_active barrier;
86+
7787
struct list_head link;
7888
const char *name;
7989
struct drm_i915_private *i915;
@@ -155,4 +165,16 @@ void i915_timelines_init(struct drm_i915_private *i915);
155165
void i915_timelines_park(struct drm_i915_private *i915);
156166
void i915_timelines_fini(struct drm_i915_private *i915);
157167

168+
/**
169+
* i915_timeline_set_barrier - orders submission between different timelines
170+
* @timeline: timeline to set the barrier on
171+
* @rq: request after which new submissions can proceed
172+
*
173+
* Sets the passed in request as the serialization point for all subsequent
174+
* submissions on @timeline. Subsequent requests will not be submitted to GPU
175+
* until the barrier has been completed.
176+
*/
177+
int i915_timeline_set_barrier(struct i915_timeline *timeline,
178+
struct i915_request *rq);
179+
158180
#endif

drivers/gpu/drm/i915/selftests/mock_timeline.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ void mock_timeline_init(struct i915_timeline *timeline, u64 context)
1515

1616
spin_lock_init(&timeline->lock);
1717

18+
init_request_active(&timeline->barrier, NULL);
1819
init_request_active(&timeline->last_request, NULL);
1920
INIT_LIST_HEAD(&timeline->requests);
2021

0 commit comments

Comments
 (0)