Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/xe/guc: Separate full CTB content from guc_info debugfs

The guc_info debugfs file is meant to be a quick view of the current
software state of the GuC interface. Including the full CTB contents
makes the file as a whole much less human readable and is not
partiular useful in the general case. So don't pollute the info dump
with the full buffers. Instead, move those into a separate debugfs
entry that can be read when that information is actually required.

Also, improve the human readability by adding a few extra blank lines
to delimt the sections.

v2: Hide the internal capture/print params from external callers that
don't need to know (review feedback from Matthew Brost).

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241024002554.1983101-3-John.C.Harrison@Intel.com

+49 -31
+1 -1
drivers/gpu/drm/xe/xe_devcoredump.c
··· 267 267 fw_ref = xe_force_wake_get(gt_to_fw(q->gt), XE_FORCEWAKE_ALL); 268 268 269 269 ss->guc.log = xe_guc_log_snapshot_capture(&guc->log, true); 270 - ss->guc.ct = xe_guc_ct_snapshot_capture(&guc->ct, true); 270 + ss->guc.ct = xe_guc_ct_snapshot_capture(&guc->ct); 271 271 ss->ge = xe_guc_exec_queue_snapshot_capture(q); 272 272 ss->job = xe_sched_job_snapshot_capture(job); 273 273 ss->vm = xe_vm_snapshot_capture(q->vm);
+4 -1
drivers/gpu/drm/xe/xe_guc.c
··· 1186 1186 1187 1187 xe_force_wake_put(gt_to_fw(gt), fw_ref); 1188 1188 1189 - xe_guc_ct_print(&guc->ct, p); 1189 + drm_puts(p, "\n"); 1190 + xe_guc_ct_print(&guc->ct, p, false); 1191 + 1192 + drm_puts(p, "\n"); 1190 1193 xe_guc_submit_print(guc, p); 1191 1194 } 1192 1195
+28 -26
drivers/gpu/drm/xe/xe_guc_ct.c
··· 1607 1607 receive_g2h(ct); 1608 1608 } 1609 1609 1610 - struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_alloc(struct xe_guc_ct *ct, bool atomic) 1610 + static struct xe_guc_ct_snapshot *guc_ct_snapshot_alloc(struct xe_guc_ct *ct, bool atomic, 1611 + bool want_ctb) 1611 1612 { 1612 1613 struct xe_guc_ct_snapshot *snapshot; 1613 1614 ··· 1616 1615 if (!snapshot) 1617 1616 return NULL; 1618 1617 1619 - if (ct->bo) { 1618 + if (ct->bo && want_ctb) { 1620 1619 snapshot->ctb_size = ct->bo->size; 1621 1620 snapshot->ctb = kmalloc(snapshot->ctb_size, atomic ? GFP_ATOMIC : GFP_KERNEL); 1622 1621 } ··· 1646 1645 drm_printf(p, "\tstatus (memory): 0x%x\n", snapshot->desc.status); 1647 1646 } 1648 1647 1649 - /** 1650 - * xe_guc_ct_snapshot_capture - Take a quick snapshot of the CT state. 1651 - * @ct: GuC CT object. 1652 - * @atomic: Boolean to indicate if this is called from atomic context like 1653 - * reset or CTB handler or from some regular path like debugfs. 1654 - * 1655 - * This can be printed out in a later stage like during dev_coredump 1656 - * analysis. 1657 - * 1658 - * Returns: a GuC CT snapshot object that must be freed by the caller 1659 - * by using `xe_guc_ct_snapshot_free`. 1660 - */ 1661 - struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_capture(struct xe_guc_ct *ct, 1662 - bool atomic) 1648 + static struct xe_guc_ct_snapshot *guc_ct_snapshot_capture(struct xe_guc_ct *ct, bool atomic, 1649 + bool want_ctb) 1663 1650 { 1664 1651 struct xe_device *xe = ct_to_xe(ct); 1665 1652 struct xe_guc_ct_snapshot *snapshot; 1666 1653 1667 - snapshot = xe_guc_ct_snapshot_alloc(ct, atomic); 1654 + snapshot = guc_ct_snapshot_alloc(ct, atomic, want_ctb); 1668 1655 if (!snapshot) { 1669 1656 xe_gt_err(ct_to_gt(ct), "Skipping CTB snapshot entirely.\n"); 1670 1657 return NULL; ··· 1669 1680 xe_map_memcpy_from(xe, snapshot->ctb, &ct->bo->vmap, 0, snapshot->ctb_size); 1670 1681 1671 1682 return snapshot; 1683 + } 1684 + 1685 + /** 1686 + * xe_guc_ct_snapshot_capture - Take a quick snapshot of the CT state. 1687 + * @ct: GuC CT object. 1688 + * 1689 + * This can be printed out in a later stage like during dev_coredump 1690 + * analysis. This is safe to be called during atomic context. 1691 + * 1692 + * Returns: a GuC CT snapshot object that must be freed by the caller 1693 + * by using `xe_guc_ct_snapshot_free`. 1694 + */ 1695 + struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_capture(struct xe_guc_ct *ct) 1696 + { 1697 + return guc_ct_snapshot_capture(ct, true, true); 1672 1698 } 1673 1699 1674 1700 /** ··· 1708 1704 drm_printf(p, "\tg2h outstanding: %d\n", 1709 1705 snapshot->g2h_outstanding); 1710 1706 1711 - if (snapshot->ctb) { 1707 + if (snapshot->ctb) 1712 1708 xe_print_blob_ascii85(p, "CTB data", snapshot->ctb, 0, snapshot->ctb_size); 1713 - } else { 1714 - drm_printf(p, "CTB snapshot missing!\n"); 1715 - return; 1716 - } 1717 1709 } else { 1718 1710 drm_puts(p, "CT disabled\n"); 1719 1711 } ··· 1735 1735 * xe_guc_ct_print - GuC CT Print. 1736 1736 * @ct: GuC CT. 1737 1737 * @p: drm_printer where it will be printed out. 1738 + * @want_ctb: Should the full CTB content be dumped (vs just the headers) 1738 1739 * 1739 - * This function quickly capture a snapshot and immediately print it out. 1740 + * This function will quickly capture a snapshot of the CT state 1741 + * and immediately print it out. 1740 1742 */ 1741 - void xe_guc_ct_print(struct xe_guc_ct *ct, struct drm_printer *p) 1743 + void xe_guc_ct_print(struct xe_guc_ct *ct, struct drm_printer *p, bool want_ctb) 1742 1744 { 1743 1745 struct xe_guc_ct_snapshot *snapshot; 1744 1746 1745 - snapshot = xe_guc_ct_snapshot_capture(ct, false); 1747 + snapshot = guc_ct_snapshot_capture(ct, false, want_ctb); 1746 1748 xe_guc_ct_snapshot_print(snapshot, p); 1747 1749 xe_guc_ct_snapshot_free(snapshot); 1748 1750 } ··· 1778 1776 return; 1779 1777 1780 1778 snapshot_log = xe_guc_log_snapshot_capture(&guc->log, true); 1781 - snapshot_ct = xe_guc_ct_snapshot_capture((ct), true); 1779 + snapshot_ct = xe_guc_ct_snapshot_capture((ct)); 1782 1780 1783 1781 spin_lock_irqsave(&ct->dead.lock, flags); 1784 1782
+2 -3
drivers/gpu/drm/xe/xe_guc_ct.h
··· 17 17 void xe_guc_ct_stop(struct xe_guc_ct *ct); 18 18 void xe_guc_ct_fast_path(struct xe_guc_ct *ct); 19 19 20 - struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_alloc(struct xe_guc_ct *ct, bool atomic); 21 - struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_capture(struct xe_guc_ct *ct, bool atomic); 20 + struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_capture(struct xe_guc_ct *ct); 22 21 void xe_guc_ct_snapshot_print(struct xe_guc_ct_snapshot *snapshot, struct drm_printer *p); 23 22 void xe_guc_ct_snapshot_free(struct xe_guc_ct_snapshot *snapshot); 24 - void xe_guc_ct_print(struct xe_guc_ct *ct, struct drm_printer *p); 23 + void xe_guc_ct_print(struct xe_guc_ct *ct, struct drm_printer *p, bool want_ctb); 25 24 26 25 static inline bool xe_guc_ct_enabled(struct xe_guc_ct *ct) 27 26 {
+14
drivers/gpu/drm/xe/xe_guc_debugfs.c
··· 47 47 return 0; 48 48 } 49 49 50 + static int guc_ctb(struct seq_file *m, void *data) 51 + { 52 + struct xe_guc *guc = node_to_guc(m->private); 53 + struct xe_device *xe = guc_to_xe(guc); 54 + struct drm_printer p = drm_seq_file_printer(m); 55 + 56 + xe_pm_runtime_get(xe); 57 + xe_guc_ct_print(&guc->ct, &p, true); 58 + xe_pm_runtime_put(xe); 59 + 60 + return 0; 61 + } 62 + 50 63 static const struct drm_info_list debugfs_list[] = { 51 64 {"guc_info", guc_info, 0}, 52 65 {"guc_log", guc_log, 0}, 66 + {"guc_ctb", guc_ctb, 0}, 53 67 }; 54 68 55 69 void xe_guc_debugfs_register(struct xe_guc *guc, struct dentry *parent)