[Intel-gfx] [PATCH 3/3] drm/i915: Store a pointer to intel_context in i915_request
Tvrtko Ursulin
tvrtko.ursulin at linux.intel.com
Thu Apr 19 12:11:58 UTC 2018
On 19/04/2018 12:10, Chris Wilson wrote:
> Quoting Tvrtko Ursulin (2018-04-19 11:40:06)
>>
>> On 19/04/2018 08:17, Chris Wilson wrote:
>>> To ease the frequent and ugly pointer dance of
>>> &request->gem_context->engine[request->engine->id] during request
>>> submission, store that pointer as request->hw_context. One major
>>> advantage that we will exploit later is that this decouples the logical
>>> context state from the engine itself.
>>
>> I can see merit in making all the places which work on engines or
>> requests more logically and elegantly grab the engine specific context.
>>
>> Authors of current unmerged work will probably be not so thrilled though.
>
>>> @@ -353,60 +346,56 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload)
>>> struct intel_vgpu_submission *s = &vgpu->submission;
>>> struct i915_gem_context *shadow_ctx = s->shadow_ctx;
>>> struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
>>> - int ring_id = workload->ring_id;
>>> - struct intel_engine_cs *engine = dev_priv->engine[ring_id];
>>> - struct intel_ring *ring;
>>> + struct intel_engine_cs *engine = dev_priv->engine[workload->ring_id];
>>> + struct intel_context *ce;
>>> int ret;
>>>
>>> lockdep_assert_held(&dev_priv->drm.struct_mutex);
>>>
>>> - if (workload->shadowed)
>>> + if (workload->req)
>>> return 0;
>>
>> GVT team will need to look at this hunk/function.
> ...
>> At which point I skip over all GVT and continue further down. :)
>
> That code doesn't merit your attention (or ours really until it is
> improved, it really is staging/ quality).
Still, best to ask GVT team to r-b their parts.
[snip]
>>> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
>>> index 0777226e65a6..e6725690b5b6 100644
>>> --- a/drivers/gpu/drm/i915/intel_lrc.c
>>> +++ b/drivers/gpu/drm/i915/intel_lrc.c
>>> @@ -164,7 +164,8 @@
>>> #define WA_TAIL_BYTES (sizeof(u32) * WA_TAIL_DWORDS)
>>>
>>> static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
>>> - struct intel_engine_cs *engine);
>>> + struct intel_engine_cs *engine,
>>> + struct intel_context *ce);
>>
>> Feels a bit redundant to pass in everything but OK.
>
> You do remember which patch this was split out of ;)
>
>>> {
>>> return (IS_ENABLED(CONFIG_DRM_I915_GVT) &&
>>> - i915_gem_context_force_single_submission(ctx));
>>> + i915_gem_context_force_single_submission(ctx->gem_context));
>>> }
>>
>> But the whole function change is again not needed I think.
>>
>>>
>>> -static bool can_merge_ctx(const struct i915_gem_context *prev,
>>> - const struct i915_gem_context *next)
>>> +static bool can_merge_ctx(const struct intel_context *prev,
>>> + const struct intel_context *next)
>>
>> This one neither.
>
> Consider what it means. The rule is that we are not allowed to submit
> the same lrc descriptor to subsequent ports; that corresponds to
> the hw context, not gem_context. The payoff, aside from the better
> semantics now, is in subsequent patches.
Yes all fine, just saying it did not have to be in _this_ series but
could have came later.
>>> +static struct intel_context *
>>> +execlists_context_pin(struct intel_engine_cs *engine,
>>> + struct i915_gem_context *ctx)
>>> {
>>> - struct intel_context *ce = &ctx->engine[engine->id];
>>> + struct intel_context *ce = to_intel_context(ctx, engine);
>>>
>>> lockdep_assert_held(&ctx->i915->drm.struct_mutex);
>>> - GEM_BUG_ON(ce->pin_count == 0);
>>> -
>>> - if (--ce->pin_count)
>>> - return;
>>>
>>> - intel_ring_unpin(ce->ring);
>>> + if (likely(ce->pin_count++))
>>> + return ce;
>>> + GEM_BUG_ON(!ce->pin_count); /* no overflow please! */
>>>
>>> - ce->state->obj->pin_global--;
>>> - i915_gem_object_unpin_map(ce->state->obj);
>>> - i915_vma_unpin(ce->state);
>>> + ce->ops = &execlists_context_ops;
>>
>> If ops are set on pin it would be good to unset them on destroy.
>
> No point on destroy, since it's being destroyed.
>
>> Hm, or even set them not on pin but on creation.
>
> engine->context_pin() is our intel_context factory, pin is the creation
> function.
>
> Definitely a bit asymmetrical, the key bit was having ce->unpin() so that
> we didn't try to release the intel_context via a stale engine reference.
>
> What I have been considering is passing intel_context to
> i915_request_alloc() instead and trying to avoid that asymmetry by
> managing the creation in the caller and separating it from pin().
>
>> Not a huge deal but it is a
>> bit unbalanced, and also if ce->ops is also a guard to distinguish
>> possible from impossible engines then it is a bit more strange.
>
> Not impossible engines in this regard, unused contexts.
Both then, since impossible engines will have unused contexts. :)
>>> @@ -1323,10 +1345,6 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine)
>>>
>>> intel_engine_setup_common(engine);
>>>
>>> - err = intel_engine_init_common(engine);
>>> - if (err)
>>> - goto err;
>>> -
>>> ring = intel_engine_create_ring(engine, 32 * PAGE_SIZE);
>>> if (IS_ERR(ring)) {
>>> err = PTR_ERR(ring);
>>> @@ -1341,8 +1359,14 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine)
>>> GEM_BUG_ON(engine->buffer);
>>> engine->buffer = ring;
>>>
>>> + err = intel_engine_init_common(engine);
>>> + if (err)
>>> + goto err_unpin;
>>> +
>>
>> This ordering change doesn't look like it has to be done in this patch.
>
> It does. Do you want to take another look ;)
>
> The problem here is the legacy ringbuffer submission uses a common
> engine->buffer, and the kernel contexts are pinned in init_common; so we
> have to create that buffer first.
So it looks like an pre-existing bug. intel_ring_context_pin returns
engine->buffer which hasn't been created yet. Oh well.. can you inject a
patch which solves only that before this one?
Regards,
Tvrtko
More information about the Intel-gfx
mailing list