Commit 6b736de5 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Pass intel_context to intel_context_pin_lock()



Move the intel_context_instance() to the caller so that we can decouple
ourselves from one context instance per engine.

v2: Rename pin_lock() to lock_pinned(), hopefully that is clearer.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190426163336.15906-5-chris@chris-wilson.co.uk
parent 1b1ae407
Loading
Loading
Loading
Loading
+0 −26
Original line number Diff line number Diff line
@@ -128,32 +128,6 @@ intel_context_instance(struct i915_gem_context *ctx,
	return intel_context_get(pos);
}

struct intel_context *
intel_context_pin_lock(struct i915_gem_context *ctx,
		       struct intel_engine_cs *engine)
	__acquires(ce->pin_mutex)
{
	struct intel_context *ce;

	ce = intel_context_instance(ctx, engine);
	if (IS_ERR(ce))
		return ce;

	if (mutex_lock_interruptible(&ce->pin_mutex)) {
		intel_context_put(ce);
		return ERR_PTR(-EINTR);
	}

	return ce;
}

void intel_context_pin_unlock(struct intel_context *ce)
	__releases(ce->pin_mutex)
{
	mutex_unlock(&ce->pin_mutex);
	intel_context_put(ce);
}

int __intel_context_do_pin(struct intel_context *ce)
{
	int err;
+27 −7
Original line number Diff line number Diff line
@@ -31,25 +31,45 @@ intel_context_lookup(struct i915_gem_context *ctx,
		     struct intel_engine_cs *engine);

/**
 * intel_context_pin_lock - Stablises the 'pinned' status of the HW context
 * @ctx - the parent GEM context
 * @engine - the target HW engine
 * intel_context_lock_pinned - Stablises the 'pinned' status of the HW context
 * @ce - the context
 *
 * Acquire a lock on the pinned status of the HW context, such that the context
 * can neither be bound to the GPU or unbound whilst the lock is held, i.e.
 * intel_context_is_pinned() remains stable.
 */
struct intel_context *
intel_context_pin_lock(struct i915_gem_context *ctx,
		       struct intel_engine_cs *engine);
static inline int intel_context_lock_pinned(struct intel_context *ce)
	__acquires(ce->pin_mutex)
{
	return mutex_lock_interruptible(&ce->pin_mutex);
}

/**
 * intel_context_is_pinned - Reports the 'pinned' status
 * @ce - the context
 *
 * While in use by the GPU, the context, along with its ring and page
 * tables is pinned into memory and the GTT.
 *
 * Returns: true if the context is currently pinned for use by the GPU.
 */
static inline bool
intel_context_is_pinned(struct intel_context *ce)
{
	return atomic_read(&ce->pin_count);
}

void intel_context_pin_unlock(struct intel_context *ce);
/**
 * intel_context_unlock_pinned - Releases the earlier locking of 'pinned' status
 * @ce - the context
 *
 * Releases the lock earlier acquired by intel_context_unlock_pinned().
 */
static inline void intel_context_unlock_pinned(struct intel_context *ce)
	__releases(ce->pin_mutex)
{
	mutex_unlock(&ce->pin_mutex);
}

struct intel_context *
__intel_context_insert(struct i915_gem_context *ctx,
+54 −38
Original line number Diff line number Diff line
@@ -141,6 +141,18 @@ static void lut_close(struct i915_gem_context *ctx)
	rcu_read_unlock();
}

static struct intel_context *
lookup_user_engine(struct i915_gem_context *ctx, u16 class, u16 instance)
{
	struct intel_engine_cs *engine;

	engine = intel_engine_lookup_user(ctx->i915, class, instance);
	if (!engine)
		return ERR_PTR(-EINVAL);

	return intel_context_instance(ctx, engine);
}

static inline int new_hw_id(struct drm_i915_private *i915, gfp_t gfp)
{
	unsigned int max;
@@ -1132,19 +1144,17 @@ out_add:
}

static int
__i915_gem_context_reconfigure_sseu(struct i915_gem_context *ctx,
				    struct intel_engine_cs *engine,
__intel_context_reconfigure_sseu(struct intel_context *ce,
				 struct intel_sseu sseu)
{
	struct intel_context *ce;
	int ret = 0;
	int ret;

	GEM_BUG_ON(INTEL_GEN(ctx->i915) < 8);
	GEM_BUG_ON(engine->id != RCS0);
	GEM_BUG_ON(INTEL_GEN(ce->gem_context->i915) < 8);
	GEM_BUG_ON(ce->engine->id != RCS0);

	ce = intel_context_pin_lock(ctx, engine);
	if (IS_ERR(ce))
		return PTR_ERR(ce);
	ret = intel_context_lock_pinned(ce);
	if (ret)
		return ret;

	/* Nothing to do if unmodified. */
	if (!memcmp(&ce->sseu, &sseu, sizeof(sseu)))
@@ -1155,24 +1165,23 @@ __i915_gem_context_reconfigure_sseu(struct i915_gem_context *ctx,
		ce->sseu = sseu;

unlock:
	intel_context_pin_unlock(ce);
	intel_context_unlock_pinned(ce);
	return ret;
}

static int
i915_gem_context_reconfigure_sseu(struct i915_gem_context *ctx,
				  struct intel_engine_cs *engine,
				  struct intel_sseu sseu)
intel_context_reconfigure_sseu(struct intel_context *ce, struct intel_sseu sseu)
{
	struct drm_i915_private *i915 = ce->gem_context->i915;
	int ret;

	ret = mutex_lock_interruptible(&ctx->i915->drm.struct_mutex);
	ret = mutex_lock_interruptible(&i915->drm.struct_mutex);
	if (ret)
		return ret;

	ret = __i915_gem_context_reconfigure_sseu(ctx, engine, sseu);
	ret = __intel_context_reconfigure_sseu(ce, sseu);

	mutex_unlock(&ctx->i915->drm.struct_mutex);
	mutex_unlock(&i915->drm.struct_mutex);

	return ret;
}
@@ -1280,7 +1289,7 @@ static int set_sseu(struct i915_gem_context *ctx,
{
	struct drm_i915_private *i915 = ctx->i915;
	struct drm_i915_gem_context_param_sseu user_sseu;
	struct intel_engine_cs *engine;
	struct intel_context *ce;
	struct intel_sseu sseu;
	int ret;

@@ -1297,27 +1306,31 @@ static int set_sseu(struct i915_gem_context *ctx,
	if (user_sseu.flags || user_sseu.rsvd)
		return -EINVAL;

	engine = intel_engine_lookup_user(i915,
	ce = lookup_user_engine(ctx,
				user_sseu.engine.engine_class,
				user_sseu.engine.engine_instance);
	if (!engine)
		return -EINVAL;
	if (IS_ERR(ce))
		return PTR_ERR(ce);

	/* Only render engine supports RPCS configuration. */
	if (engine->class != RENDER_CLASS)
		return -ENODEV;
	if (ce->engine->class != RENDER_CLASS) {
		ret = -ENODEV;
		goto out_ce;
	}

	ret = user_to_context_sseu(i915, &user_sseu, &sseu);
	if (ret)
		return ret;
		goto out_ce;

	ret = i915_gem_context_reconfigure_sseu(ctx, engine, sseu);
	ret = intel_context_reconfigure_sseu(ce, sseu);
	if (ret)
		return ret;
		goto out_ce;

	args->size = sizeof(user_sseu);

	return 0;
out_ce:
	intel_context_put(ce);
	return ret;
}

static int ctx_setparam(struct drm_i915_file_private *fpriv,
@@ -1522,8 +1535,8 @@ static int get_sseu(struct i915_gem_context *ctx,
		    struct drm_i915_gem_context_param *args)
{
	struct drm_i915_gem_context_param_sseu user_sseu;
	struct intel_engine_cs *engine;
	struct intel_context *ce;
	int err;

	if (args->size == 0)
		goto out;
@@ -1537,22 +1550,25 @@ static int get_sseu(struct i915_gem_context *ctx,
	if (user_sseu.flags || user_sseu.rsvd)
		return -EINVAL;

	engine = intel_engine_lookup_user(ctx->i915,
	ce = lookup_user_engine(ctx,
				user_sseu.engine.engine_class,
				user_sseu.engine.engine_instance);
	if (!engine)
		return -EINVAL;

	ce = intel_context_pin_lock(ctx, engine); /* serialises with set_sseu */
	if (IS_ERR(ce))
		return PTR_ERR(ce);

	err = intel_context_lock_pinned(ce); /* serialises with set_sseu */
	if (err) {
		intel_context_put(ce);
		return err;
	}

	user_sseu.slice_mask = ce->sseu.slice_mask;
	user_sseu.subslice_mask = ce->sseu.subslice_mask;
	user_sseu.min_eus_per_subslice = ce->sseu.min_eus_per_subslice;
	user_sseu.max_eus_per_subslice = ce->sseu.max_eus_per_subslice;

	intel_context_pin_unlock(ce);
	intel_context_unlock_pinned(ce);
	intel_context_put(ce);

	if (copy_to_user(u64_to_user_ptr(args->value), &user_sseu,
			 sizeof(user_sseu)))
+1 −1
Original line number Diff line number Diff line
@@ -1017,7 +1017,7 @@ __sseu_test(struct drm_i915_private *i915,
	if (ret)
		return ret;

	ret = __i915_gem_context_reconfigure_sseu(ce->gem_context, ce->engine, sseu);
	ret = __intel_context_reconfigure_sseu(ce, sseu);
	if (ret)
		goto out_spin;