struct i915_gem_context *ctx;
list_for_each_entry(ctx, &i915->contexts.list, link) {
- struct intel_engine_cs *engine;
- enum intel_engine_id id;
-
- for_each_engine(engine, i915, id) {
- struct intel_context *ce = to_intel_context(ctx, engine);
+ struct intel_context *ce;
+ list_for_each_entry(ce, &ctx->active_engines, active_link) {
if (ce->state)
per_file_stats(0, ce->state->obj, &kstats);
if (ce->ring)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
struct drm_device *dev = &dev_priv->drm;
- struct intel_engine_cs *engine;
struct i915_gem_context *ctx;
- enum intel_engine_id id;
int ret;
ret = mutex_lock_interruptible(&dev->struct_mutex);
return ret;
list_for_each_entry(ctx, &dev_priv->contexts.list, link) {
+ struct intel_context *ce;
+
seq_puts(m, "HW context ");
if (!list_empty(&ctx->hw_id_link))
seq_printf(m, "%x [pin %u]", ctx->hw_id,
seq_putc(m, ctx->remap_slice ? 'R' : 'r');
seq_putc(m, '\n');
- for_each_engine(engine, dev_priv, id) {
- struct intel_context *ce =
- to_intel_context(ctx, engine);
-
- seq_printf(m, "%s: ", engine->name);
+ list_for_each_entry(ce, &ctx->active_engines, active_link) {
+ seq_printf(m, "%s: ", ce->engine->name);
if (ce->state)
describe_obj(m, ce->state->obj);
if (ce->ring)
lockdep_assert_held(&ctx->i915->drm.struct_mutex);
GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
+ GEM_BUG_ON(!list_empty(&ctx->active_engines));
release_hw_id(ctx);
i915_ppgtt_put(ctx->ppgtt);
put_pid(ctx->pid);
list_del(&ctx->link);
+ mutex_destroy(&ctx->mutex);
kfree_rcu(ctx, rcu);
}
struct intel_engine_cs *engine)
{
ce->gem_context = ctx;
+ ce->engine = engine;
INIT_LIST_HEAD(&ce->signal_link);
INIT_LIST_HEAD(&ce->signals);
list_add_tail(&ctx->link, &dev_priv->contexts.list);
ctx->i915 = dev_priv;
ctx->sched.priority = I915_USER_PRIORITY(I915_PRIORITY_NORMAL);
+ INIT_LIST_HEAD(&ctx->active_engines);
+ mutex_init(&ctx->mutex);
for (n = 0; n < ARRAY_SIZE(ctx->__engine); n++)
intel_context_init(&ctx->__engine[n], ctx, dev_priv->engine[n]);
atomic_t hw_id_pin_count;
struct list_head hw_id_link;
+ struct list_head active_engines;
+ struct mutex mutex;
+
/**
* @user_handle: userspace identifier
*
/** engine: per-engine logical HW state */
struct intel_context {
struct i915_gem_context *gem_context;
+ struct intel_engine_cs *engine;
struct intel_engine_cs *active;
+ struct list_head active_link;
struct list_head signal_link;
struct list_head signals;
struct i915_vma *state;
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);
}
__execlists_update_reg_state(engine, ce);
ce->state->obj->pin_global++;
+
+ mutex_lock(&ctx->mutex);
+ list_add(&ce->active_link, &ctx->active_engines);
+ mutex_unlock(&ctx->mutex);
+
i915_gem_context_get(ctx);
return ce;
void intel_lr_context_resume(struct drm_i915_private *i915)
{
- struct intel_engine_cs *engine;
struct i915_gem_context *ctx;
- enum intel_engine_id id;
+ struct intel_context *ce;
/*
* Because we emit WA_TAIL_DWORDS there may be a disparity
* simplicity, we just zero everything out.
*/
list_for_each_entry(ctx, &i915->contexts.list, link) {
- for_each_engine(engine, i915, id) {
- struct intel_context *ce =
- to_intel_context(ctx, engine);
-
- if (!ce->state)
- continue;
-
+ list_for_each_entry(ce, &ctx->active_engines, active_link) {
+ GEM_BUG_ON(!ce->ring);
intel_ring_reset(ce->ring, 0);
-
- if (ce->pin_count) /* otherwise done in context_pin */
- __execlists_update_reg_state(engine, ce);
+ __execlists_update_reg_state(ce->engine, ce);
}
}
}
__context_unpin_ppgtt(ce->gem_context);
__context_unpin(ce);
+ list_del(&ce->active_link);
i915_gem_context_put(ce->gem_context);
}
{
int err;
+ /* One ringbuffer to rule them all */
+ GEM_BUG_ON(!engine->buffer);
+ ce->ring = engine->buffer;
+
if (!ce->state && engine->context_size) {
struct i915_vma *vma;
if (err)
goto err_unpin;
- i915_gem_context_get(ctx);
-
- /* One ringbuffer to rule them all */
- GEM_BUG_ON(!engine->buffer);
- ce->ring = engine->buffer;
+ mutex_lock(&ctx->mutex);
+ list_add(&ce->active_link, &ctx->active_engines);
+ mutex_unlock(&ctx->mutex);
+ i915_gem_context_get(ctx);
return ce;
err_unpin:
INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
INIT_LIST_HEAD(&ctx->handles_list);
INIT_LIST_HEAD(&ctx->hw_id_link);
+ INIT_LIST_HEAD(&ctx->active_engines);
+ mutex_init(&ctx->mutex);
for (n = 0; n < ARRAY_SIZE(ctx->__engine); n++)
intel_context_init(&ctx->__engine[n], ctx, i915->engine[n]);
static void mock_context_unpin(struct intel_context *ce)
{
mock_timeline_unpin(ce->ring->timeline);
+ list_del(&ce->active_link);
i915_gem_context_put(ce->gem_context);
}
mock_timeline_pin(ce->ring->timeline);
ce->ops = &mock_context_ops;
+
+ mutex_lock(&ctx->mutex);
+ list_add(&ce->active_link, &ctx->active_engines);
+ mutex_unlock(&ctx->mutex);
+
i915_gem_context_get(ctx);
return ce;