[Intel-gfx] [RFC 07/12] drm/i915: Allocate local buffer to store GuC ukernel logs

akash.goel at intel.com akash.goel at intel.com
Fri May 27 19:42:58 UTC 2016


From: Akash Goel <akash.goel at intel.com>

If relay framework can't be used for all production kernels,
due to debugfs limitation, then need to have our own local buffer
to store the logs and manage it.
This patch allocates a buffer to store the GuC ukernel logs.
The contents of the GuC log buffer will be copied into local buffer
on every flush interrupt from GuC. The local buffer is allocated a
GEM object and is accessed through the vmalloc mapping.

Signed-off-by: Akash Goel <akash.goel at intel.com>
---
 drivers/gpu/drm/i915/i915_guc_submission.c | 40 +++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_guc.h           |  6 +++++
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index d6d6ead..26b95e7 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -963,6 +963,12 @@ static void guc_logging_fini(struct intel_guc *guc)
 {
 #ifdef CONFIG_DEBUG_FS
         guc_remove_log_relay_file(guc);
+#else
+	if (guc->log.buf_obj) {
+		i915_gem_object_unpin_map(guc->log.buf_obj);
+		drm_gem_object_unreference(&guc->log.buf_obj->base);
+		guc->log.buf_obj = NULL;
+	}
 #endif
 }
 
@@ -970,6 +976,38 @@ static void guc_logging_init(struct intel_guc *guc)
 {
 #ifdef CONFIG_DEBUG_FS
 	guc_create_log_relay_file(guc);
+#else
+	struct drm_i915_private *dev_priv = guc_to_i915(guc);
+	struct drm_i915_gem_object *obj;
+	size_t n_subbufs, subbuf_size;
+	void *vaddr;
+
+	spin_lock_init(&guc->log.buf_lock);
+
+	subbuf_size = guc->log_obj->base.size;
+	/* TODO: Decide based on the User's input */
+	n_subbufs = GUC_SCRATCH_LOG_ENTRIES_NR;
+
+	obj = i915_gem_object_create(dev_priv->dev, subbuf_size * n_subbufs);
+	if (IS_ERR(obj))
+		return;
+
+	/* For now permanently pin the pages & create a persistent vmalloc
+	 * mapping of them.
+	 * TODO: Pin/unpin on the fly (to participate in vmap shrinking also),
+	 * once dependency on struct_mutex is obviated.
+	 */
+	vaddr = i915_gem_object_pin_map(obj);
+	if (IS_ERR(vaddr)) {
+		drm_gem_object_unreference(&obj->base);
+		return;
+	}
+
+	guc->log.buf_obj = obj;
+
+	/* Enable the flush interrupt, we have a buffer to store GuC logs */
+	if (i915.guc_log_level >= 0)
+		gen8_enable_guc_interrupts(dev_priv->dev);
 #endif
 }
 
@@ -1224,7 +1262,7 @@ int intel_guc_resume(struct drm_device *dev)
 	if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS)
 		return 0;
 
-	if (i915.guc_log_level >= 0 && guc->log_relay_chan)
+	if (i915.guc_log_level >= 0 && (guc->log_relay_chan || guc->log.buf_obj))
 		gen8_enable_guc_interrupts(dev);
 
 	ctx = dev_priv->kernel_context;
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index bf61925..9e6ce2d 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -121,11 +121,17 @@ struct intel_guc_fw {
 	uint32_t ucode_offset;
 };
 
+struct intel_guc_log {
+	struct drm_i915_gem_object *buf_obj;
+	spinlock_t buf_lock;
+};
+
 struct intel_guc {
 	struct intel_guc_fw guc_fw;
 	uint32_t log_flags;
 	struct drm_i915_gem_object *log_obj;
 	struct rchan *log_relay_chan;
+	struct intel_guc_log log;
 	/*
 	 * work, interrupts_enabled are protected by dev_priv->irq_lock
 	 */
-- 
1.9.2



More information about the Intel-gfx mailing list