drm/xe: Add performance tunings to debugfs
authorTvrtko Ursulin <tvrtko.ursulin@igalia.com>
Thu, 27 Feb 2025 10:13:04 +0000 (10:13 +0000)
committerLucas De Marchi <lucas.demarchi@intel.com>
Sat, 1 Mar 2025 05:47:33 +0000 (21:47 -0800)
Add a list of active tunings to debugfs, analogous to the existing
list of workarounds.

Rationale being that it seems to make sense to either have both or none.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250227101304.46660-6-tvrtko.ursulin@igalia.com
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
drivers/gpu/drm/xe/xe_gt.c
drivers/gpu/drm/xe/xe_gt_debugfs.c
drivers/gpu/drm/xe/xe_gt_types.h
drivers/gpu/drm/xe/xe_tuning.c
drivers/gpu/drm/xe/xe_tuning.h

index 90ff51ad76a635beb54597726a67462e39580f43..10a9e3c72b3604b0276f6e42985c9737ab36638f 100644 (file)
@@ -362,6 +362,10 @@ int xe_gt_init_early(struct xe_gt *gt)
        if (err)
                return err;
 
+       err = xe_tuning_init(gt);
+       if (err)
+               return err;
+
        xe_wa_process_oob(gt);
 
        xe_force_wake_init_gt(gt, gt_to_fw(gt));
index e7792858b1e46626bd35630414bc62a446be9210..2d63a69cbfa38e59b04416412b978f02168ecdeb 100644 (file)
@@ -30,6 +30,7 @@
 #include "xe_reg_sr.h"
 #include "xe_reg_whitelist.h"
 #include "xe_sriov.h"
+#include "xe_tuning.h"
 #include "xe_uc_debugfs.h"
 #include "xe_wa.h"
 
@@ -217,6 +218,15 @@ static int workarounds(struct xe_gt *gt, struct drm_printer *p)
        return 0;
 }
 
