[Intel-gfx] [PATCH] drm/i915: HSW GT3 Slices: exec flag to warn kernel that userspace is using predication
Chris Wilson
chris at chris-wilson.co.uk
Fri Oct 25 10:43:52 CEST 2013
On Thu, Oct 24, 2013 at 06:24:18PM -0200, Rodrigo Vivi wrote:
> If Userspace isn't using MI_PREDICATE all slices must be enabled for
> backward compatibility.
>
> If I915_EXEC_USE_PREDICATE isn't set and defaul is set to half, kernel will force
> all slices on.
>
> v2: fix the inverted logic for backwards compatibility
> USE_PREDICATE unset force gt_full when defaul is half
> instead of GT_FULL flag.
>
> v3: Accepting Chris's suggestions: better variable names;
> better logic around state_default x legacy_userspace_busy;
> remove unecessary mutex;
>
> v4: Accepting more suggestions from Chris:
> * Send all LRIs in only one block and don't ignore if it fails.
> * function name and cleaner code on forcing_full.
>
> CC: Chris Wilson <chris at chris-wilson.co.uk>
> CC: Eric Anholt <eric at anholt.net>
> CC: Kenneth Graunke <kenneth at whitecape.org>
> Signed-off-by: Rodrigo Vivi <rodrigo.vivi at gmail.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 8 ++++
> drivers/gpu/drm/i915/i915_gem_execbuffer.c | 63 ++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/i915_reg.h | 11 ++++++
> drivers/gpu/drm/i915/i915_sysfs.c | 3 ++
> drivers/gpu/drm/i915/intel_display.c | 5 +++
> drivers/gpu/drm/i915/intel_drv.h | 1 +
> drivers/gpu/drm/i915/intel_pm.c | 45 ++++++++++++++++++++-
> include/uapi/drm/i915_drm.h | 8 +++-
> 8 files changed, 141 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 685fb1d..67bbbce 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1219,6 +1219,12 @@ struct i915_package_c8 {
> } regsave;
> };
>
> +struct i915_gt_slices {
> + int state_default;
> + int legacy_userspace_busy;
> + struct mutex lock; /* locks access to this scruct and slice registers */
> +};
Ok, I'm getting happier. This time I looked at what locks we were
holding for accessing state_default and legacy_userspace_busy. I'm
afraid we alternated between no locking and struct_mutex. This will add
some unfortunate complexity...
> +
> typedef struct drm_i915_private {
> struct drm_device *dev;
> struct kmem_cache *slab;
> @@ -1418,6 +1424,8 @@ typedef struct drm_i915_private {
>
> struct i915_package_c8 pc8;
>
> + struct i915_gt_slices gt_slices;
> +
> /* Old dri1 support infrastructure, beware the dragons ya fools entering
> * here! */
> struct i915_dri1_state dri1;
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index 0ce0d47..7a362a2 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -922,6 +922,62 @@ i915_reset_gen7_sol_offsets(struct drm_device *dev,
> return 0;
> }
>
> +static int gt_legacy_userspace_busy(struct intel_ring_buffer *ring)
> +{
> + int ret;
> +
if (dev_priv->gt_slices.state_default == 1)
return 0;
> + ret = intel_ring_begin(ring, 18);
> + if (ret)
> + return ret;
> +
> + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
> + intel_ring_emit(ring, HSW_GT_SLICE_INFO);
> + intel_ring_emit(ring, SLICE_SEL_BOTH);
> +
> + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
> + intel_ring_emit(ring, MI_PREDICATE_RESULT_2);
> + intel_ring_emit(ring, LOWER_SLICE_ENABLED);
> +
> + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
> + intel_ring_emit(ring, HSW_SLICESHUTDOWN);
> + intel_ring_emit(ring, ~SLICE_SHUTDOWN);
> +
> + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
> + intel_ring_emit(ring, RC_IDLE_MAX_COUNT);
> + intel_ring_emit(ring, CS_IDLE_COUNT_1US);
> +
> + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
> + intel_ring_emit(ring, WAIT_FOR_RC6_EXIT);
> + intel_ring_emit(ring, _MASKED_BIT_ENABLE(WAIT_RC6_EXIT));
> +
> + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
> + intel_ring_emit(ring, RC_IDLE_MAX_COUNT);
> + intel_ring_emit(ring, CS_IDLE_COUNT_5US);
> +
> + intel_ring_advance(ring);
> + return 0;
> +}
> +
> +static bool gt_legacy_userspace(struct intel_ring_buffer *ring,
> + struct drm_i915_gem_execbuffer2 *args)
> +{
> + drm_i915_private_t *dev_priv = ring->dev->dev_private;
> +
> + if (ring->id == BCS)
> + return false;
> +
> + if (!HAS_SLICE_SHUTDOWN(ring->dev))
> + return false;
> +
> + if (dev_priv->gt_slices.state_default == 1)
> + return false;
> +
> + if (dev_priv->gt_slices.legacy_userspace_busy)
> + return false;
Remove these two.
> +
> + return (args->flags & I915_EXEC_USE_PREDICATE) == 0;
> +}
> +
> static int
> i915_gem_do_execbuffer(struct drm_device *dev, void *data,
> struct drm_file *file,
> @@ -999,6 +1055,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
> return -EINVAL;
> }
>
> + if (gt_legacy_userspace(ring, args)) {
mutex_lock(&dev_priv->gt_slices.lock);
if (!dev_priv->gt_slices.legacy_userspace_busy) {
> + ret = gt_legacy_userspace_busy(ring);
> + if (ret == 0)
> + dev_priv->gt_slices.legacy_userspace_busy = true;
}
mutex_unlock(&dev_priv->gt_slices.lock);
if (ret)
return ret;
> + }
Or you can even push that locking and conditional down to
gt_legacy_userspace_busy().
Fixing the use of dev_priv->gt_slices.lock around the other instances
of gt_slices.legacy_userspace_busy and gt_slices.state_default should be
easier.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
More information about the Intel-gfx
mailing list