Commit 32271ecd authored by Daniele Ceraolo Spurio's avatar Daniele Ceraolo Spurio Committed by Rodrigo Vivi
Browse files

drm/i915/pxp: start the arb session on demand



Now that we can handle destruction and re-creation of the arb session,
we can postpone the start of the session to the first submission that
requires it, to avoid keeping it running with no user.

v10: increase timeout when waiting in intel_pxp_start as firmware
     session startup is slower right after boot.
v13: increase the same timeout by 50 milisec because previous timeout
     was not enough to cover two lower level 100 milisec timeouts
     in the session termination + creation steps.

Signed-off-by: default avatarAlan Previn <alan.previn.teres.alexis@intel.com>
Signed-off-by: default avatarDaniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210924191452.1539378-12-alan.previn.teres.alexis@intel.com
parent d3ac8d42
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -267,7 +267,9 @@ static int proto_context_set_protected(struct drm_i915_private *i915,
		 * which in turn requires the device to be active.
		 */
		pc->pxp_wakeref = intel_runtime_pm_get(&i915->runtime_pm);
		ret = intel_pxp_wait_for_arb_start(&i915->gt.pxp);

		if (!intel_pxp_is_active(&i915->gt.pxp))
			ret = intel_pxp_start(&i915->gt.pxp);
	}

	return ret;
+24 −13
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ void intel_pxp_init(struct intel_pxp *pxp)
	init_completion(&pxp->termination);
	complete_all(&pxp->termination);

	mutex_init(&pxp->arb_mutex);
	INIT_WORK(&pxp->session_work, intel_pxp_session_work);

	ret = create_vcs_context(pxp);
@@ -127,7 +128,7 @@ void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp)
	reinit_completion(&pxp->termination);
}

static void intel_pxp_queue_termination(struct intel_pxp *pxp)
static void pxp_queue_termination(struct intel_pxp *pxp)
{
	struct intel_gt *gt = pxp_to_gt(pxp);

@@ -146,31 +147,41 @@ static void intel_pxp_queue_termination(struct intel_pxp *pxp)
 * the arb session is restarted from the irq work when we receive the
 * termination completion interrupt
 */
int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
int intel_pxp_start(struct intel_pxp *pxp)
{
	int ret = 0;

	if (!intel_pxp_is_enabled(pxp))
		return 0;
		return -ENODEV;

	mutex_lock(&pxp->arb_mutex);

	if (pxp->arb_is_valid)
		goto unlock;

	pxp_queue_termination(pxp);

	if (!wait_for_completion_timeout(&pxp->termination,
					 msecs_to_jiffies(100)))
		return -ETIMEDOUT;
					msecs_to_jiffies(250))) {
		ret = -ETIMEDOUT;
		goto unlock;
	}

	/* make sure the compiler doesn't optimize the double access */
	barrier();

	if (!pxp->arb_is_valid)
		return -EIO;
		ret = -EIO;

	return 0;
unlock:
	mutex_unlock(&pxp->arb_mutex);
	return ret;
}

void intel_pxp_init_hw(struct intel_pxp *pxp)
{
	kcr_pxp_enable(pxp_to_gt(pxp));
	intel_pxp_irq_enable(pxp);

	/*
	 * the session could've been attacked while we weren't loaded, so
	 * handle it as if it was and re-create it.
	 */
	intel_pxp_queue_termination(pxp);
}

void intel_pxp_fini_hw(struct intel_pxp *pxp)
+8 −2
Original line number Diff line number Diff line
@@ -26,7 +26,8 @@ void intel_pxp_init_hw(struct intel_pxp *pxp);
void intel_pxp_fini_hw(struct intel_pxp *pxp);

void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);

int intel_pxp_start(struct intel_pxp *pxp);

int intel_pxp_key_check(struct intel_pxp *pxp, struct drm_i915_gem_object *obj);

@@ -40,11 +41,16 @@ static inline void intel_pxp_fini(struct intel_pxp *pxp)
{
}

static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
static inline int intel_pxp_start(struct intel_pxp *pxp)
{
	return -ENODEV;
}

static inline bool intel_pxp_is_active(const struct intel_pxp *pxp)
{
	return false;
}

static inline int intel_pxp_key_check(struct intel_pxp *pxp,
				      struct drm_i915_gem_object *obj)
{
+1 −1
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
		   GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT)) {
		/* immediately mark PXP as inactive on termination */
		intel_pxp_mark_termination_in_progress(pxp);
		pxp->session_events |= PXP_TERMINATION_REQUEST;
		pxp->session_events |= PXP_TERMINATION_REQUEST | PXP_INVAL_REQUIRED;
	}

	if (iir & GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
+3 −3
Original line number Diff line number Diff line
@@ -88,9 +88,6 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
	/* must mark termination in progress calling this function */
	GEM_WARN_ON(pxp->arb_is_valid);

	/* invalidate protected objects */
	intel_pxp_invalidate(pxp);

	/* terminate the hw sessions */
	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
	if (ret) {
@@ -147,6 +144,9 @@ void intel_pxp_session_work(struct work_struct *work)
	if (!events)
		return;

	if (events & PXP_INVAL_REQUIRED)
		intel_pxp_invalidate(pxp);

	if (events & PXP_TERMINATION_REQUEST) {
		events &= ~PXP_TERMINATION_COMPLETE;
		pxp_terminate(pxp);
Loading