[PATCH v6 5/6] drm/xe/guc: Add GuC log event buffer output in LFD format
Zhanjun Dong
zhanjun.dong at intel.com
Tue Jul 22 01:35:52 UTC 2025
Add GuC log event buffer output in LFD format.
Signed-off-by: Zhanjun Dong <zhanjun.dong at intel.com>
---
drivers/gpu/drm/xe/xe_guc_log.c | 88 ++++++++++++++++++++++++++++++++-
1 file changed, 87 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_guc_log.c b/drivers/gpu/drm/xe/xe_guc_log.c
index 609a9fd5ba0c..a8910211c579 100644
--- a/drivers/gpu/drm/xe/xe_guc_log.c
+++ b/drivers/gpu/drm/xe/xe_guc_log.c
@@ -421,10 +421,92 @@ xe_guc_log_output_lfd_init(struct drm_printer *p, struct xe_guc_log_snapshot *sn
return size;
}
+static void
+xe_guc_log_print_over_chunks(struct drm_printer *p, struct xe_guc_log_snapshot *snapshot,
+ u32 from, u32 to)
+{
+ int chunk_from = from % GUC_LOG_CHUNK_SIZE;
+ int chunk_id = from / GUC_LOG_CHUNK_SIZE;
+ int to_chunk_id = to / GUC_LOG_CHUNK_SIZE;
+ int chunk_to = to % GUC_LOG_CHUNK_SIZE;
+ int pos = from;
+
+ do {
+ size_t size = (to_chunk_id > chunk_id ? GUC_LOG_CHUNK_SIZE : chunk_to) - chunk_from;
+
+ xe_print_blob_ascii85(p, NULL, 0, snapshot->copy[chunk_id], chunk_from, size);
+ pos += size;
+ chunk_id++;
+ chunk_from = 0;
+ } while (pos < to);
+}
+
+static void
+xe_guc_log_lfd_print_from_chunks(struct drm_printer *p, struct xe_guc_log_snapshot *snapshot,
+ struct guc_log_buffer_entry_list *entry)
+{
+ /* Output data from guc log chunks directly */
+ if (entry->rd_ptr < entry->wr_ptr) {
+ xe_guc_log_print_over_chunks(p, snapshot,
+ entry->offset + entry->rd_ptr,
+ entry->offset + entry->wr_ptr);
+ } else {
+ /* print from rd to buf end 1st */
+ xe_guc_log_print_over_chunks(p, snapshot,
+ entry->offset + entry->rd_ptr,
+ entry->offset + entry->buf_size);
+
+ /* print from buf start to wr */
+ xe_guc_log_print_over_chunks(p, snapshot, entry->offset,
+ entry->offset + entry->wr_ptr);
+ }
+}
+
+static inline int
+xe_guc_log_add_log_event(struct drm_printer *p, struct xe_guc_log_snapshot *snapshot,
+ struct guc_lic_save *config)
+{
+ size_t size;
+ u32 data_len;
+ struct guc_lfd_data *lfd;
+ struct guc_log_buffer_entry_list *entry;
+ struct guc_lfd_data_log_events_buf *events_buf;
+ char buf[GUC_LFD_BUFFER_SIZE] = {0};
+
+ lfd = (void *)buf;
+ entry = &config->entry[GUC_LOG_BUFFER_STATE_HEADER_ENTRY_LOG];
+
+ /* Skip empty log */
+ if (entry->rd_ptr == entry->wr_ptr)
+ return 0;
+
+ size = xe_guc_log_add_lfd_header(buf, GUC_LFD_BUFFER_SIZE);
+ lfd->dw0 |= FIELD_PREP(GUC_LFD_DATA_DESC_TYPE, GUC_LFD_TYPE_LOG_EVENTS_BUFFER);
+ events_buf = (void *)&lfd->data;
+ events_buf->log_events_format_version = config->version;
+
+ /* Adjust to log_format_buf */
+ data_len = offsetof(struct guc_lfd_data_log_events_buf, log_format_buf);
+ size += data_len;
+
+ /* Calculate data length */
+ data_len += (entry->wr_ptr + entry->buf_size - entry->rd_ptr) % entry->buf_size;
+ /* make length u32 aligned */
+ lfd->dw_size = DIV_ROUND_UP(data_len, sizeof(u32));
+
+ /* Output GUC_LFD_TYPE_LOG_EVENTS_BUFFER header */
+ xe_print_blob_ascii85(p, NULL, 0, buf, 0, size);
+ xe_guc_log_lfd_print_from_chunks(p, snapshot, entry);
+
+ /* log event buffer content did not use buf, exclude from size count */
+ return size;
+}
+
static void
xe_guc_log_snapshot_print_lfd(struct xe_guc_log_snapshot *snapshot, struct drm_printer *p)
{
struct guc_lic_save config;
+ size_t size;
if (!snapshot || !snapshot->size)
return;
@@ -435,7 +517,11 @@ xe_guc_log_snapshot_print_lfd(struct xe_guc_log_snapshot *snapshot, struct drm_p
/* Output LFD stream */
xe_guc_log_load_lic(snapshot->copy[0], &config);
- xe_guc_log_output_lfd_init(p, snapshot, &config);
+ size = xe_guc_log_output_lfd_init(p, snapshot, &config);
+ if (size < 0)
+ return;
+
+ xe_guc_log_add_log_event(p, snapshot, &config);
}
/**
--
2.34.1
More information about the Intel-xe
mailing list