[RFC 4/5] drm/xe: Make coredump printing to in-memory cache optional

John.C.Harrison at Intel.com John.C.Harrison at Intel.com
Sat Nov 9 01:59:33 UTC 2024


From: John Harrison <John.C.Harrison at Intel.com>

The devcoredump printing via sysfs is a multi-stage process. After a
binary capture is created, a worker thread is scheduled to convert
the binary data into human readable text stored in a memory
buffer. That buffer is then read via sysfs at a later point.

However, internal driver debug usage of devcoredumps does not
necessarily want to use the in memory buffer and sysfs output method.
E.g. when needing to dump via dmesg for various reasons.

So make the worker thread optional and allow the printing code to be
called with other targets. Also, move blank lines into separate prints
as some print targets need to add per line prefixes.

Signed-off-by: John Harrison <John.C.Harrison at Intel.com>
---
 drivers/gpu/drm/xe/xe_devcoredump.c | 98 +++++++++++++++++------------
 drivers/gpu/drm/xe/xe_devcoredump.h |  2 +
 2 files changed, 59 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c
index 53dc79506094..146b5cd4fbe6 100644
--- a/drivers/gpu/drm/xe/xe_devcoredump.c
+++ b/drivers/gpu/drm/xe/xe_devcoredump.c
@@ -74,56 +74,69 @@ static struct xe_guc *exec_queue_to_guc(struct xe_exec_queue *q)
 	return &q->gt->uc.guc;
 }
 
-static ssize_t __xe_devcoredump_read(char *buffer, size_t count,
-				     struct xe_devcoredump *coredump)
+void xe_devcoredump_print(struct drm_printer *p, struct xe_devcoredump *coredump)
 {
 	struct xe_device *xe = coredump->xe;
 	struct xe_devcoredump_snapshot *ss;
-	struct drm_printer p;
-	struct drm_print_iterator iter;
 	struct timespec64 ts;
 	int i;
 
 	ss = &coredump->snapshot;
 
-	iter.data = buffer;
-	iter.start = 0;
-	iter.remain = count;
-
-	p = drm_coredump_printer(&iter);
-
-	drm_puts(&p, "**** Xe Device Coredump ****\n");
-	drm_puts(&p, "kernel: " UTS_RELEASE "\n");
-	drm_puts(&p, "module: " KBUILD_MODNAME "\n");
+	drm_puts(p, "**** Xe Device Coredump ****\n");
+	drm_puts(p, "kernel: " UTS_RELEASE "\n");
+	drm_puts(p, "module: " KBUILD_MODNAME "\n");
 
 	ts = ktime_to_timespec64(ss->snapshot_time);
-	drm_printf(&p, "Snapshot time: %lld.%09ld\n", ts.tv_sec, ts.tv_nsec);
+	drm_printf(p, "Snapshot time: %lld.%09ld\n", ts.tv_sec, ts.tv_nsec);
 	ts = ktime_to_timespec64(ss->boot_time);
-	drm_printf(&p, "Uptime: %lld.%09ld\n", ts.tv_sec, ts.tv_nsec);
-	drm_printf(&p, "Process: %s\n", ss->process_name);
-	xe_device_snapshot_print(xe, &p);
-
-	drm_printf(&p, "\n**** GT #%d ****\n", ss->gt->info.id);
-	drm_printf(&p, "\tTile: %d\n", ss->gt->tile->id);
+	drm_printf(p, "Uptime: %lld.%09ld\n", ts.tv_sec, ts.tv_nsec);
+	drm_printf(p, "Process: %s\n", ss->process_name);
+	xe_device_snapshot_print(xe, p);
+
+	drm_puts(p, "\n");
+	drm_printf(p, "**** GT #%d ****\n", ss->gt->info.id);
+	drm_printf(p, "\tTile: %d\n", ss->gt->tile->id);
+
+	drm_puts(p, "\n");
+	drm_puts(p, "**** GuC Log ****\n");
+	xe_guc_log_snapshot_print(ss->guc.log, p);
+	drm_puts(p, "\n");
+	drm_puts(p, "**** GuC CT ****\n");
+	xe_guc_ct_snapshot_print(ss->guc.ct, p);
+
+	drm_puts(p, "\n");
+	drm_puts(p, "**** Contexts ****\n");
+	xe_guc_exec_queue_snapshot_print(ss->ge, p);
+
+	drm_puts(p, "\n");
+	drm_puts(p, "**** Job ****\n");
+	xe_sched_job_snapshot_print(ss->job, p);
+
+	drm_puts(p, "\n");
+	drm_puts(p, "**** HW Engines ****\n");
+	for (i = 0; i < XE_NUM_HW_ENGINES; i++)
+		if (ss->hwe[i])
+			xe_engine_snapshot_print(ss->hwe[i], p);
 
-	drm_puts(&p, "\n**** GuC Log ****\n");
-	xe_guc_log_snapshot_print(ss->guc.log, &p);
-	drm_puts(&p, "\n**** GuC CT ****\n");
-	xe_guc_ct_snapshot_print(ss->guc.ct, &p);
+	drm_puts(p, "\n");
+	drm_puts(p, "**** VM state ****\n");
+	xe_vm_snapshot_print(ss->vm, p);
+}
 
