[PATCH 6/9] drm/i915/guc: Add client refcounting to enable/disable_guc_interrupts

Sagar Arun Kamble sagar.a.kamble at intel.com
Fri Oct 13 11:28:47 UTC 2017


This patch adds support to enable/disable GuC interrupts for different
features without impacting others needs. Currently GuC log capture and
CT buffer receive mechanisms use the GuC interrupts.
GuC interrupts are currently enabled and disabled in different
scenarios. Disabling GuC interrupts during GuC load failure and suspend
should now check that logging was enabled.
With guc_log_unregister disabling logging and interrupts there is no
need to disable interrupts during uc_fini_hw hence it is removed.

v2: Rebase with all GuC interrupt handlers moved to intel_guc.c. Handling
multiple clients for GuC interrupts enable/disable.
(Michal Wajdeczko)

Signed-off-by: Sagar Arun Kamble <sagar.a.kamble at intel.com>
Cc: Michal Wajdeczko <michal.wajdeczko at intel.com>
Cc: MichaƂ Winiarski <michal.winiarski at intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
---
 drivers/gpu/drm/i915/intel_guc.c     | 15 +++++++++++----
 drivers/gpu/drm/i915/intel_guc.h     |  2 +-
 drivers/gpu/drm/i915/intel_guc_log.c |  1 +
 drivers/gpu/drm/i915/intel_uc.c      |  6 ++++--
 4 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c
index 066b0ef..9e24d93 100644
--- a/drivers/gpu/drm/i915/intel_guc.c
+++ b/drivers/gpu/drm/i915/intel_guc.c
@@ -181,7 +181,8 @@ int intel_guc_suspend(struct drm_i915_private *dev_priv)
 	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
 		return 0;
 
-	intel_disable_guc_interrupts(guc);
+	if (i915_modparams.guc_log_level >= 0)
+		intel_disable_guc_interrupts(guc);
 
 	ctx = dev_priv->kernel_context;
 
@@ -278,12 +279,13 @@ void intel_enable_guc_interrupts(struct intel_guc *guc)
 	struct drm_i915_private *dev_priv = guc_to_i915(guc);
 
 	spin_lock_irq(&dev_priv->irq_lock);
-	if (!dev_priv->guc.interrupts_enabled) {
+
+	if (!guc->interrupt_clients++) {
 		WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) &
 				       dev_priv->pm_guc_events);
-		dev_priv->guc.interrupts_enabled = true;
 		gen6_enable_pm_irq(dev_priv, dev_priv->pm_guc_events);
 	}
+
 	spin_unlock_irq(&dev_priv->irq_lock);
 }
 
@@ -292,7 +294,12 @@ void intel_disable_guc_interrupts(struct intel_guc *guc)
 	struct drm_i915_private *dev_priv = guc_to_i915(guc);
 
 	spin_lock_irq(&dev_priv->irq_lock);
-	dev_priv->guc.interrupts_enabled = false;
+
+	WARN_ON(!guc->interrupt_clients);
+	if (--guc->interrupt_clients) {
+		spin_unlock_irq(&dev_priv->irq_lock);
+		return;
+	}
 
 	gen6_disable_pm_irq(dev_priv, dev_priv->pm_guc_events);
 
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index c7171fd..ffbc595 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -42,7 +42,7 @@ struct intel_guc {
 	struct drm_i915_gem_object *load_err_log;
 
 	/* intel_guc_recv interrupt related state */
-	bool interrupts_enabled;
+	u32 interrupt_clients;
 
 	/* GuC submission related state */
 	bool submission_initialized;
diff --git a/drivers/gpu/drm/i915/intel_guc_log.c b/drivers/gpu/drm/i915/intel_guc_log.c
index aa28c7b..4d17f92 100644
--- a/drivers/gpu/drm/i915/intel_guc_log.c
+++ b/drivers/gpu/drm/i915/intel_guc_log.c
@@ -663,6 +663,7 @@ void i915_guc_log_unregister(struct drm_i915_private *dev_priv)
 	mutex_lock(&dev_priv->drm.struct_mutex);
 	/* GuC logging is currently the only user of Guc2Host interrupts */
 	intel_disable_guc_interrupts(guc);
+	i915_modparams.guc_log_level = -1;
 	guc_log_runtime_destroy(guc);
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 }
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index 8343b88..1ff3823 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -235,7 +235,10 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
 	 */
 err_interrupts:
 	guc_disable_communication(guc);
-	intel_disable_guc_interrupts(guc);
+	if (i915_modparams.guc_log_level >= 0) {
+		intel_disable_guc_interrupts(guc);
+		i915_modparams.guc_log_level = -1;
+	}
 err_log_capture:
 	guc_capture_load_err_log(guc);
 err_submission:
@@ -274,7 +277,6 @@ void intel_uc_fini_hw(struct drm_i915_private *dev_priv)
 
 	guc_disable_communication(guc);
 
-	intel_disable_guc_interrupts(guc);
 	i915_guc_submission_fini(dev_priv);
 
 	i915_ggtt_disable_guc(dev_priv);
-- 
1.9.1



More information about the Intel-gfx-trybot mailing list