<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Nov 12, 2014 at 9:37 AM, Daniel Vetter <span dir="ltr"><<a href="mailto:daniel@ffwll.ch" target="_blank">daniel@ffwll.ch</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">On Mon, Nov 10, 2014 at 02:56:50PM +0000, Robert Bragg wrote:<br>
> This adds i915_gem_context_pin/unpin_state functions so that code<br>
> outside i915_gem_context.c can pin/unpin a context without duplicating<br>
> knowledge about the alignment constraints.<br>
><br>
> Signed-off-by: Robert Bragg <<a href="mailto:robert@sixbynine.org">robert@sixbynine.org</a>><br>
<br>
</span>At first I've thought this is ok to get going, but then I pondered a bit<br>
more. We unpin ctx objects from the shrinker, and this here torpedos that<br>
a bit. And I think the proper implementation isn't more fuzz that this<br>
here:<br>
<br>
When pinning the context we call an OA function to update OA state. When<br>
OA notices that this is the buffer it cares about (for filtered mode) and<br>
that it has moved, it updates OA hw/sw state. I don't think this can race<br>
since a ctx can only be moved when it's not actively used by the gpu, so I<br>
think we should be able to do this. Also unbinding ctxs is a fairly<br>
last-resort kind of thing, so even when this requires a stall (maybe OA<br>
needs to be stopped/restarted) it should still be ok.<br>
<br>
Or do I miss something and this is too much fuzz?<br></blockquote><div><br></div><div>Yeah, this seems workable too; and seems similar to what I had in mind with the previous version I sent out to the lkml:<br><br>/* XXX: Not sure that this is really acceptable...<br> *<br> * i915_gem_context.c currently owns pinning/unpinning legacy<br> * context buffers and although that code has a<br> * get_context_alignment() func to handle a different<br> * constraint for gen6 we are assuming it's fixed for gen7<br> * here. Another option besides pinning here would be to<br> * instead hook into context switching and update the<br> * OACONTROL configuration on the fly.<br> */<br>if (dev_priv->oa_pmu.specific_ctx) {<br>    struct intel_context *ctx = dev_priv->oa_pmu.specific_ctx;<br>    int ret;<br><br>    ret = i915_gem_obj_ggtt_pin(ctx->legacy_hw_ctx.rcs_state,<br>                    4096, 0);<br>    if (ret) {<br>        DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);<br>        ret = -EBUSY;<br>        goto err;<br>    }<br>}<br></div><br></div><div class="gmail_quote">Incidentally; considering some initial patches that Peng Li  sent me recently adding experimental Broadwell support, that also requires us to hook into the context switching to be able to insert some LRIs after the MI_SET_CONTEXT so adding some form of pre set-context hook for this too seems similar.<br><br></div><div class="gmail_quote">Thanks,<br></div><div class="gmail_quote">- Robert<br></div><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
-Daniel<br>
<div class=""><div class="h5"><br>
> ---<br>
>  drivers/gpu/drm/i915/i915_drv.h         |  4 ++++<br>
>  drivers/gpu/drm/i915/i915_gem_context.c | 30 +++++++++++++++++++++---------<br>
>  2 files changed, 25 insertions(+), 9 deletions(-)<br>
><br>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h<br>
> index 3212d62..acaf76c 100644<br>
> --- a/drivers/gpu/drm/i915/i915_drv.h<br>
> +++ b/drivers/gpu/drm/i915/i915_drv.h<br>
> @@ -2675,6 +2675,10 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,<br>
>  int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,<br>
>                                  struct drm_file *file);<br>
><br>
> +int i915_gem_context_pin_state(struct drm_device *dev,<br>
> +                            struct intel_context *ctx);<br>
> +void i915_gem_context_unpin_state(struct intel_context *ctx);<br>
> +<br>
>  /* i915_gem_evict.c */<br>
>  int __must_check i915_gem_evict_something(struct drm_device *dev,<br>
>                                         struct i915_address_space *vm,<br>
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c<br>
> index a5221d8..feb1a23 100644<br>
> --- a/drivers/gpu/drm/i915/i915_gem_context.c<br>
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c<br>
> @@ -132,6 +132,20 @@ static int get_context_size(struct drm_device *dev)<br>
>       return ret;<br>
>  }<br>
><br>
> +int i915_gem_context_pin_state(struct drm_device *dev,<br>
> +                            struct intel_context *ctx)<br>
> +{<br>
> +     BUG_ON(!mutex_is_locked(&dev->struct_mutex));<br>
> +<br>
> +     return i915_gem_obj_ggtt_pin(ctx->legacy_hw_ctx.rcs_state,<br>
> +                                  get_context_alignment(dev), 0);<br>
> +}<br>
> +<br>
> +void i915_gem_context_unpin_state(struct intel_context *ctx)<br>
> +{<br>
> +     i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state);<br>
> +}<br>
> +<br>
>  void i915_gem_context_free(struct kref *ctx_ref)<br>
>  {<br>
>       struct intel_context *ctx = container_of(ctx_ref,<br>
> @@ -253,8 +267,7 @@ i915_gem_create_context(struct drm_device *dev,<br>
>                * be available. To avoid this we always pin the default<br>
>                * context.<br>
>                */<br>
> -             ret = i915_gem_obj_ggtt_pin(ctx->legacy_hw_ctx.rcs_state,<br>
> -                                         get_context_alignment(dev), 0);<br>
> +             ret = i915_gem_context_pin_state(dev, ctx);<br>
>               if (ret) {<br>
>                       DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);<br>
>                       goto err_destroy;<br>
> @@ -278,7 +291,7 @@ i915_gem_create_context(struct drm_device *dev,<br>
><br>
>  err_unpin:<br>
>       if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state)<br>
> -             i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state);<br>
> +             i915_gem_context_unpin_state(ctx);<br>
>  err_destroy:<br>
>       i915_gem_context_unreference(ctx);<br>
>       return ERR_PTR(ret);<br>
> @@ -375,12 +388,12 @@ void i915_gem_context_fini(struct drm_device *dev)<br>
>               if (dev_priv->ring[RCS].last_context == dctx) {<br>
>                       /* Fake switch to NULL context */<br>
>                       WARN_ON(dctx->legacy_hw_ctx.rcs_state->active);<br>
> -                     i915_gem_object_ggtt_unpin(dctx->legacy_hw_ctx.rcs_state);<br>
> +                     i915_gem_context_unpin_state(dctx);<br>
>                       i915_gem_context_unreference(dctx);<br>
>                       dev_priv->ring[RCS].last_context = NULL;<br>
>               }<br>
><br>
> -             i915_gem_object_ggtt_unpin(dctx->legacy_hw_ctx.rcs_state);<br>
> +             i915_gem_context_unpin_state(dctx);<br>
>       }<br>
><br>
>       for (i = 0; i < I915_NUM_RINGS; i++) {<br>
> @@ -534,8 +547,7 @@ static int do_switch(struct intel_engine_cs *ring,<br>
><br>
>       /* Trying to pin first makes error handling easier. */<br>
>       if (ring == &dev_priv->ring[RCS]) {<br>
> -             ret = i915_gem_obj_ggtt_pin(to->legacy_hw_ctx.rcs_state,<br>
> -                                         get_context_alignment(ring->dev), 0);<br>
> +             ret = i915_gem_context_pin_state(ring->dev, to);<br>
>               if (ret)<br>
>                       return ret;<br>
>       }<br>
> @@ -616,7 +628,7 @@ static int do_switch(struct intel_engine_cs *ring,<br>
>               BUG_ON(from->legacy_hw_ctx.rcs_state->ring != ring);<br>
><br>
>               /* obj is kept alive until the next request by its active ref */<br>
> -             i915_gem_object_ggtt_unpin(from->legacy_hw_ctx.rcs_state);<br>
> +             i915_gem_context_unpin_state(from);<br>
>               i915_gem_context_unreference(from);<br>
>       }<br>
><br>
> @@ -643,7 +655,7 @@ done:<br>
><br>
>  unpin_out:<br>
>       if (ring->id == RCS)<br>
> -             i915_gem_object_ggtt_unpin(to->legacy_hw_ctx.rcs_state);<br>
> +             i915_gem_context_unpin_state(to);<br>
>       return ret;<br>
>  }<br>
><br>
> --<br>
> 2.1.3<br>
><br>
> _______________________________________________<br>
> Intel-gfx mailing list<br>
> <a href="mailto:Intel-gfx@lists.freedesktop.org">Intel-gfx@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/intel-gfx" target="_blank">http://lists.freedesktop.org/mailman/listinfo/intel-gfx</a><br>
<br>
</div></div><span class=""><font color="#888888">--<br>
Daniel Vetter<br>
Software Engineer, Intel Corporation<br>
<a href="tel:%2B41%20%280%29%2079%20365%2057%2048" value="+41793655748">+41 (0) 79 365 57 48</a> - <a href="http://blog.ffwll.ch" target="_blank">http://blog.ffwll.ch</a><br>
</font></span><div class=""><div class="h5">_______________________________________________<br>
Intel-gfx mailing list<br>
<a href="mailto:Intel-gfx@lists.freedesktop.org">Intel-gfx@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/intel-gfx" target="_blank">http://lists.freedesktop.org/mailman/listinfo/intel-gfx</a><br>
</div></div></blockquote></div><br></div></div>