[PATCH 9/9] drm/i915: Lift timeline into intel_context
Chris Wilson
chris at chris-wilson.co.uk
Sat Aug 3 15:53:53 UTC 2019
Move the timeline from being inside the intel_ring to intel_context
itself. This saves much pointer dancing and makes the relations of the
context to its timeline much clearer.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
drivers/gpu/drm/i915/gt/intel_context.c | 19 ++++--
drivers/gpu/drm/i915/gt/intel_context.h | 8 +--
drivers/gpu/drm/i915/gt/intel_context_types.h | 1 +
drivers/gpu/drm/i915/gt/intel_engine.h | 4 +-
drivers/gpu/drm/i915/gt/intel_engine_cs.c | 1 -
drivers/gpu/drm/i915/gt/intel_engine_types.h | 8 ++-
drivers/gpu/drm/i915/gt/intel_lrc.c | 34 ++++------
drivers/gpu/drm/i915/gt/intel_ringbuffer.c | 63 +++++++++----------
drivers/gpu/drm/i915/gt/mock_engine.c | 49 ++++++---------
drivers/gpu/drm/i915/gt/selftest_context.c | 2 +-
drivers/gpu/drm/i915/i915_active.c | 6 +-
drivers/gpu/drm/i915/i915_request.c | 4 +-
12 files changed, 92 insertions(+), 107 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
index e0181b09282c..a2f1f1a079b3 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -60,7 +60,7 @@ int __intel_context_do_pin(struct intel_context *ce)
goto err;
GEM_TRACE("%s context:%llx pin ring:{head:%04x, tail:%04x}\n",
- ce->engine->name, ce->ring->timeline->fence_context,
+ ce->engine->name, ce->timeline->fence_context,
ce->ring->head, ce->ring->tail);
i915_gem_context_get(ce->gem_context); /* for ctx->ppgtt */
@@ -90,7 +90,7 @@ void intel_context_unpin(struct intel_context *ce)
if (likely(atomic_dec_and_test(&ce->pin_count))) {
GEM_TRACE("%s context:%llx retire\n",
- ce->engine->name, ce->ring->timeline->fence_context);
+ ce->engine->name, ce->timeline->fence_context);
ce->ops->unpin(ce);
@@ -135,11 +135,12 @@ static void __intel_context_retire(struct i915_active *active)
struct intel_context *ce = container_of(active, typeof(*ce), active);
GEM_TRACE("%s context:%llx retire\n",
- ce->engine->name, ce->ring->timeline->fence_context);
+ ce->engine->name, ce->timeline->fence_context);
if (ce->state)
__context_unpin_state(ce->state);
+ intel_timeline_unpin(ce->timeline);
intel_ring_unpin(ce->ring);
intel_context_put(ce);
}
@@ -155,15 +156,21 @@ static int __intel_context_active(struct i915_active *active)
if (err)
goto err_put;
+ err = intel_timeline_pin(ce->timeline);
+ if (err)
+ goto err_ring;
+
if (!ce->state)
return 0;
err = __context_pin_state(ce->state);
if (err)
- goto err_ring;
+ goto err_timeline;
return 0;
+err_timeline:
+ intel_timeline_unpin(ce->timeline);
err_ring:
intel_ring_unpin(ce->ring);
err_put:
@@ -210,6 +217,8 @@ intel_context_init(struct intel_context *ce,
ce->gem_context = ctx;
ce->vm = i915_vm_get(ctx->vm ?: &engine->gt->ggtt->vm);
+ if (ctx->timeline)
+ ce->timeline = intel_timeline_get(ctx->timeline);
ce->engine = engine;
ce->ops = engine->cops;
@@ -271,7 +280,7 @@ void intel_context_exit_engine(struct intel_context *ce)
int intel_context_prepare_remote_request(struct intel_context *ce,
struct i915_request *rq)
{
- struct intel_timeline *tl = ce->ring->timeline;
+ struct intel_timeline *tl = ce->timeline;
int err;
/* Only suitable for use in remotely modifying this context */
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
index 13f28dd316bc..9fa8b588f18e 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -120,15 +120,15 @@ static inline void intel_context_put(struct intel_context *ce)
static inline int __must_check
intel_context_timeline_lock(struct intel_context *ce)
- __acquires(&ce->ring->timeline->mutex)
+ __acquires(&ce->timeline->mutex)
{
- return mutex_lock_interruptible(&ce->ring->timeline->mutex);
+ return mutex_lock_interruptible(&ce->timeline->mutex);
}
static inline void intel_context_timeline_unlock(struct intel_context *ce)
- __releases(&ce->ring->timeline->mutex)
+ __releases(&ce->timeline->mutex)
{
- mutex_unlock(&ce->ring->timeline->mutex);
+ mutex_unlock(&ce->timeline->mutex);
}
int intel_context_prepare_remote_request(struct intel_context *ce,
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 68a7e979b1a9..1ce7e8d57a4e 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -51,6 +51,7 @@ struct intel_context {
struct i915_vma *state;
struct intel_ring *ring;
+ struct intel_timeline *timeline;
u32 *lrc_reg_state;
u64 lrc_desc;
diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h
index 01e8c8a6328a..cb22067a1a68 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -197,9 +197,7 @@ intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value)
#define CNL_HWS_CSB_WRITE_INDEX 0x2f
struct intel_ring *
-intel_engine_create_ring(struct intel_engine_cs *engine,
- struct intel_timeline *timeline,
- int size);
+intel_engine_create_ring(struct intel_engine_cs *engine, int size);
int intel_ring_pin(struct intel_ring *ring);
void intel_ring_reset(struct intel_ring *ring, u32 tail);
unsigned int intel_ring_update_space(struct intel_ring *ring);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 2b2a1c93f8a4..2d8a6722d14a 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -703,7 +703,6 @@ static int measure_breadcrumb_dw(struct intel_engine_cs *engine)
goto out_frame;
INIT_LIST_HEAD(&frame->ring.request_list);
- frame->ring.timeline = &frame->timeline;
frame->ring.vaddr = frame->cs;
frame->ring.size = sizeof(frame->cs);
frame->ring.effective_size = frame->ring.size;
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 49258884cf11..5177587e1705 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -69,7 +69,6 @@ struct intel_ring {
struct i915_vma *vma;
void *vaddr;
- struct intel_timeline *timeline;
struct list_head request_list;
struct list_head active_link;
@@ -283,8 +282,6 @@ struct intel_engine_cs {
struct intel_sseu sseu;
- struct intel_ring *buffer;
-
struct {
spinlock_t lock;
struct list_head requests;
@@ -303,6 +300,11 @@ struct intel_engine_cs {
struct drm_i915_gem_object *default_state;
void *pinned_default_state;
+ struct {
+ struct intel_ring *ring;
+ struct intel_timeline *timeline;
+ } legacy;
+
/* Rather than have every client wait upon all user interrupts,
* with the herd waking after every interrupt and each doing the
* heavyweight seqno dance, we delegate the task (of being the
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 5e113ddbe273..004cb49b1b20 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1555,6 +1555,7 @@ static void execlists_submit_request(struct i915_request *request)
static void __execlists_context_fini(struct intel_context *ce)
{
+ intel_timeline_put(ce->timeline);
intel_ring_put(ce->ring);
i915_vma_put(ce->state);
}
@@ -2812,9 +2813,6 @@ logical_ring_default_irqs(struct intel_engine_cs *engine)
int intel_execlists_submission_setup(struct intel_engine_cs *engine)
{
- /* Intentionally left blank. */
- engine->buffer = NULL;
-
tasklet_init(&engine->execlists.tasklet,
execlists_submission_tasklet, (unsigned long)engine);
timer_setup(&engine->execlists.timer, execlists_submission_timer, 0);
@@ -3062,23 +3060,13 @@ populate_lr_context(struct intel_context *ce,
return ret;
}
-static struct intel_timeline *
-get_timeline(struct i915_gem_context *ctx, struct intel_gt *gt)
-{
- if (ctx->timeline)
- return intel_timeline_get(ctx->timeline);
- else
- return intel_timeline_create(gt, NULL);
-}
-
static int execlists_context_deferred_alloc(struct intel_context *ce,
struct intel_engine_cs *engine)
{
struct drm_i915_gem_object *ctx_obj;
+ struct intel_ring *ring;
struct i915_vma *vma;
u32 context_size;
- struct intel_ring *ring;
- struct intel_timeline *timeline;
int ret;
if (ce->state)
@@ -3102,15 +3090,19 @@ static int execlists_context_deferred_alloc(struct intel_context *ce,
goto error_deref_obj;
}
- timeline = get_timeline(ce->gem_context, engine->gt);
- if (IS_ERR(timeline)) {
- ret = PTR_ERR(timeline);
- goto error_deref_obj;
+ if (!ce->timeline) {
+ struct intel_timeline *tl;
+
+ tl = intel_timeline_create(engine->gt, NULL);
+ if (IS_ERR(tl)) {
+ ret = PTR_ERR(tl);
+ goto error_deref_obj;
+ }
+
+ ce->timeline = tl;
}
- ring = intel_engine_create_ring(engine, timeline,
- (unsigned long)ce->ring);
- intel_timeline_put(timeline);
+ ring = intel_engine_create_ring(engine, (unsigned long)ce->ring);
if (IS_ERR(ring)) {
ret = PTR_ERR(ring);
goto error_deref_obj;
diff --git a/drivers/gpu/drm/i915/gt/intel_ringbuffer.c b/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
index f5b563531003..fd7f936ce854 100644
--- a/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
@@ -636,7 +636,7 @@ static bool stop_ring(struct intel_engine_cs *engine)
static int xcs_resume(struct intel_engine_cs *engine)
{
struct drm_i915_private *dev_priv = engine->i915;
- struct intel_ring *ring = engine->buffer;
+ struct intel_ring *ring = engine->legacy.ring;
int ret = 0;
GEM_TRACE("%s: ring:{HEAD:%04x, TAIL:%04x}\n",
@@ -832,12 +832,12 @@ static void reset_ring(struct intel_engine_cs *engine, bool stalled)
*/
__i915_request_reset(rq, stalled);
- GEM_BUG_ON(rq->ring != engine->buffer);
+ GEM_BUG_ON(rq->ring != engine->legacy.ring);
head = rq->head;
} else {
- head = engine->buffer->tail;
+ head = engine->legacy.ring->tail;
}
- engine->buffer->head = intel_ring_wrap(engine->buffer, head);
+ engine->legacy.ring->head = intel_ring_wrap(engine->legacy.ring, head);
spin_unlock_irqrestore(&engine->active.lock, flags);
}
@@ -1192,10 +1192,6 @@ int intel_ring_pin(struct intel_ring *ring)
if (atomic_fetch_inc(&ring->pin_count))
return 0;
- ret = intel_timeline_pin(ring->timeline);
- if (ret)
- goto err_unpin;
-
flags = PIN_GLOBAL;
/* Ring wraparound at offset 0 sometimes hangs. No idea why. */
@@ -1208,7 +1204,7 @@ int intel_ring_pin(struct intel_ring *ring)
ret = i915_vma_pin(vma, 0, 0, flags);
if (unlikely(ret))
- goto err_timeline;
+ goto err_unpin;
if (i915_vma_is_map_and_fenceable(vma))
addr = (void __force *)i915_vma_pin_iomap(vma);
@@ -1225,13 +1221,10 @@ int intel_ring_pin(struct intel_ring *ring)
GEM_BUG_ON(ring->vaddr);
ring->vaddr = addr;
- GEM_TRACE("ring:%llx pin\n", ring->timeline->fence_context);
return 0;
err_ring:
i915_vma_unpin(vma);
-err_timeline:
- intel_timeline_unpin(ring->timeline);
err_unpin:
atomic_dec(&ring->pin_count);
return ret;
@@ -1254,8 +1247,6 @@ void intel_ring_unpin(struct intel_ring *ring)
if (!atomic_dec_and_test(&ring->pin_count))
return;
- GEM_TRACE("ring:%llx unpin\n", ring->timeline->fence_context);
-
/* Discard any unused bytes beyond that submitted to hw. */
intel_ring_reset(ring, ring->tail);
@@ -1270,8 +1261,6 @@ void intel_ring_unpin(struct intel_ring *ring)
i915_vma_unpin(vma);
i915_vma_make_purgeable(vma);
-
- intel_timeline_unpin(ring->timeline);
}
static struct i915_vma *create_ring_vma(struct i915_ggtt *ggtt, int size)
@@ -1306,9 +1295,7 @@ static struct i915_vma *create_ring_vma(struct i915_ggtt *ggtt, int size)
}
struct intel_ring *
-intel_engine_create_ring(struct intel_engine_cs *engine,
- struct intel_timeline *timeline,
- int size)
+intel_engine_create_ring(struct intel_engine_cs *engine, int size)
{
struct drm_i915_private *i915 = engine->i915;
struct intel_ring *ring;
@@ -1323,7 +1310,6 @@ intel_engine_create_ring(struct intel_engine_cs *engine,
kref_init(&ring->ref);
INIT_LIST_HEAD(&ring->request_list);
- ring->timeline = intel_timeline_get(timeline);
ring->size = size;
/* Workaround an erratum on the i830 which causes a hang if
@@ -1353,7 +1339,6 @@ void intel_ring_free(struct kref *ref)
i915_vma_close(ring->vma);
i915_vma_put(ring->vma);
- intel_timeline_put(ring->timeline);
kfree(ring);
}
@@ -1486,8 +1471,9 @@ static int ring_context_pin(struct intel_context *ce)
int err;
/* One ringbuffer to rule them all */
- GEM_BUG_ON(!engine->buffer);
- ce->ring = engine->buffer;
+ GEM_BUG_ON(!engine->legacy.ring);
+ ce->ring = engine->legacy.ring;
+ ce->timeline = engine->legacy.timeline;
if (!ce->state && engine->context_size) {
struct i915_vma *vma;
@@ -2156,8 +2142,11 @@ static void ring_destroy(struct intel_engine_cs *engine)
intel_engine_cleanup_common(engine);
- intel_ring_unpin(engine->buffer);
- intel_ring_put(engine->buffer);
+ intel_ring_unpin(engine->legacy.ring);
+ intel_ring_put(engine->legacy.ring);
+
+ intel_timeline_unpin(engine->legacy.timeline);
+ intel_timeline_put(engine->legacy.timeline);
kfree(engine);
}
@@ -2341,32 +2330,40 @@ int intel_ring_submission_init(struct intel_engine_cs *engine)
}
GEM_BUG_ON(timeline->has_initial_breadcrumb);
- ring = intel_engine_create_ring(engine, timeline, SZ_16K);
- intel_timeline_put(timeline);
+ err = intel_timeline_pin(timeline);
+ if (err)
+ goto err_timeline;
+
+ ring = intel_engine_create_ring(engine, SZ_16K);
if (IS_ERR(ring)) {
err = PTR_ERR(ring);
- goto err;
+ goto err_timeline_unpin;
}
err = intel_ring_pin(ring);
if (err)
goto err_ring;
- GEM_BUG_ON(engine->buffer);
- engine->buffer = ring;
+ GEM_BUG_ON(engine->legacy.ring);
+ engine->legacy.ring = ring;
+ engine->legacy.timeline = timeline;
err = intel_engine_init_common(engine);
if (err)
- goto err_unpin;
+ goto err_ring_unpin;
- GEM_BUG_ON(ring->timeline->hwsp_ggtt != engine->status_page.vma);
+ GEM_BUG_ON(timeline->hwsp_ggtt != engine->status_page.vma);
return 0;
-err_unpin:
+err_ring_unpin:
intel_ring_unpin(ring);
err_ring:
intel_ring_put(ring);
+err_timeline_unpin:
+ intel_timeline_unpin(timeline);
+err_timeline:
+ intel_timeline_put(timeline);
err:
intel_engine_cleanup_common(engine);
return err;
diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c
index bf2dc1142f3c..ff72a37fbf08 100644
--- a/drivers/gpu/drm/i915/gt/mock_engine.c
+++ b/drivers/gpu/drm/i915/gt/mock_engine.c
@@ -31,11 +31,6 @@
#include "mock_engine.h"
#include "selftests/mock_request.h"
-struct mock_ring {
- struct intel_ring base;
- struct intel_timeline timeline;
-};
-
static void mock_timeline_pin(struct intel_timeline *tl)
{
tl->pin_count++;
@@ -50,36 +45,22 @@ static void mock_timeline_unpin(struct intel_timeline *tl)
static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
{
const unsigned long sz = PAGE_SIZE / 2;
- struct mock_ring *ring;
+ struct intel_ring *ring;
ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
if (!ring)
return NULL;
- if (intel_timeline_init(&ring->timeline, engine->gt, NULL)) {
- kfree(ring);
- return NULL;
- }
-
- kref_init(&ring->base.ref);
- ring->base.size = sz;
- ring->base.effective_size = sz;
- ring->base.vaddr = (void *)(ring + 1);
- ring->base.timeline = &ring->timeline;
- atomic_set(&ring->base.pin_count, 1);
+ kref_init(&ring->ref);
+ ring->size = sz;
+ ring->effective_size = sz;
+ ring->vaddr = (void *)(ring + 1);
+ atomic_set(&ring->pin_count, 1);
- INIT_LIST_HEAD(&ring->base.request_list);
- intel_ring_update_space(&ring->base);
+ INIT_LIST_HEAD(&ring->request_list);
+ intel_ring_update_space(ring);
- return &ring->base;
-}
-
-static void mock_ring_free(struct intel_ring *base)
-{
- struct mock_ring *ring = container_of(base, typeof(*ring), base);
-
- intel_timeline_fini(&ring->timeline);
- kfree(ring);
+ return ring;
}
static struct i915_request *first_request(struct mock_engine *engine)
@@ -130,7 +111,7 @@ static void hw_delay_complete(struct timer_list *t)
static void mock_context_unpin(struct intel_context *ce)
{
- mock_timeline_unpin(ce->ring->timeline);
+ mock_timeline_unpin(ce->timeline);
}
static bool has_ring(struct intel_context *ce)
@@ -145,7 +126,7 @@ static void mock_context_destroy(struct kref *ref)
GEM_BUG_ON(intel_context_is_pinned(ce));
if (has_ring(ce))
- mock_ring_free(ce->ring);
+ kfree(ce->ring);
intel_context_fini(ce);
intel_context_free(ce);
@@ -161,11 +142,17 @@ static int mock_context_pin(struct intel_context *ce)
return -ENOMEM;
}
+ if (!ce->timeline) {
+ ce->timeline = intel_timeline_create(ce->engine->gt, NULL);
+ if (IS_ERR(ce->timeline))
+ return PTR_ERR(ce->timeline);
+ }
+
ret = intel_context_active_acquire(ce);
if (ret)
return ret;
- mock_timeline_pin(ce->ring->timeline);
+ mock_timeline_pin(ce->timeline);
return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/selftest_context.c b/drivers/gpu/drm/i915/gt/selftest_context.c
index d39b5594cb02..9d3cdcc67b4d 100644
--- a/drivers/gpu/drm/i915/gt/selftest_context.c
+++ b/drivers/gpu/drm/i915/gt/selftest_context.c
@@ -32,7 +32,7 @@ static int request_sync(struct i915_request *rq)
static int context_sync(struct intel_context *ce)
{
- struct intel_timeline *tl = ce->ring->timeline;
+ struct intel_timeline *tl = ce->timeline;
int err = 0;
do {
diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c
index 1e09722b5317..7698fcaa648a 100644
--- a/drivers/gpu/drm/i915/i915_active.c
+++ b/drivers/gpu/drm/i915/i915_active.c
@@ -246,7 +246,7 @@ static bool __active_del_barrier(struct i915_active *ref,
struct llist_node *head = NULL, *tail = NULL;
struct llist_node *pos, *next;
- GEM_BUG_ON(node->timeline != engine->kernel_context->ring->timeline->fence_context);
+ GEM_BUG_ON(node->timeline != engine->kernel_context->timeline->fence_context);
/*
* Rebuild the llist excluding our node. We may perform this
@@ -568,7 +568,7 @@ int i915_active_acquire_preallocate_barrier(struct i915_active *ref,
* i915_active_acquire_barrier()
*/
for_each_engine_masked(engine, i915, mask, tmp) {
- u64 idx = engine->kernel_context->ring->timeline->fence_context;
+ u64 idx = engine->kernel_context->timeline->fence_context;
struct active_node *node;
node = reuse_idle_barrier(ref, idx);
@@ -665,7 +665,7 @@ void i915_request_add_active_barriers(struct i915_request *rq)
struct llist_node *node, *next;
GEM_BUG_ON(intel_engine_is_virtual(engine));
- GEM_BUG_ON(rq->timeline != engine->kernel_context->ring->timeline);
+ GEM_BUG_ON(rq->timeline != engine->kernel_context->timeline);
/*
* Attach the list of proto-fences to the in-flight request such
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 81094f250bdb..bee4afddabb2 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -607,7 +607,7 @@ request_alloc_slow(struct intel_context *ce, gfp_t gfp)
struct i915_request *
__i915_request_create(struct intel_context *ce, gfp_t gfp)
{
- struct intel_timeline *tl = ce->ring->timeline;
+ struct intel_timeline *tl = ce->timeline;
struct i915_request *rq;
u32 seqno;
int ret;
@@ -759,7 +759,7 @@ i915_request_create(struct intel_context *ce)
goto err_unlock;
/* Check that we do not interrupt ourselves with a new request */
- rq->cookie = lockdep_pin_lock(&ce->ring->timeline->mutex);
+ rq->cookie = lockdep_pin_lock(&ce->timeline->mutex);
return rq;
--
2.23.0.rc1
More information about the Intel-gfx-trybot
mailing list