diff mbox

[RFC,08/12] drm/i915: Store GuC ukernel logs in the local buffer

Message ID 1464378183-9433-9-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>

This patch copies the content of GuC log buffer into the local buffer.
The data is written into local buffer in a circular manner, so 2 pointers
are maintained to track the data inside the buffer. And after copying the
logs, readers waiting for the data are woken up.
The data from the local buffer is supposed to be consumed by Userspace.

Signed-off-by: Akash Goel <akash.goel@intel.com>
---
 drivers/gpu/drm/i915/i915_guc_submission.c | 27 +++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_guc.h           |  3 +++
 2 files changed, 30 insertions(+)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index 26b95e7..149826a 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -776,6 +776,11 @@  static void guc_move_to_next_buf(struct intel_guc *guc)
 #ifdef CONFIG_DEBUG_FS
 	/* nothing to do here, all managed by relay */
 	return;
+#else
+	/* New log buffer produced, wake up the readers */
+	guc->log.next_seq++;
+	spin_unlock(&guc->log.buf_lock);
+	wake_up_interruptible_all(&guc->log.wq);
 #endif
 }
 
@@ -796,6 +801,27 @@  static void* guc_get_write_buffer(struct intel_guc *guc)
 		relay_reserve(guc->log_relay_chan, guc->log_obj->base.size);
 
 	return base_addr;
+#else
+	size_t n_subbufs, subbuf_size;
+	int next_index;
+
+	base_addr = guc->log.buf_obj->mapping;
+	if (!base_addr)
+		return NULL;
+
+	subbuf_size = guc->log_obj->base.size;
+	n_subbufs = guc->log.buf_obj->base.size / subbuf_size;
+
+	spin_lock(&guc->log.buf_lock);
+	next_index = guc->log.next_seq & (n_subbufs - 1);
+	/*
+	 * If the logs are not being consumed fast enough, do not wait
+	 * and overwrite the oldest data.
+	 */
+	if ((guc->log.next_seq - guc->log.first_seq) >= n_subbufs)
+		guc->log.first_seq++;
+
+	return (base_addr + next_index * subbuf_size);
 #endif
 }
 
@@ -983,6 +1009,7 @@  static void guc_logging_init(struct intel_guc *guc)
 	void *vaddr;
 
 	spin_lock_init(&guc->log.buf_lock);
+	init_waitqueue_head(&guc->log.wq);
 
 	subbuf_size = guc->log_obj->base.size;
 	/* TODO: Decide based on the User's input */
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index 9e6ce2d..bdc3e63 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -124,6 +124,9 @@  struct intel_guc_fw {
 struct intel_guc_log {
 	struct drm_i915_gem_object *buf_obj;
 	spinlock_t buf_lock;
+	wait_queue_head_t wq;
+	uint64_t first_seq;
+	uint64_t next_seq;
 };
 
 struct intel_guc {