From: John.C.Harrison@Intel.com
To: Intel-Xe@Lists.FreeDesktop.Org
Cc: John Harrison <John.C.Harrison@Intel.com>
Subject: [PATCH v6 7/9] drm/xe/guc: Dump entire CTB on errors
Date: Thu, 29 Aug 2024 23:23:08 -0700 [thread overview]
Message-ID: <20240830062310.3450387-8-John.C.Harrison@Intel.com> (raw)
In-Reply-To: <20240830062310.3450387-1-John.C.Harrison@Intel.com>
From: John Harrison <John.C.Harrison@Intel.com>
The dump of the CT buffers was only showing the unprocessed data which
is not generally useful for saying why a hang occurred - because it
was probably caused by the commands that were just processed. So save
and dump the entire buffer but in a more compact dump format. Also
zero fill it on allocation to avoid confusion over uninitialised data
in the dump.
v2: Add kerneldoc - review feedback from Michal W.
v3: Fix kerneldoc.
v4: Use ascii85 instead of hexdump (review feedback from Matthew B).
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
drivers/gpu/drm/xe/xe_guc_ct.c | 85 ++++++++++++----------------
drivers/gpu/drm/xe/xe_guc_ct.h | 8 +--
drivers/gpu/drm/xe/xe_guc_ct_types.h | 2 +
3 files changed, 41 insertions(+), 54 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c
index f51fc0d9e648..e41f2e4fbe6b 100644
--- a/drivers/gpu/drm/xe/xe_guc_ct.c
+++ b/drivers/gpu/drm/xe/xe_guc_ct.c
@@ -17,6 +17,7 @@
#include "abi/guc_actions_sriov_abi.h"
#include "abi/guc_klvs_abi.h"
#include "xe_bo.h"
+#include "xe_devcoredump.h"
#include "xe_device.h"
#include "xe_gt.h"
#include "xe_gt_pagefault.h"
@@ -444,6 +445,7 @@ int xe_guc_ct_enable(struct xe_guc_ct *ct)
xe_gt_assert(gt, !xe_guc_ct_enabled(ct));
+ xe_map_memset(xe, &ct->bo->vmap, 0, 0, ct->bo->size);
guc_ct_ctb_h2g_init(xe, &ct->ctbs.h2g, &ct->bo->vmap);
guc_ct_ctb_g2h_init(xe, &ct->ctbs.g2h, &ct->bo->vmap);
@@ -1571,49 +1573,42 @@ static void g2h_worker_func(struct work_struct *w)
receive_g2h(ct);
}
-static void guc_ctb_snapshot_capture(struct xe_device *xe, struct guc_ctb *ctb,
- struct guc_ctb_snapshot *snapshot,
- bool atomic)
+static void guc_ctb_snapshot_alloc(struct guc_ctb *ctb, struct guc_ctb_snapshot *snapshot,
+ bool atomic)
+{
+ snapshot->size = ctb->info.size * sizeof(u32);
+ snapshot->cmds = kmalloc(snapshot->size, atomic ? GFP_ATOMIC : GFP_KERNEL);
+}
+
+struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_alloc(struct xe_guc_ct *ct, bool atomic)
{
- u32 head, tail;
+ struct xe_guc_ct_snapshot *snapshot;
+
+ snapshot = kzalloc(sizeof(*snapshot), atomic ? GFP_ATOMIC : GFP_KERNEL);
+ if (!snapshot)
+ return NULL;
+
+ /* Don't give up if the CTB storage fails to allocate */
+ guc_ctb_snapshot_alloc(&ct->ctbs.h2g, &snapshot->h2g, atomic);
+ guc_ctb_snapshot_alloc(&ct->ctbs.g2h, &snapshot->g2h, atomic);
+ return snapshot;
+}
+
+static void guc_ctb_snapshot_capture(struct xe_device *xe, struct guc_ctb *ctb,
+ struct guc_ctb_snapshot *snapshot)
+{
xe_map_memcpy_from(xe, &snapshot->desc, &ctb->desc, 0,
sizeof(struct guc_ct_buffer_desc));
memcpy(&snapshot->info, &ctb->info, sizeof(struct guc_ctb_info));
- snapshot->cmds = kmalloc_array(ctb->info.size, sizeof(u32),
- atomic ? GFP_ATOMIC : GFP_KERNEL);
-
- if (!snapshot->cmds) {
- drm_err(&xe->drm, "Skipping CTB commands snapshot. Only CT info will be available.\n");
- return;
- }
-
- head = snapshot->desc.head;
- tail = snapshot->desc.tail;
-
- if (head != tail) {
- struct iosys_map map =
- IOSYS_MAP_INIT_OFFSET(&ctb->cmds, head * sizeof(u32));
-
- while (head != tail) {
- snapshot->cmds[head] = xe_map_rd(xe, &map, 0, u32);
- ++head;
- if (head == ctb->info.size) {
- head = 0;
- map = ctb->cmds;
- } else {
- iosys_map_incr(&map, sizeof(u32));
- }
- }
- }
+ if (snapshot->cmds)
+ xe_map_memcpy_from(xe, snapshot->cmds, &ctb->cmds, 0, snapshot->size);
}
static void guc_ctb_snapshot_print(struct guc_ctb_snapshot *snapshot,
struct drm_printer *p)
{
- u32 head, tail;
-
drm_printf(p, "\tsize: %d\n", snapshot->info.size);
drm_printf(p, "\tresv_space: %d\n", snapshot->info.resv_space);
drm_printf(p, "\thead: %d\n", snapshot->info.head);
@@ -1624,19 +1619,13 @@ static void guc_ctb_snapshot_print(struct guc_ctb_snapshot *snapshot,
drm_printf(p, "\ttail (memory): %d\n", snapshot->desc.tail);
drm_printf(p, "\tstatus (memory): 0x%x\n", snapshot->desc.status);
- if (!snapshot->cmds)
+ if (!snapshot->cmds) {
+ drm_printf(p, "CT buffer allocation missing!\n");
return;
-
- head = snapshot->desc.head;
- tail = snapshot->desc.tail;
-
- while (head != tail) {
- drm_printf(p, "\tcmd[%d]: 0x%08x\n", head,
- snapshot->cmds[head]);
- ++head;
- if (head == snapshot->info.size)
- head = 0;
}
+
+ drm_printf(p, "CT buffer:\n");
+ xe_print_blob_ascii85(p, snapshot->cmds, 0, snapshot->size);
}
static void guc_ctb_snapshot_free(struct guc_ctb_snapshot *snapshot)
@@ -1662,9 +1651,7 @@ struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_capture(struct xe_guc_ct *ct,
struct xe_device *xe = ct_to_xe(ct);
struct xe_guc_ct_snapshot *snapshot;
- snapshot = kzalloc(sizeof(*snapshot),
- atomic ? GFP_ATOMIC : GFP_KERNEL);
-
+ snapshot = xe_guc_ct_snapshot_alloc(ct, atomic);
if (!snapshot) {
drm_err(&xe->drm, "Skipping CTB snapshot entirely.\n");
return NULL;
@@ -1673,10 +1660,8 @@ struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_capture(struct xe_guc_ct *ct,
if (xe_guc_ct_enabled(ct) || ct->state == XE_GUC_CT_STATE_STOPPED) {
snapshot->ct_enabled = true;
snapshot->g2h_outstanding = READ_ONCE(ct->g2h_outstanding);
- guc_ctb_snapshot_capture(xe, &ct->ctbs.h2g,
- &snapshot->h2g, atomic);
- guc_ctb_snapshot_capture(xe, &ct->ctbs.g2h,
- &snapshot->g2h, atomic);
+ guc_ctb_snapshot_capture(xe, &ct->ctbs.h2g, &snapshot->h2g);
+ guc_ctb_snapshot_capture(xe, &ct->ctbs.g2h, &snapshot->g2h);
}
return snapshot;
diff --git a/drivers/gpu/drm/xe/xe_guc_ct.h b/drivers/gpu/drm/xe/xe_guc_ct.h
index 293041bed7ed..338f0b75d29f 100644
--- a/drivers/gpu/drm/xe/xe_guc_ct.h
+++ b/drivers/gpu/drm/xe/xe_guc_ct.h
@@ -9,6 +9,7 @@
#include "xe_guc_ct_types.h"
struct drm_printer;
+struct xe_device;
int xe_guc_ct_init(struct xe_guc_ct *ct);
int xe_guc_ct_enable(struct xe_guc_ct *ct);
@@ -16,10 +17,9 @@ void xe_guc_ct_disable(struct xe_guc_ct *ct);
void xe_guc_ct_stop(struct xe_guc_ct *ct);
void xe_guc_ct_fast_path(struct xe_guc_ct *ct);
-struct xe_guc_ct_snapshot *
-xe_guc_ct_snapshot_capture(struct xe_guc_ct *ct, bool atomic);
-void xe_guc_ct_snapshot_print(struct xe_guc_ct_snapshot *snapshot,
- struct drm_printer *p);
+struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_alloc(struct xe_guc_ct *ct, bool atomic);
+struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_capture(struct xe_guc_ct *ct, bool atomic);
+void xe_guc_ct_snapshot_print(struct xe_guc_ct_snapshot *snapshot, struct drm_printer *p);
void xe_guc_ct_snapshot_free(struct xe_guc_ct_snapshot *snapshot);
void xe_guc_ct_print(struct xe_guc_ct *ct, struct drm_printer *p);
diff --git a/drivers/gpu/drm/xe/xe_guc_ct_types.h b/drivers/gpu/drm/xe/xe_guc_ct_types.h
index 85e127ec91d7..c2a2a2831e82 100644
--- a/drivers/gpu/drm/xe/xe_guc_ct_types.h
+++ b/drivers/gpu/drm/xe/xe_guc_ct_types.h
@@ -52,6 +52,8 @@ struct guc_ctb {
struct guc_ctb_snapshot {
/** @desc: snapshot of the CTB descriptor */
struct guc_ct_buffer_desc desc;
+ /** @size: size of the snapshot of the CTB commands */
+ size_t size;
/** @cmds: snapshot of the CTB commands */
u32 *cmds;
/** @info: snapshot of the CTB info */
--
2.46.0
next prev parent reply other threads:[~2024-08-30 6:23 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-30 6:23 [PATCH v6 0/9] drm/xe/guc: Improve GuC log dumping and add to devcoredump John.C.Harrison
2024-08-30 6:23 ` [PATCH v6 1/9] drm/xe/guc: Remove spurious line feed in debug print John.C.Harrison
2024-08-30 6:23 ` [PATCH v6 2/9] drm/xe: Add ASCII85 dump helper function John.C.Harrison
2024-08-30 17:29 ` John Harrison
2024-08-30 17:31 ` John Harrison
2024-08-30 21:56 ` Matthew Brost
2024-08-30 23:33 ` John Harrison
2024-08-31 1:18 ` John Harrison
2024-08-30 6:23 ` [PATCH v6 3/9] drm/xe/guc: Copy GuC log prior to dumping John.C.Harrison
2024-08-30 6:23 ` [PATCH v6 4/9] drm/xe/guc: Use a two stage dump for GuC logs and add more info John.C.Harrison
2024-08-30 6:23 ` [PATCH v6 5/9] drm/print: Introduce drm_line_printer John.C.Harrison
2024-08-30 6:23 ` [PATCH v6 6/9] drm/xe/guc: Dead CT helper John.C.Harrison
2024-08-30 6:23 ` John.C.Harrison [this message]
2024-08-30 6:23 ` [PATCH v6 8/9] drm/xe/guc: Add GuC log to devcoredump captures John.C.Harrison
2024-08-30 6:23 ` [PATCH v6 9/9] drm/xe/guc: Add a helper function for dumping GuC log to dmesg John.C.Harrison
2024-08-30 6:59 ` ✓ CI.Patch_applied: success for drm/xe/guc: Improve GuC log dumping and add to devcoredump Patchwork
2024-08-30 6:59 ` ✗ CI.checkpatch: warning " Patchwork
2024-08-30 7:00 ` ✓ CI.KUnit: success " Patchwork
2024-08-30 7:16 ` ✓ CI.Build: " Patchwork
2024-08-30 7:23 ` ✓ CI.Hooks: " Patchwork
2024-08-30 7:25 ` ✗ CI.checksparse: warning " Patchwork
2024-08-30 19:10 ` ✗ CI.FULL: failure " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240830062310.3450387-8-John.C.Harrison@Intel.com \
--to=john.c.harrison@intel.com \
--cc=Intel-Xe@Lists.FreeDesktop.Org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox