diff mbox

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

Message ID 1464378183-9433-8-git-send-email-akash.goel@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

akash.goel@intel.com May 27, 2016, 7:42 p.m. UTC
From: Akash Goel <akash.goel@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@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 mbox

Patch

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
 	 */