[PATCH 46/54] context-barrier-task
Chris Wilson
chris at chris-wilson.co.uk
Mon Jan 28 00:12:14 UTC 2019
---
drivers/gpu/drm/i915/i915_gem_context.c | 76 +++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_lrc.c | 4 +-
drivers/gpu/drm/i915/intel_ringbuffer.c | 5 +-
3 files changed, 80 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index ef726a3bfb49..375c8a8f222e 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -685,6 +685,82 @@ last_request_on_engine(struct i915_timeline *timeline,
return NULL;
}
+struct context_barrier_task {
+ void (*func)(void *data);
+ void *data;
+
+ unsigned int count;
+ struct cb_active {
+ struct i915_active_request active;
+ struct context_barrier_task *cb;
+ } active[0];
+};
+
+static void
+cb_retire(struct i915_active_request *base, struct i915_request *rq)
+{
+ struct context_barrier_task *cb =
+ container_of(base, struct cb_active, active)->cb;
+
+ if (--cb->count)
+ return;
+
+ if (cb->func)
+ cb->func(cb->data);
+
+ kfree(cb);
+}
+
+static int context_barrier_task(struct i915_gem_context *ctx,
+ void (*func)(void *data),
+ void *data)
+{
+ struct drm_i915_private *i915 = ctx->i915;
+ struct context_barrier_task *cb;
+ struct intel_context *ce;
+ unsigned int count;
+
+ lockdep_assert_held(&i915->drm.struct_mutex);
+ GEM_BUG_ON(!func);
+
+ count = 0;
+ list_for_each_entry(ce, &ctx->active_engines, active_link)
+ count++;
+ if (!count) {
+ func(data);
+ return 0;
+ }
+
+ cb = kmalloc(sizeof(*cb) + count * sizeof(cb->active[0]), GFP_KERNEL);
+ if (!cb)
+ return -ENOMEM;
+
+ cb->func = func;
+ cb->data = data;
+ cb->count = 0;
+
+ list_for_each_entry(ce, &ctx->active_engines, active_link) {
+ struct intel_engine_cs *engine = ce->engine;
+ struct cb_active *active;
+ struct i915_request *rq;
+
+ rq = i915_request_alloc(engine, ctx);
+ if (IS_ERR(rq)) {
+ cb->func = NULL;
+ return PTR_ERR(rq);
+ }
+
+ active = &cb->active[cb->count++];
+ i915_active_request_init(&active->active, rq, cb_retire);
+ active->cb = cb;
+
+ i915_request_add(rq);
+ }
+ GEM_BUG_ON(cb->count != count);
+
+ return 0;
+}
+
int i915_gem_switch_to_kernel_context(struct drm_i915_private *i915)
{
struct intel_engine_cs *engine;
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 18a08b528be3..2debd5bf20b4 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1272,7 +1272,6 @@ static void execlists_context_unpin(struct intel_context *ce)
GEM_BUG_ON(READ_ONCE(ce->active));
}
- list_del(&ce->active_link);
i915_gem_context_unpin_hw_id(ce->gem_context);
intel_ring_unpin(ce->ring);
@@ -1281,6 +1280,7 @@ static void execlists_context_unpin(struct intel_context *ce)
i915_gem_object_unpin_map(ce->state->obj);
i915_vma_unpin(ce->state);
+ list_del(&ce->active_link);
i915_gem_context_put(ce->gem_context);
}
@@ -1364,9 +1364,9 @@ __execlists_context_pin(struct intel_engine_cs *engine,
__execlists_update_reg_state(engine, ce);
- list_add(&ce->active_link, &ctx->active_engines);
ce->state->obj->pin_global++;
i915_gem_context_get(ctx);
+ list_add(&ce->active_link, &ctx->active_engines);
return ce;
unpin_ring:
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 48dfca8aefa8..5ee7c51407c1 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1414,8 +1414,6 @@ static void __context_unpin(struct intel_context *ce)
{
struct i915_vma *vma;
- list_del(&ce->active_link);
-
vma = ce->state;
if (!vma)
return;
@@ -1429,6 +1427,7 @@ static void intel_ring_context_unpin(struct intel_context *ce)
__context_unpin_ppgtt(ce->gem_context);
__context_unpin(ce);
+ list_del(&ce->active_link);
i915_gem_context_put(ce->gem_context);
}
@@ -1528,8 +1527,8 @@ __ring_context_pin(struct intel_engine_cs *engine,
if (err)
goto err_unpin;
- list_add(&ce->active_link, &ctx->active_engines);
i915_gem_context_get(ctx);
+ list_add(&ce->active_link, &ctx->active_engines);
/* One ringbuffer to rule them all */
GEM_BUG_ON(!engine->buffer);
--
2.20.1
More information about the Intel-gfx-trybot
mailing list