[PATCH 2/3] drm/i915/guc: Handle interrupt based logging with lack of SSE4.1, relay and other setup

Sagar Arun Kamble sagar.a.kamble at intel.com
Tue Jan 30 08:02:17 UTC 2018


On some systems like skl-gvtdvm, SSE4.1 movntdqa might not be available.
movntdqa is needed for efficient capture of the logs from uncached GuC
log buffer. GuC init was tied with this support and other setup needed
for interrupt based GuC log capture like relay channel/file support and
uncached mapping support.
With this patch, GuC init is now unblocked from lack of this support.

Signed-off-by: Sagar Arun Kamble <sagar.a.kamble at intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c      |  2 +-
 drivers/gpu/drm/i915/intel_guc.c     |  2 +-
 drivers/gpu/drm/i915/intel_guc_log.c | 90 ++++++++++++++++++++++++++----------
 drivers/gpu/drm/i915/intel_guc_log.h | 12 +++++
 drivers/gpu/drm/i915/intel_uc.c      | 15 +++---
 5 files changed, 88 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 1ec12ad..831988b 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -911,8 +911,8 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
 	mutex_init(&dev_priv->wm.wm_mutex);
 	mutex_init(&dev_priv->pps_mutex);
 
-	intel_uc_init_early(dev_priv);
 	i915_memcpy_init_early(dev_priv);
+	intel_uc_init_early(dev_priv);
 
 	ret = i915_workqueues_init(dev_priv);
 	if (ret < 0)
diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c
index 21140cc..a9e5848 100644
--- a/drivers/gpu/drm/i915/intel_guc.c
+++ b/drivers/gpu/drm/i915/intel_guc.c
@@ -458,7 +458,7 @@ int intel_guc_resume(struct drm_i915_private *dev_priv)
 	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
 		return 0;
 
-	if (i915_modparams.guc_log_level)
+	if (guc->log.runtime.enabled)
 		gen9_enable_guc_interrupts(dev_priv);
 
 	data[0] = INTEL_GUC_ACTION_EXIT_S_STATE;
diff --git a/drivers/gpu/drm/i915/intel_guc_log.c b/drivers/gpu/drm/i915/intel_guc_log.c
index 3fbe93a..dc96d179 100644
--- a/drivers/gpu/drm/i915/intel_guc_log.c
+++ b/drivers/gpu/drm/i915/intel_guc_log.c
@@ -153,6 +153,9 @@ static int guc_log_relay_file_create(struct intel_guc *guc)
 	struct dentry *log_dir;
 	int ret;
 
+	if (!guc->log.runtime.supported)
+		return -ENODEV;
+
 	if (!i915_modparams.guc_log_level)
 		return 0;
 
@@ -174,14 +177,16 @@ static int guc_log_relay_file_create(struct intel_guc *guc)
 	 *	relay channel buffer.
 	 */
 	if (!log_dir) {
-		DRM_ERROR("Debugfs dir not available yet for GuC log file\n");
+		DRM_DEBUG_DRIVER("Debugfs dir not available yet for "
+				 "GuC log file\n");
 		ret = -ENODEV;
 		goto out_unlock;
 	}
 
 	ret = relay_late_setup_files(guc->log.runtime.relay_chan, "guc_log", log_dir);
 	if (ret < 0 && ret != -EEXIST) {
-		DRM_ERROR("Couldn't associate relay chan with file %d\n", ret);
+		DRM_DEBUG_DRIVER("Couldn't associate relay chan with file %d\n",
+				 ret);
 		goto out_unlock;
 	}
 
@@ -395,6 +400,9 @@ static int guc_log_runtime_create(struct intel_guc *guc)
 	void *vaddr;
 	int ret;
 
+	if (!guc->log.runtime.supported)
+		return -ENODEV;
+
 	lockdep_assert_held(&dev_priv->drm.struct_mutex);
 
 	GEM_BUG_ON(guc_log_has_runtime(guc));
@@ -410,7 +418,7 @@ static int guc_log_runtime_create(struct intel_guc *guc)
 	 */
 	vaddr = i915_gem_object_pin_map(guc->log.vma->obj, I915_MAP_WC);
 	if (IS_ERR(vaddr)) {
-		DRM_ERROR("Couldn't map log buffer pages %d\n", ret);
+		DRM_DEBUG_DRIVER("Couldn't map log buffer pages %d\n", ret);
 		return PTR_ERR(vaddr);
 	}
 
