[PATCH 28/30] ctx-acq
Chris Wilson
chris at chris-wilson.co.uk
Thu Jul 9 02:56:24 UTC 2020
---
drivers/gpu/drm/i915/gt/intel_context.c | 108 ++++++++++++++--
drivers/gpu/drm/i915/gt/intel_ring.c | 17 ++-
drivers/gpu/drm/i915/gt/intel_ring.h | 5 +-
.../gpu/drm/i915/gt/intel_ring_submission.c | 117 ++++++++++++------
drivers/gpu/drm/i915/gt/intel_timeline.c | 14 ++-
drivers/gpu/drm/i915/gt/intel_timeline.h | 10 +-
drivers/gpu/drm/i915/gt/mock_engine.c | 2 +
drivers/gpu/drm/i915/gt/selftest_timeline.c | 30 ++++-
8 files changed, 237 insertions(+), 66 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
index 52db2bde44a3..2f1606365f63 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -6,6 +6,7 @@
#include "gem/i915_gem_context.h"
#include "gem/i915_gem_pm.h"
+#include "mm/i915_acquire_ctx.h"
#include "i915_drv.h"
#include "i915_globals.h"
@@ -93,6 +94,27 @@ static void intel_context_active_release(struct intel_context *ce)
i915_active_release(&ce->active);
}
+static int __intel_context_sync(struct intel_context *ce)
+{
+ int err;
+
+ err = i915_vma_wait_for_bind(ce->ring->vma);
+ if (err)
+ return err;
+
+ err = i915_vma_wait_for_bind(ce->timeline->hwsp_ggtt);
+ if (err)
+ return err;
+
+ if (ce->state) {
+ err = i915_vma_wait_for_bind(ce->state);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
int __intel_context_do_pin(struct intel_context *ce)
{
int err;
@@ -118,6 +140,10 @@ int __intel_context_do_pin(struct intel_context *ce)
}
if (likely(!atomic_add_unless(&ce->pin_count, 1, 0))) {
+ err = __intel_context_sync(ce);
+ if (unlikely(err))
+ goto out_unlock;
+
err = intel_context_active_acquire(ce);
if (unlikely(err))
goto out_unlock;
@@ -166,12 +192,12 @@ void intel_context_unpin(struct intel_context *ce)
intel_context_put(ce);
}
-static int __context_pin_state(struct i915_vma *vma)
+static int __context_active_locked(struct i915_vma *vma)
{
unsigned int bias = i915_ggtt_pin_bias(vma) | PIN_OFFSET_BIAS;
int err;
- err = i915_ggtt_pin(vma, 0, bias | PIN_HIGH);
+ err = i915_ggtt_pin_locked(vma, 0, bias | PIN_HIGH);
if (err)
return err;
@@ -200,11 +226,11 @@ static void __context_unpin_state(struct i915_vma *vma)
__i915_vma_unpin(vma);
}
-static int __ring_active(struct intel_ring *ring)
+static int __ring_active_locked(struct intel_ring *ring)
{
int err;
- err = intel_ring_pin(ring);
+ err = intel_ring_pin_locked(ring);
if (err)
return err;
@@ -244,27 +270,53 @@ static void __intel_context_retire(struct i915_active *active)
intel_context_put(ce);
}
-static int __intel_context_active(struct i915_active *active)
+static int
+__intel_context_acquire_lock(struct intel_context *ce,
+ struct i915_acquire_ctx *ctx)
+{
+ return i915_acquire_ctx_lock(ctx, ce->state->obj);
+}
+
+static int
+intel_context_acquire_lock(struct intel_context *ce,
+ struct i915_acquire_ctx *ctx)
{
- struct intel_context *ce = container_of(active, typeof(*ce), active);
int err;
- CE_TRACE(ce, "active\n");
+ err = intel_ring_acquire_lock(ce->ring, ctx);
+ if (err)
+ return err;
- intel_context_get(ce);
+ if (ce->state) {
+ err = __intel_context_acquire_lock(ce, ctx);
+ if (err)
+ return err;
+ }
- err = __ring_active(ce->ring);
+ /* Note that the timeline will migrate as the seqno wrap around */
+ err = intel_timeline_acquire_lock(ce->timeline, ctx);
if (err)
- goto err_put;
+ return err;
+
+ return 0;
+}
- err = intel_timeline_pin(ce->timeline);
+static int intel_context_active_locked(struct intel_context *ce)
+{
+ int err;
+
+ err = __ring_active_locked(ce->ring);
+ if (err)
+ return err;
+
+ err = intel_timeline_pin_locked(ce->timeline);
if (err)
goto err_ring;
if (!ce->state)
return 0;
- err = __context_pin_state(ce->state);
+ err = __context_active_locked(ce->state);
if (err)
goto err_timeline;
@@ -274,7 +326,37 @@ static int __intel_context_active(struct i915_active *active)
intel_timeline_unpin(ce->timeline);
err_ring:
__ring_retire(ce->ring);
-err_put:
+ return err;
+}
+
+static int __intel_context_active(struct i915_active *active)
+{
+ struct intel_context *ce = container_of(active, typeof(*ce), active);
+ struct i915_acquire_ctx acquire;
+ int err;
+
+ CE_TRACE(ce, "active\n");
+
+ intel_context_get(ce);
+ i915_acquire_ctx_init(&acquire);
+
+ err = intel_context_acquire_lock(ce, &acquire);
+ if (err)
+ goto err;
+
+ err = i915_acquire_mm(&acquire);
+ if (err)
+ goto err;
+
+ err = intel_context_active_locked(ce);
+ if (err)
+ goto err;
+
+ i915_acquire_ctx_fini(&acquire);
+ return 0;
+
+err:
+ i915_acquire_ctx_fini(&acquire);
intel_context_put(ce);
return err;
}
diff --git a/drivers/gpu/drm/i915/gt/intel_ring.c b/drivers/gpu/drm/i915/gt/intel_ring.c
index bdb324167ef3..1c21f5725731 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring.c
@@ -5,6 +5,8 @@
*/
#include "gem/i915_gem_object.h"
+#include "mm/i915_acquire_ctx.h"
+
#include "i915_drv.h"
#include "i915_vma.h"
#include "intel_engine.h"
@@ -21,9 +23,16 @@ unsigned int intel_ring_update_space(struct intel_ring *ring)
return space;
}
-int intel_ring_pin(struct intel_ring *ring)
+int intel_ring_acquire_lock(struct intel_ring *ring,
+ struct i915_acquire_ctx *ctx)
+{
+ return i915_acquire_ctx_lock(ctx, ring->vma->obj);
+}
+
+int intel_ring_pin_locked(struct intel_ring *ring)
{
struct i915_vma *vma = ring->vma;
+ enum i915_map_type type;
unsigned int flags;
void *addr;
int ret;
@@ -39,15 +48,15 @@ int intel_ring_pin(struct intel_ring *ring)
else
flags |= PIN_HIGH;
- ret = i915_ggtt_pin(vma, 0, flags);
+ ret = i915_ggtt_pin_locked(vma, 0, flags);
if (unlikely(ret))
goto err_unpin;
+ type = i915_coherent_map_type(vma->vm->i915);
if (i915_vma_is_map_and_fenceable(vma))
addr = (void __force *)i915_vma_pin_iomap(vma);
else
- addr = i915_gem_object_pin_map(vma->obj,
- i915_coherent_map_type(vma->vm->i915));
+ addr = __i915_gem_object_pin_map_locked(vma->obj, type);
if (IS_ERR(addr)) {
ret = PTR_ERR(addr);
goto err_ring;
diff --git a/drivers/gpu/drm/i915/gt/intel_ring.h b/drivers/gpu/drm/i915/gt/intel_ring.h
index cc0ebca65167..34134a0b80b3 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring.h
+++ b/drivers/gpu/drm/i915/gt/intel_ring.h
@@ -11,6 +11,7 @@
#include "i915_request.h"
#include "intel_ring_types.h"
+struct i915_acquire_ctx;
struct intel_engine_cs;
struct intel_ring *
@@ -21,7 +22,9 @@ int intel_ring_cacheline_align(struct i915_request *rq);
unsigned int intel_ring_update_space(struct intel_ring *ring);
-int intel_ring_pin(struct intel_ring *ring);
+int intel_ring_acquire_lock(struct intel_ring *ring,
+ struct i915_acquire_ctx *ctx);
+int intel_ring_pin_locked(struct intel_ring *ring);
void intel_ring_unpin(struct intel_ring *ring);
void intel_ring_reset(struct intel_ring *ring, u32 tail);
diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
index 9a126ad517c1..ec54ff029699 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
@@ -27,6 +27,8 @@
*
*/
+#include "mm/i915_acquire_ctx.h"
+
#include "gen2_engine_cs.h"
#include "gen6_engine_cs.h"
#include "gen6_ppgtt.h"
@@ -1009,6 +1011,15 @@ static void gen6_bsd_set_default_submission(struct intel_engine_cs *engine)
engine->submit_request = gen6_bsd_submit_request;
}
+static void ring_release_global_timeline(struct intel_engine_cs *engine)
+{
+ intel_ring_unpin(engine->legacy.ring);
+ intel_ring_put(engine->legacy.ring);
+
+ intel_timeline_unpin(engine->legacy.timeline);
+ intel_timeline_put(engine->legacy.timeline);
+}
+
static void ring_release(struct intel_engine_cs *engine)
{
struct drm_i915_private *dev_priv = engine->i915;
@@ -1023,11 +1034,7 @@ static void ring_release(struct intel_engine_cs *engine)
i915_vma_unpin_and_release(&engine->wa_ctx.vma, 0);
}
- intel_ring_unpin(engine->legacy.ring);
- intel_ring_put(engine->legacy.ring);
-
- intel_timeline_unpin(engine->legacy.timeline);
- intel_timeline_put(engine->legacy.timeline);
+ ring_release_global_timeline(engine);
}
static void setup_irq(struct intel_engine_cs *engine)
@@ -1226,12 +1233,69 @@ static int gen7_ctx_switch_bb_init(struct intel_engine_cs *engine)
return err;
}
-int intel_ring_submission_setup(struct intel_engine_cs *engine)
+static int ring_setup_global_timeline(struct intel_engine_cs *engine)
{
+ struct i915_acquire_ctx acquire;
struct intel_timeline *timeline;
struct intel_ring *ring;
int err;
+ timeline = intel_timeline_create(engine->gt, engine->status_page.vma);
+ if (IS_ERR(timeline))
+ return PTR_ERR(timeline);
+ GEM_BUG_ON(timeline->has_initial_breadcrumb);
+
+ ring = intel_engine_create_ring(engine, SZ_16K);
+ if (IS_ERR(ring)) {
+ err = PTR_ERR(ring);
+ goto err_timeline;
+ }
+
+ i915_acquire_ctx_init(&acquire);
+
+ err = intel_ring_acquire_lock(ring, &acquire);
+ if (err)
+ goto err_acquire;
+
+ err = intel_timeline_acquire_lock(timeline, &acquire);
+ if (err)
+ goto err_acquire;
+
+ err = i915_acquire_mm(&acquire);
+ if (err)
+ goto err_acquire;
+
+ err = intel_timeline_pin_locked(timeline);
+ if (err)
+ goto err_acquire;
+
+ err = intel_ring_pin_locked(ring);
+ if (err)
+ goto err_timeline_unpin;
+
+ i915_acquire_ctx_fini(&acquire);
+
+ GEM_BUG_ON(engine->legacy.ring);
+ engine->legacy.ring = ring;
+ engine->legacy.timeline = timeline;
+
+ GEM_BUG_ON(timeline->hwsp_ggtt != engine->status_page.vma);
+ return 0;
+
+err_timeline_unpin:
+ intel_timeline_unpin(timeline);
+err_acquire:
+ i915_acquire_ctx_fini(&acquire);
+ intel_ring_put(ring);
+err_timeline:
+ intel_timeline_put(timeline);
+ return err;
+}
+
+int intel_ring_submission_setup(struct intel_engine_cs *engine)
+{
+ int err;
+
setup_common(engine);
switch (engine->class) {
@@ -1252,37 +1316,14 @@ int intel_ring_submission_setup(struct intel_engine_cs *engine)
return -ENODEV;
}
- timeline = intel_timeline_create(engine->gt, engine->status_page.vma);
- if (IS_ERR(timeline)) {
- err = PTR_ERR(timeline);
- goto err;
- }
- GEM_BUG_ON(timeline->has_initial_breadcrumb);
-
- 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_timeline_unpin;
- }
-
- err = intel_ring_pin(ring);
+ err = ring_setup_global_timeline(engine);
if (err)
- goto err_ring;
-
- GEM_BUG_ON(engine->legacy.ring);
- engine->legacy.ring = ring;
- engine->legacy.timeline = timeline;
-
- GEM_BUG_ON(timeline->hwsp_ggtt != engine->status_page.vma);
+ goto err_common;
if (IS_HASWELL(engine->i915) && engine->class == RENDER_CLASS) {
err = gen7_ctx_switch_bb_init(engine);
if (err)
- goto err_ring_unpin;
+ goto err_global;
}
/* Finally, take ownership and responsibility for cleanup! */
@@ -1290,15 +1331,9 @@ int intel_ring_submission_setup(struct intel_engine_cs *engine)
return 0;
-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:
+err_global:
+ ring_release_global_timeline(engine);
+err_common:
intel_engine_cleanup_common(engine);
return err;
}
diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c
index e4a5326633b8..0e449c4b3e61 100644
--- a/drivers/gpu/drm/i915/gt/intel_timeline.c
+++ b/drivers/gpu/drm/i915/gt/intel_timeline.c
@@ -4,9 +4,10 @@
* Copyright © 2016-2018 Intel Corporation
*/
-#include "i915_drv.h"
+#include "mm/i915_acquire_ctx.h"
#include "i915_active.h"
+#include "i915_drv.h"
#include "i915_syncmap.h"
#include "intel_gt.h"
#include "intel_ring.h"
@@ -313,14 +314,21 @@ intel_timeline_create(struct intel_gt *gt, struct i915_vma *global_hwsp)
return timeline;
}
-int intel_timeline_pin(struct intel_timeline *tl)
+int
+intel_timeline_acquire_lock(struct intel_timeline *tl,
+ struct i915_acquire_ctx *ctx)
+{
+ return i915_acquire_ctx_lock(ctx, tl->hwsp_ggtt->obj);
+}
+
+int intel_timeline_pin_locked(struct intel_timeline *tl)
{
int err;
if (atomic_add_unless(&tl->pin_count, 1, 0))
return 0;
- err = i915_ggtt_pin(tl->hwsp_ggtt, 0, PIN_HIGH);
+ err = i915_ggtt_pin_locked(tl->hwsp_ggtt, 0, PIN_HIGH);
if (err)
return err;
diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.h b/drivers/gpu/drm/i915/gt/intel_timeline.h
index 4298b9ac7327..073c94cd8160 100644
--- a/drivers/gpu/drm/i915/gt/intel_timeline.h
+++ b/drivers/gpu/drm/i915/gt/intel_timeline.h
@@ -29,7 +29,9 @@
#include "i915_active.h"
#include "i915_syncmap.h"
-#include "gt/intel_timeline_types.h"
+#include "intel_timeline_types.h"
+
+struct i915_acquire_ctx;
struct intel_timeline *
intel_timeline_create(struct intel_gt *gt, struct i915_vma *global_hwsp);
@@ -71,7 +73,11 @@ static inline bool intel_timeline_sync_is_later(struct intel_timeline *tl,
return __intel_timeline_sync_is_later(tl, fence->context, fence->seqno);
}
-int intel_timeline_pin(struct intel_timeline *tl);
+int
+intel_timeline_acquire_lock(struct intel_timeline *tl,
+ struct i915_acquire_ctx *ctx);
+int intel_timeline_pin_locked(struct intel_timeline *tl);
+
void intel_timeline_enter(struct intel_timeline *tl);
int intel_timeline_get_seqno(struct intel_timeline *tl,
struct i915_request *rq,
diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c
index b8dd3cbc8696..283cfa2912b3 100644
--- a/drivers/gpu/drm/i915/gt/mock_engine.c
+++ b/drivers/gpu/drm/i915/gt/mock_engine.c
@@ -67,6 +67,7 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
__set_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(ring->vma));
__set_bit(DRM_MM_NODE_ALLOCATED_BIT, &ring->vma->node.flags);
ring->vma->node.size = sz;
+ ring->vma->obj = i915_gem_object_create_internal(engine->i915, 4096);
intel_ring_update_space(ring);
@@ -75,6 +76,7 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
static void mock_ring_free(struct intel_ring *ring)
{
+ i915_gem_object_put(ring->vma->obj);
i915_active_fini(&ring->vma->active);
i915_vma_free(ring->vma);
diff --git a/drivers/gpu/drm/i915/gt/selftest_timeline.c b/drivers/gpu/drm/i915/gt/selftest_timeline.c
index fcdee951579b..db7966106569 100644
--- a/drivers/gpu/drm/i915/gt/selftest_timeline.c
+++ b/drivers/gpu/drm/i915/gt/selftest_timeline.c
@@ -6,6 +6,8 @@
#include <linux/prime_numbers.h>
+#include "mm/i915_acquire_ctx.h"
+
#include "intel_context.h"
#include "intel_engine_heartbeat.h"
#include "intel_engine_pm.h"
@@ -449,13 +451,37 @@ static int emit_ggtt_store_dw(struct i915_request *rq, u32 addr, u32 value)
return 0;
}
+static int tl_pin(struct intel_timeline *tl)
+{
+ struct i915_acquire_ctx acquire;
+ int err;
+
+ i915_acquire_ctx_init(&acquire);
+
+ err = intel_timeline_acquire_lock(tl, &acquire);
+ if (err)
+ goto out;
+
+ err = i915_acquire_mm(&acquire);
+ if (err)
+ goto out;
+
+ err = intel_timeline_pin_locked(tl);
+ if (err == 0)
+ err = i915_vma_wait_for_bind(tl->hwsp_ggtt);
+
+out:
+ i915_acquire_ctx_fini(&acquire);
+ return err;
+}
+
static struct i915_request *
tl_write(struct intel_timeline *tl, struct intel_engine_cs *engine, u32 value)
{
struct i915_request *rq;
int err;
- err = intel_timeline_pin(tl);
+ err = tl_pin(tl);
if (err) {
rq = ERR_PTR(err);
goto out;
@@ -665,7 +691,7 @@ static int live_hwsp_wrap(void *arg)
if (!tl->has_initial_breadcrumb || !tl->hwsp_cacheline)
goto out_free;
- err = intel_timeline_pin(tl);
+ err = tl_pin(tl);
if (err)
goto out_free;
--
2.20.1
More information about the Intel-gfx-trybot
mailing list