drm/i915: Free RPS boosts for all laggards
authorChris Wilson <chris@chris-wilson.co.uk>
Mon, 27 Apr 2015 12:41:24 +0000 (13:41 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 21 May 2015 20:50:05 +0000 (22:50 +0200)
If the client stalls on a congested request, chosen to be 20ms old to
match throttling, allow the client a free RPS boost.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
[danvet: s/rq/req/]
[danvet: s/0/NULL/ reported by 0-day build]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_pm.c

index 289178b7e684175e9caeb1334437934c01064236..50e49a3d7e51c218afb7582ab62cb247f3d52695 100644 (file)
@@ -1245,7 +1245,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
                jiffies + nsecs_to_jiffies_timeout((u64)*timeout) : 0;
 
        if (INTEL_INFO(dev_priv)->gen >= 6)
-               gen6_rps_boost(dev_priv, rps);
+               gen6_rps_boost(dev_priv, rps, req->emitted_jiffies);
 
        /* Record current time in case interrupted by signal, or wedged */
        trace_i915_gem_request_wait_begin(req);
index 6968e7483863c166a083f27be6648783f05aaa32..e94cb6e1645606e2ae868fa14aded4aa23a6932d 100644 (file)
@@ -1365,7 +1365,8 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv);
 void gen6_rps_reset_ei(struct drm_i915_private *dev_priv);
 void gen6_rps_idle(struct drm_i915_private *dev_priv);
 void gen6_rps_boost(struct drm_i915_private *dev_priv,
-                   struct intel_rps_client *rps);
+                   struct intel_rps_client *rps,
+                   unsigned long submitted);
 void intel_queue_rps_boost_for_request(struct drm_device *dev,
                                       struct drm_i915_gem_request *req);
 void ilk_wm_get_hw_state(struct drm_device *dev);
index b676fe81c56382aa9cf0e8f7ebe9778ab1dfa68c..6414b27692d43a77984585b0c867cf6267b53f87 100644 (file)
@@ -4150,10 +4150,17 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
 }
 
 void gen6_rps_boost(struct drm_i915_private *dev_priv,
-                   struct intel_rps_client *rps)
+                   struct intel_rps_client *rps,
+                   unsigned long submitted)
 {
        u32 val;
 
+       /* Force a RPS boost (and don't count it against the client) if
+        * the GPU is severely congested.
+        */
+       if (rps && time_after(jiffies, submitted + msecs_to_jiffies(20)))
+               rps = NULL;
+
        mutex_lock(&dev_priv->rps.hw_lock);
        val = dev_priv->rps.max_freq_softlimit;
        if (dev_priv->rps.enabled &&
@@ -6848,11 +6855,13 @@ struct request_boost {
 static void __intel_rps_boost_work(struct work_struct *work)
 {
        struct request_boost *boost = container_of(work, struct request_boost, work);
+       struct drm_i915_gem_request *req = boost->req;
 
-       if (!i915_gem_request_completed(boost->req, true))
-               gen6_rps_boost(to_i915(boost->req->ring->dev), NULL);
+       if (!i915_gem_request_completed(req, true))
+               gen6_rps_boost(to_i915(req->ring->dev), NULL,
+                              req->emitted_jiffies);
 
-       i915_gem_request_unreference__unlocked(boost->req);
+       i915_gem_request_unreference__unlocked(req);
        kfree(boost);
 }
 
@@ -6864,6 +6873,9 @@ void intel_queue_rps_boost_for_request(struct drm_device *dev,
        if (req == NULL || INTEL_INFO(dev)->gen < 6)
                return;
 
+       if (i915_gem_request_completed(req, true))
+               return;
+
        boost = kmalloc(sizeof(*boost), GFP_ATOMIC);
        if (boost == NULL)
                return;