@@ -436,6 +444,14 @@ void intel_guc_log_init_early(struct intel_guc *guc)
 {
 	mutex_init(&guc->log.runtime.relay_lock);
 	INIT_WORK(&guc->log.runtime.flush_work, capture_logs_work);
+
+	/*
+	 * We require SSE 4.1 for fast reads from the GuC log buffer and
+	 * it should likely be present on the chipsets supporting GuC based
+	 * submisssions. Interrupt based GuC log capture is to be supported if
+	 * SSE 4.1 support is present and relay & uncached buffer can be setup.
+	 */
+	guc->log.runtime.supported = i915_has_memcpy_from_wc();
 }
 
 int intel_guc_log_relay_create(struct intel_guc *guc)
@@ -445,6 +461,9 @@ int intel_guc_log_relay_create(struct intel_guc *guc)
 	size_t n_subbufs, subbuf_size;
 	int ret;
 
+	if (!guc->log.runtime.supported)
+		return -ENODEV;
+
 	if (!i915_modparams.guc_log_level)
 		return 0;
 
@@ -471,7 +490,8 @@ int intel_guc_log_relay_create(struct intel_guc *guc)
 	guc_log_relay_chan = relay_open(NULL, NULL, subbuf_size,
 					n_subbufs, &relay_callbacks, dev_priv);
 	if (!guc_log_relay_chan) {
-		DRM_ERROR("Couldn't create relay chan for GuC logging\n");
+		DRM_DEBUG_DRIVER("Couldn't create relay chan for "
+				 "GuC logging\n");
 
 		ret = -ENOMEM;
 		goto err;
@@ -486,8 +506,7 @@ int intel_guc_log_relay_create(struct intel_guc *guc)
 
 err:
 	mutex_unlock(&guc->log.runtime.relay_lock);
-	/* logging will be off */
-	i915_modparams.guc_log_level = 0;
+	guc->log.runtime.supported = false;
 	return ret;
 }
 
@@ -514,6 +533,11 @@ static int guc_log_late_setup(struct intel_guc *guc)
 	struct drm_i915_private *dev_priv = guc_to_i915(guc);
 	int ret;
 
+	if (!guc->log.runtime.supported) {
+		ret = -ENODEV;
+		goto err;
+	}
+
 	if (!guc_log_has_runtime(guc)) {
 		/*
 		 * If log was disabled at boot time, then setup needed to handle
@@ -534,6 +558,10 @@ static int guc_log_late_setup(struct intel_guc *guc)
 			goto err_relay;
 	}
 
+	/*
+	 * We are not marking relay file creation failure as catastrophic
+	 * since we can continue to use GuC and base log support.
+	 */
 	ret = guc_log_relay_file_create(guc);
 	if (ret)
 		goto err_runtime;
@@ -547,8 +575,16 @@ static int guc_log_late_setup(struct intel_guc *guc)
 err_relay:
 	intel_guc_log_relay_destroy(guc);
 err:
-	/* logging will remain off */
-	i915_modparams.guc_log_level = 0;
+	mutex_lock(&dev_priv->drm.struct_mutex);
+	intel_runtime_pm_get(dev_priv);
+	gen9_disable_guc_interrupts(dev_priv);
+	intel_runtime_pm_put(dev_priv);
+	mutex_unlock(&dev_priv->drm.struct_mutex);
+
+	/* runtime logging will remain off */
+	guc->log.runtime.supported = false;
+	guc->log.runtime.enabled = false;
+
 	return ret;
 }
 
