Hi Airban,

On 10-06-2026 01:21, Sk Anirban wrote:
Add a GT debugfs entry that iterates over engines and reports
whether each engine is active or idle. This can help debug C6
issues by identifying engines that may be preventing the GT
from going idle.

Signed-off-by: Sk Anirban <sk.anirban@intel.com>
---
 drivers/gpu/drm/xe/xe_gt_debugfs.c | 31 +++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xe/xe_gt_debugfs.c b/drivers/gpu/drm/xe/xe_gt_debugfs.c
index f45306308cd6..d404467146d1 100644
--- a/drivers/gpu/drm/xe/xe_gt_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_gt_debugfs.c
@@ -10,6 +10,8 @@
 #include <drm/drm_debugfs.h>
 #include <drm/drm_managed.h>
 
+#include "regs/xe_engine_regs.h"
+
 #include "xe_device.h"
 #include "xe_force_wake.h"
 #include "xe_gt.h"
@@ -115,8 +117,10 @@ static int hw_engines(struct xe_gt *gt, struct drm_printer *p)
 	enum xe_hw_engine_id id;
 
 	CLASS(xe_force_wake, fw_ref)(gt_to_fw(gt), XE_FORCEWAKE_ALL);
-	if (!xe_force_wake_ref_has_domain(fw_ref.domains, XE_FORCEWAKE_ALL))
+	if (!xe_force_wake_ref_has_domain(fw_ref.domains, XE_FORCEWAKE_ALL)) {
+		drm_printf(p, "ERROR: Could not acquire forcewake\n");
 		return -ETIMEDOUT;
+	}
 
 	for_each_hw_engine(hwe, gt, id)
 		xe_hw_engine_print(hwe, p);
@@ -124,6 +128,30 @@ static int hw_engines(struct xe_gt *gt, struct drm_printer *p)
 	return 0;
 }
 
+static bool hw_engine_is_active(struct xe_hw_engine *hwe)
Should it be renamed as is_ring_empty or something similar ? Why the active ticks are nor being checked to evaluate the busyness ?  
+{
+	u32 head = xe_hw_engine_mmio_read32(hwe, RING_HEAD(0));
+	u32 tail = xe_hw_engine_mmio_read32(hwe, RING_TAIL(0));
+
+	return (head & HEAD_ADDR) != (tail & TAIL_ADDR);
+}
+
+static int hw_engine_status(struct xe_gt *gt, struct drm_printer *p)
+{
+	struct xe_hw_engine *hwe;
+	enum xe_hw_engine_id id;
+
+	CLASS(xe_force_wake, fw_ref)(gt_to_fw(gt), XE_FORCEWAKE_ALL);
+	if (!xe_force_wake_ref_has_domain(fw_ref.domains, XE_FORCEWAKE_ALL))

It silently returns -ETIMEDOUT on  failure. Better, a reason could be emitted as done for hw_engine().

Thanks, Soham

+		return -ETIMEDOUT;
+
+	for_each_hw_engine(hwe, gt, id)
+		drm_printf(p, "%s: %s\n", hwe->name,
+			   hw_engine_is_active(hwe) ? "active" : "idle");
+
+	return 0;
+}
+
 static int steering(struct xe_gt *gt, struct drm_printer *p)
 {
 	xe_gt_mcr_steering_dump(gt, p);
@@ -240,6 +268,7 @@ static const struct drm_info_list vf_safe_debugfs_list[] = {
 /* everything else should be added here */
 static const struct drm_info_list pf_only_debugfs_list[] = {
 	{ "hw_engines", .show = xe_gt_debugfs_show_with_rpm, .data = hw_engines },
+	{ "hw_engine_status", .show = xe_gt_debugfs_show_with_rpm, .data = hw_engine_status },
 	{ "mocs", .show = xe_gt_debugfs_show_with_rpm, .data = xe_mocs_dump },
 	{ "pat", .show = xe_gt_debugfs_show_with_rpm, .data = xe_pat_dump },
 	{ "powergate_info", .show = xe_gt_debugfs_show_with_rpm, .data = xe_gt_idle_pg_print },