summaryrefslogtreecommitdiff
path: root/mali_kbase/platform
diff options
context:
space:
mode:
authorKevin DuBois <kevindubois@google.com>2022-09-26 21:25:24 +0000
committerTreeHugger Robot <treehugger-gerrit@google.com>2022-12-06 18:36:49 +0000
commit119bf2a0f97698fabf81f714bcbd4babc3d13785 (patch)
treee1cbde89be458cb9f8147b861481cbc0e813ce85 /mali_kbase/platform
parent70b6fd3e7bcc1fbe0631c5f98d1b897c5514622f (diff)
downloadgpu-119bf2a0f97698fabf81f714bcbd4babc3d13785.tar.gz
mali_kbase: add KTRACE gather ability to SSCD
Gather the KTRACE buffer into the SSCD report to give us some information about the CPU side activity before ramdump. Should only be enabled on debug builds. Test: trigger ramdump, see usable data in dmesg Bug: 249325561 Change-Id: I151644e425d8c3d235c2c540819f9c50c01f2bf8
Diffstat (limited to 'mali_kbase/platform')
-rw-r--r--mali_kbase/platform/pixel/pixel_gpu_sscd.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/mali_kbase/platform/pixel/pixel_gpu_sscd.c b/mali_kbase/platform/pixel/pixel_gpu_sscd.c
index 0c7118f..eb1ecb1 100644
--- a/mali_kbase/platform/pixel/pixel_gpu_sscd.c
+++ b/mali_kbase/platform/pixel/pixel_gpu_sscd.c
@@ -50,6 +50,7 @@ enum
PM_EVENT_LOG = 0x6,
POWER_RAIL_LOG = 0x7,
PDC_STATUS = 0x8,
+ KTRACE = 0x9,
NUM_SEGMENTS
} sscd_segs;
@@ -130,6 +131,70 @@ static void get_fw_trace(struct kbase_device *kbdev, struct sscd_segment *seg)
return;
}
+
+/**
+ * struct pixel_ktrace_metadata - Info about the ktrace log
+ *
+ * @magic: Always 'ktra', helps find the log in memory dumps
+ * @trace_address: The memory address of the ktrace log
+ * @trace_start: Start of the ktrace ringbuffer
+ * @trace_end: End of the ktrace ringbuffer
+ * @version_major: Ktrace major version.
+ * @version_minor: Ktrace minor version.
+ * @_reserved: Bytes reserved for future use
+ **/
+struct pixel_ktrace_metadata {
+ char magic[4];
+ uint64_t trace_address;
+ uint32_t trace_start;
+ uint32_t trace_end;
+ uint8_t version_major;
+ uint8_t version_minor;
+ char _reserved[28];
+} __attribute__((packed));
+_Static_assert(sizeof(struct pixel_ktrace_metadata) == 50,
+ "Incorrect pixel_ktrace_metadata size");
+
+struct pixel_ktrace {
+ struct pixel_ktrace_metadata meta;
+#if KBASE_KTRACE_TARGET_RBUF
+ struct kbase_ktrace_msg trace_log[KBASE_KTRACE_SIZE];
+#endif
+};
+static void get_ktrace(struct kbase_device *kbdev,
+ struct sscd_segment *seg)
+{
+ struct pixel_ktrace *ktrace = seg->addr;
+#if KBASE_KTRACE_TARGET_RBUF
+ unsigned long flags;
+ u32 entries_copied = 0;
+#endif
+
+ if (seg->addr == NULL)
+ return;
+
+ ktrace->meta = (struct pixel_ktrace_metadata) { .magic = "ktra" };
+#if KBASE_KTRACE_TARGET_RBUF
+ lockdep_assert_held(&kbdev->hwaccess_lock);
+ spin_lock_irqsave(&kbdev->ktrace.lock, flags);
+ ktrace->meta.trace_address = (uint64_t)kbdev->ktrace.rbuf;
+ ktrace->meta.trace_start = kbdev->ktrace.first_out;
+ ktrace->meta.trace_end = kbdev->ktrace.next_in;
+ ktrace->meta.version_major = KBASE_KTRACE_VERSION_MAJOR;
+ ktrace->meta.version_minor = KBASE_KTRACE_VERSION_MINOR;
+
+ entries_copied = kbasep_ktrace_copy(kbdev, seg->addr, KBASE_KTRACE_SIZE);
+ if (entries_copied != KBASE_KTRACE_SIZE)
+ dev_warn(kbdev->dev, "only copied %i of %i ktrace entries",
+ entries_copied, KBASE_KTRACE_SIZE);
+ spin_unlock_irqrestore(&kbdev->ktrace.lock, flags);
+
+ KBASE_KTRACE_RBUF_DUMP(kbdev);
+#else
+ dev_warn(kbdev->dev, "ktrace information not present");
+#endif
+}
+
/*
* Stub pending FW support
*/
@@ -223,6 +288,14 @@ static int segments_init(struct kbase_device *kbdev, struct sscd_segment* segmen
return -ENOMEM;
}
+ segments[KTRACE].size = sizeof(struct pixel_ktrace);
+ segments[KTRACE].addr = kzalloc(sizeof(struct pixel_ktrace), GFP_KERNEL);
+ if (segments[KTRACE].addr == NULL) {
+ segments[KTRACE].size = 0;
+ dev_err(kbdev->dev, "pixel: failed to allocate for ktrace buffer");
+ return -ENOMEM;
+ }
+
return 0;
}
@@ -232,6 +305,7 @@ static void segments_term(struct kbase_device *kbdev, struct sscd_segment* segme
kfree(segments[FW_TRACE].addr);
kfree(segments[PM_EVENT_LOG].addr);
+ kfree(segments[KTRACE].addr);
/* Null out the pointers */
memset(segments, 0, sizeof(struct sscd_segment) * NUM_SEGMENTS);
}
@@ -291,6 +365,8 @@ void gpu_sscd_dump(struct kbase_device *kbdev, const char* reason)
get_pm_event_log(kbdev, &segs[PM_EVENT_LOG]);
+ get_ktrace(kbdev, &segs[KTRACE]);
+
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
/* Acquire the pm lock to prevent modifications to the rail state log */