+static int tunings(struct xe_gt *gt, struct drm_printer *p)
+{
+       xe_pm_runtime_get(gt_to_xe(gt));
+       xe_tuning_dump(gt, p);
+       xe_pm_runtime_put(gt_to_xe(gt));
+
+       return 0;
+}
+
 static int pat(struct xe_gt *gt, struct drm_printer *p)
 {
        xe_pm_runtime_get(gt_to_xe(gt));
@@ -300,6 +310,7 @@ static const struct drm_info_list debugfs_list[] = {
        {"powergate_info", .show = xe_gt_debugfs_simple_show, .data = powergate_info},
        {"register-save-restore", .show = xe_gt_debugfs_simple_show, .data = register_save_restore},
        {"workarounds", .show = xe_gt_debugfs_simple_show, .data = workarounds},
+       {"tunings", .show = xe_gt_debugfs_simple_show, .data = tunings},
        {"pat", .show = xe_gt_debugfs_simple_show, .data = pat},
        {"mocs", .show = xe_gt_debugfs_simple_show, .data = mocs},
        {"default_lrc_rcs", .show = xe_gt_debugfs_simple_show, .data = rcs_default_lrc},
index f67474e06fb36abf1388837f228f401206a5f1fc..e3cfb026ac88ed1a152b4d6afa326885e841bd43 100644 (file)
@@ -413,6 +413,16 @@ struct xe_gt {
                bool oob_initialized;
        } wa_active;
 
+       /** @tuning_active: keep track of active tunings */
+       struct {
+               /** @tuning_active.gt: bitmap with active GT tunings */
+               unsigned long *gt;
+               /** @tuning_active.engine: bitmap with active engine tunings */
+               unsigned long *engine;
+               /** @tuning_active.lrc: bitmap with active LRC tunings */
+               unsigned long *lrc;
+       } tuning_active;
+
        /** @user_engines: engines present in GT and available to userspace */
        struct {
                /**
index 551c2f308e1c0d51a297143629c744d6e857e073..77bc958f5a42cd017d3c363825dfd05cd73f872e 100644 (file)
@@ -7,6 +7,8 @@
 
 #include <kunit/visibility.h>
 
+#include <drm/drm_managed.h>
+
 #include "regs/xe_gt_regs.h"
 #include "xe_gt_types.h"
 #include "xe_platform_types.h"
@@ -140,10 +142,44 @@ static const struct xe_rtp_entry_sr lrc_tunings[] = {
        {}
 };
 
+/**
+ * xe_tuning_init - initialize gt with tunings bookkeeping
+ * @gt: GT instance to initialize
+ *
+ * Returns 0 for success, negative error code otherwise.
+ */
+int xe_tuning_init(struct xe_gt *gt)
+{
+       struct xe_device *xe = gt_to_xe(gt);
+       size_t n_lrc, n_engine, n_gt, total;
+       unsigned long *p;
+
+       n_gt = BITS_TO_LONGS(ARRAY_SIZE(gt_tunings));
+       n_engine = BITS_TO_LONGS(ARRAY_SIZE(engine_tunings));
+       n_lrc = BITS_TO_LONGS(ARRAY_SIZE(lrc_tunings));
+       total = n_gt + n_engine + n_lrc;
+
+       p = drmm_kzalloc(&xe->drm, sizeof(*p) * total, GFP_KERNEL);
+       if (!p)
+               return -ENOMEM;
+
+       gt->tuning_active.gt = p;
+       p += n_gt;
+       gt->tuning_active.engine = p;
+       p += n_engine;
+       gt->tuning_active.lrc = p;
+
+       return 0;
+}
+ALLOW_ERROR_INJECTION(xe_tuning_init, ERRNO); /* See xe_pci_probe() */
+
 void xe_tuning_process_gt(struct xe_gt *gt)
 {
        struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(gt);
 
+       xe_rtp_process_ctx_enable_active_tracking(&ctx,
+                                                 gt->tuning_active.gt,
+                                                 ARRAY_SIZE(gt_tunings));
        xe_rtp_process_to_sr(&ctx, gt_tunings, &gt->reg_sr);
 }
 EXPORT_SYMBOL_IF_KUNIT(xe_tuning_process_gt);
@@ -152,6 +188,9 @@ void xe_tuning_process_engine(struct xe_hw_engine *hwe)
 {
        struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
 
+       xe_rtp_process_ctx_enable_active_tracking(&ctx,
+                                                 hwe->gt->tuning_active.engine,
+                                                 ARRAY_SIZE(engine_tunings));
        xe_rtp_process_to_sr(&ctx, engine_tunings, &hwe->reg_sr);
 }
 EXPORT_SYMBOL_IF_KUNIT(xe_tuning_process_engine);
@@ -168,5 +207,25 @@ void xe_tuning_process_lrc(struct xe_hw_engine *hwe)
 {
        struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
 
+       xe_rtp_process_ctx_enable_active_tracking(&ctx,
+                                                 hwe->gt->tuning_active.lrc,
+                                                 ARRAY_SIZE(lrc_tunings));
        xe_rtp_process_to_sr(&ctx, lrc_tunings, &hwe->reg_lrc);
 }
+
+void xe_tuning_dump(struct xe_gt *gt, struct drm_printer *p)
+{
+       size_t idx;
+
+       drm_printf(p, "GT Tunings\n");
+       for_each_set_bit(idx, gt->tuning_active.gt, ARRAY_SIZE(gt_tunings))
+               drm_printf_indent(p, 1, "%s\n", gt_tunings[idx].name);
+
+       drm_printf(p, "\nEngine Tunings\n");
+       for_each_set_bit(idx, gt->tuning_active.engine, ARRAY_SIZE(engine_tunings))
+               drm_printf_indent(p, 1, "%s\n", engine_tunings[idx].name);
+
+       drm_printf(p, "\nLRC Tunings\n");
+       for_each_set_bit(idx, gt->tuning_active.lrc, ARRAY_SIZE(lrc_tunings))
+               drm_printf_indent(p, 1, "%s\n", lrc_tunings[idx].name);
+}
index 4f9c3ac3b5162eed82ec8800e1fbad0a48b9610a..dd0d3ccc9c654cfdb1086411e30aff0d5ac225d2 100644 (file)
@@ -6,11 +6,14 @@
 #ifndef _XE_TUNING_
 #define _XE_TUNING_
 
+struct drm_printer;
 struct xe_gt;
 struct xe_hw_engine;
 
+int xe_tuning_init(struct xe_gt *gt);
 void xe_tuning_process_gt(struct xe_gt *gt);
 void xe_tuning_process_engine(struct xe_hw_engine *hwe);
 void xe_tuning_process_lrc(struct xe_hw_engine *hwe);
+void xe_tuning_dump(struct xe_gt *gt, struct drm_printer *p);
 
 #endif