-	drm_puts(&p, "\n**** Contexts ****\n");
-	xe_guc_exec_queue_snapshot_print(ss->ge, &p);
+static ssize_t __xe_devcoredump_read(char *buffer, size_t count,
+				     struct xe_devcoredump *coredump)
+{
+	struct drm_printer p;
+	struct drm_print_iterator iter;
 
-	drm_puts(&p, "\n**** Job ****\n");
-	xe_sched_job_snapshot_print(ss->job, &p);
+	iter.data = buffer;
+	iter.start = 0;
+	iter.remain = count;
 
-	drm_puts(&p, "\n**** HW Engines ****\n");
-	for (i = 0; i < XE_NUM_HW_ENGINES; i++)
-		if (ss->hwe[i])
-			xe_engine_snapshot_print(ss->hwe[i], &p);
+	p = drm_coredump_printer(&iter);
 
-	drm_puts(&p, "\n**** VM state ****\n");
-	xe_vm_snapshot_print(ss->vm, &p);
+	xe_devcoredump_print(&p, coredump);
 
 	return count - iter.remain;
 }
@@ -330,7 +343,8 @@ static void devcoredump_snapshot_xe(struct xe_devcoredump *coredump)
 }
 
 static void devcoredump_snapshot_for_thing(struct xe_devcoredump *coredump,
-					   struct xe_gt *gt, struct xe_sched_job *job)
+					   struct xe_gt *gt, struct xe_sched_job *job,
+					   bool want_work)
 {
 	struct xe_devcoredump_snapshot *ss;
 	struct xe_device *xe;
@@ -356,12 +370,14 @@ static void devcoredump_snapshot_for_thing(struct xe_devcoredump *coredump,
 	else
 		devcoredump_snapshot_xe(coredump);
 
-	queue_work(system_unbound_wq, &ss->work);
+	if (want_work)
+		queue_work(system_unbound_wq, &ss->work);
 
 	dma_fence_end_signalling(cookie);
 }
 
-static void devcoredump_for_thing(struct xe_device *_xe, struct xe_gt *gt, struct xe_sched_job *job)
+static void devcoredump_for_thing(struct xe_device *_xe, struct xe_gt *gt,
+				  struct xe_sched_job *job, bool want_work)
 {
 	struct xe_devcoredump *coredump;
 	struct xe_device *xe;
@@ -375,7 +391,7 @@ static void devcoredump_for_thing(struct xe_device *_xe, struct xe_gt *gt, struc
 	}
 
 	coredump->xe = xe;
-	devcoredump_snapshot_for_thing(coredump, gt, job);
+	devcoredump_snapshot_for_thing(coredump, gt, job, want_work);
 
 	drm_info(&xe->drm, "Xe device coredump has been created\n");
 	drm_info(&xe->drm, "Check your /sys/class/drm/card%d/device/devcoredump/data\n",
@@ -396,7 +412,7 @@ static void devcoredump_for_thing(struct xe_device *_xe, struct xe_gt *gt, struc
  */
 void xe_devcoredump_for_job(struct xe_sched_job *job)
 {
-	devcoredump_for_thing(NULL, NULL, job);
+	devcoredump_for_thing(NULL, NULL, job, true);
 }
 
 /**
@@ -409,7 +425,7 @@ void xe_devcoredump_for_job(struct xe_sched_job *job)
  */
 void xe_devcoredump_for_gt(struct xe_gt *gt)
 {
-	devcoredump_for_thing(NULL, gt, NULL);
+	devcoredump_for_thing(NULL, gt, NULL, true);
 }
 
 /**
@@ -422,7 +438,7 @@ void xe_devcoredump_for_gt(struct xe_gt *gt)
  */
 void xe_devcoredump_for_xe(struct xe_device *xe)
 {
-	devcoredump_for_thing(xe, NULL, NULL);
+	devcoredump_for_thing(xe, NULL, NULL, true);
 }
 
 static void xe_driver_devcoredump_fini(void *arg)
diff --git a/drivers/gpu/drm/xe/xe_devcoredump.h b/drivers/gpu/drm/xe/xe_devcoredump.h
index a83c93d0e82c..1d2f9bbd4ebe 100644
--- a/drivers/gpu/drm/xe/xe_devcoredump.h
+++ b/drivers/gpu/drm/xe/xe_devcoredump.h
@@ -10,6 +10,7 @@
 
 struct drm_printer;
 struct xe_device;
+struct xe_devcoredump;
 struct xe_gt;
 struct xe_sched_job;
 
@@ -29,6 +30,7 @@ static inline int xe_devcoredump_init(struct xe_device *xe)
 }
 #endif
 
+void xe_devcoredump_print(struct drm_printer *p, struct xe_devcoredump *coredump);
 void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix,
 			   const void *blob, size_t offset, size_t size);
 
-- 
2.47.0



More information about the Intel-xe mailing list