@@ -571,7 +607,7 @@ static void guc_flush_logs(struct intel_guc *guc)
 {
 	struct drm_i915_private *dev_priv = guc_to_i915(guc);
 
-	if (!USES_GUC_SUBMISSION(dev_priv) || !i915_modparams.guc_log_level)
+	if (!USES_GUC_SUBMISSION(dev_priv) || !guc->log.runtime.enabled)
 		return;
 
 	/* First disable the interrupts, will be renabled afterwards */
@@ -605,16 +641,6 @@ int intel_guc_log_create(struct intel_guc *guc)
 
 	GEM_BUG_ON(guc->log.vma);
 
-	/*
-	 * We require SSE 4.1 for fast reads from the GuC log buffer and
-	 * it should be present on the chipsets supporting GuC based
-	 * submisssions.
-	 */
-	if (WARN_ON(!i915_has_memcpy_from_wc())) {
-		ret = -EINVAL;
-		goto err;
-	}
-
 	vma = intel_guc_allocate_vma(guc, GUC_LOG_SIZE);
 	if (IS_ERR(vma)) {
 		ret = PTR_ERR(vma);
@@ -624,27 +650,41 @@ int intel_guc_log_create(struct intel_guc *guc)
 	guc->log.vma = vma;
 
 	if (i915_modparams.guc_log_level) {
+		/*
+		 * We are not marking runtime creation failure as catastrophic
+		 * since we can continue to use GuC and base log support.
+		 */
 		ret = guc_log_runtime_create(guc);
-		if (ret < 0)
-			goto err_vma;
+		if (ret < 0) {
+			DRM_DEBUG_DRIVER("GuC log runtime create failed. "
+					 "Interrupt based log capture support "
+					 "disabled\n");
+			guc->log.runtime.supported = false;
+		}
 	}
 
 	/* each allocated unit is a page */
-	flags = GUC_LOG_VALID | GUC_LOG_NOTIFY_ON_HALF_FULL |
+	flags = GUC_LOG_VALID |
 		(GUC_LOG_DPC_PAGES << GUC_LOG_DPC_SHIFT) |
 		(GUC_LOG_ISR_PAGES << GUC_LOG_ISR_SHIFT) |
 		(GUC_LOG_CRASH_PAGES << GUC_LOG_CRASH_SHIFT);
 
+	if (guc->log.runtime.supported) {
+		flags |= GUC_LOG_NOTIFY_ON_HALF_FULL;
+		guc->log.runtime.enabled = true;
+	}
+
 	offset = guc_ggtt_offset(vma) >> PAGE_SHIFT; /* in pages */
 	guc->log.flags = (offset << GUC_LOG_BUF_ADDR_SHIFT) | flags;
 
 	return 0;
 
-err_vma:
-	i915_vma_unpin_and_release(&guc->log.vma);
 err:
 	/* logging will be off */
 	i915_modparams.guc_log_level = 0;
+	/* runtime logging will remain off */
+	guc->log.runtime.supported = false;
+
 	return ret;
 }
 
@@ -720,6 +760,8 @@ int intel_guc_log_control(struct intel_guc *guc, u64 control_val)
 		i915_modparams.guc_log_level = 0;
 	}
 
+	guc->log.runtime.enabled = enable_logging;
+
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_guc_log.h b/drivers/gpu/drm/i915/intel_guc_log.h
index dab0e94..8a2d24f 100644
--- a/drivers/gpu/drm/i915/intel_guc_log.h
+++ b/drivers/gpu/drm/i915/intel_guc_log.h
@@ -44,6 +44,18 @@ struct intel_guc_log {
 	struct i915_vma *vma;
 	/* The runtime stuff gets created only when GuC logging gets enabled */
 	struct {
+		/*
+		 * Support based on movntdqa availability, GuC log, relay and
+		 * runtime creation status.
+		 */
+		bool supported;
+
+		/*
+		 * Status based on "supported" and user request for logging
+		 * through i915_modparams.guc_log_level.
+		 */
+		bool enabled;
+
 		void *buf_addr;
 		struct workqueue_struct *flush_wq;
 		struct work_struct flush_work;
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index e3f3509..bb614f7 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -250,16 +250,17 @@ int intel_uc_init_misc(struct drm_i915_private *dev_priv)
 		goto err;
 	}
 
+	/*
+	 * We are not marking relay creation failure as catastrophic
+	 * since we can continue to use GuC and base log support.
+	 */
 	ret = intel_guc_log_relay_create(guc);
-	if (ret) {
-		DRM_ERROR("Couldn't allocate relay for GuC log\n");
-		goto err_relay;
-	}
+	if (ret)
+		DRM_DEBUG_DRIVER("Couldn't allocate relay for GuC log: %d\n",
+				 ret);
 
 	return 0;
 
-err_relay:
-	intel_guc_fini_wq(guc);
 err:
 	return ret;
 }
@@ -386,7 +387,7 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
 	}
 
 	if (USES_GUC_SUBMISSION(dev_priv)) {
-		if (i915_modparams.guc_log_level)
+		if (guc->log.runtime.enabled)
 			gen9_enable_guc_interrupts(dev_priv);
 
 		ret = intel_guc_submission_enable(guc);
-- 
1.9.1



More information about the Intel-gfx-trybot mailing list