drm/i915/slpc: Balance the inc/dec for num_waiters
authorVinay Belgaumkar <vinay.belgaumkar@intel.com>
Mon, 28 Apr 2025 18:35:55 +0000 (11:35 -0700)
committerJani Nikula <jani.nikula@intel.com>
Mon, 5 May 2025 09:36:04 +0000 (12:36 +0300)
As seen in some recent failures, SLPC num_waiters value is < 0.
This happens because the inc/dec are not balanced. We should skip
decrement for the same conditions as the increment. Currently, we
do that for power saving profile mode. This patch also ensures that
num_waiters is incremented in the case min_softlimit is at boost
freq. It ensures that we don't reduce the frequency while this request
is in flight.

v2: Add Fixes tags

Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13598
Fixes: f864a29afc32 ("drm/i915/slpc: Optmize waitboost for SLPC")
Fixes: 4a82ceb04ad4 ("drm/i915/slpc: Add sysfs for SLPC power profiles")
Cc: Sk Anirban <sk.anirban@intel.com>
Reviewed-by: Sk Anirban <sk.anirban@intel.com>
Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Link: https://lore.kernel.org/r/20250428183555.3250021-1-vinay.belgaumkar@intel.com
(cherry picked from commit d26e55085f4b7a63677670db827541209257b313)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
drivers/gpu/drm/i915/gt/intel_rps.c

index 64e9317f58fb6fa9ef3e943386fee8870881ca97..71ee01d9ef642ccb97a6775a5d75c940184eacab 100644 (file)
@@ -1001,6 +1001,10 @@ void intel_rps_dec_waiters(struct intel_rps *rps)
        if (rps_uses_slpc(rps)) {
                slpc = rps_to_slpc(rps);
 
+               /* Don't decrement num_waiters for req where increment was skipped */
+               if (slpc->power_profile == SLPC_POWER_PROFILES_POWER_SAVING)
+                       return;
+
                intel_guc_slpc_dec_waiters(slpc);
        } else {
                atomic_dec(&rps->num_waiters);
@@ -1029,11 +1033,15 @@ void intel_rps_boost(struct i915_request *rq)
                        if (slpc->power_profile == SLPC_POWER_PROFILES_POWER_SAVING)
                                return;
 
-                       if (slpc->min_freq_softlimit >= slpc->boost_freq)
-                               return;
-
                        /* Return if old value is non zero */
                        if (!atomic_fetch_inc(&slpc->num_waiters)) {
+                               /*
+                                * Skip queuing boost work if frequency is already boosted,
+                                * but still increment num_waiters.
+                                */
+                               if (slpc->min_freq_softlimit >= slpc->boost_freq)
+                                       return;
+
                                GT_TRACE(rps_to_gt(rps), "boost fence:%llx:%llx\n",
                                         rq->fence.context, rq->fence.seqno);
                                queue_work(rps_to_gt(rps)->i915->unordered_wq,