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

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


From: Akash Goel <akash.goel at 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 at 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 --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 {
-- 
1.9.2



More information about the Intel-gfx mailing list