]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
i915/guc: Ensure busyness counter increases motonically
authorUmesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Wed, 27 Nov 2024 17:40:05 +0000 (09:40 -0800)
committerUmesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Fri, 13 Dec 2024 23:13:50 +0000 (15:13 -0800)
Active busyness of an engine is calculated using gt timestamp and the
context switch in time. While capturing the gt timestamp, it's possible
that the context switches out. This race could result in an active
busyness value that is greater than the actual context runtime value by a
small amount. This leads to a negative delta and throws off busyness
calculations for the user.

If a subsequent count is smaller than the previous one, just return the
previous one, since we expect the busyness to catch up.

Fixes: 77cdd054dd2c ("drm/i915/pmu: Connect engine busyness stats from GuC to pmu")
Signed-off-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Reviewed-by: John Harrison <John.C.Harrison@Intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241127174006.190128-3-umesh.nerlige.ramappa@intel.com
drivers/gpu/drm/i915/gt/intel_engine_types.h
drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c

index ba55c059063dbb792acecce94270c4db6f4cf954..fe1f85e5dda330c78caa689d1927f91c0707ed62 100644 (file)
@@ -343,6 +343,11 @@ struct intel_engine_guc_stats {
         * @start_gt_clk: GT clock time of last idle to active transition.
         */
        u64 start_gt_clk;
+
+       /**
+        * @total: The last value of total returned
+        */
+       u64 total;
 };
 
 union intel_engine_tlb_inv_reg {
index 795058bb714118a833c20184abd5a7bce519d31f..43c9c5dc2eb516244c77a2928275caf683e2d0d8 100644 (file)
@@ -1378,9 +1378,12 @@ static ktime_t guc_engine_busyness(struct intel_engine_cs *engine, ktime_t *now)
                total += intel_gt_clock_interval_to_ns(gt, clk);
        }
 
+       if (total > stats->total)
+               stats->total = total;
+
        spin_unlock_irqrestore(&guc->timestamp.lock, flags);
 
-       return ns_to_ktime(total);
+       return ns_to_ktime(stats->total);
 }
 
 static void guc_enable_busyness_worker(struct intel_guc *guc)