OSDN Git Service

drm/i915: Remove unsafe i915.enable_rc6
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 1 Dec 2017 11:30:30 +0000 (11:30 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 1 Dec 2017 15:20:02 +0000 (15:20 +0000)
It has been many years since the last confirmed sighting (and fix) of an
RC6 related bug (usually a system hang). Remove the parameter to stop
users from setting dangerous values, as they often set it during triage
and end up disabling the entire runtime pm instead (the option is not a
fine scalpel!).

Furthermore, it allows users to set known dangerous values which were
intended for testing and not for production use. For testing, we can
always patch in the required setting without having to expose ourselves
to random abuse.

v2: Fixup NEEDS_WaRsDisableCoarsePowerGating fumble, and document the
lack of ilk support better.
v3: Clear intel_info->rc6p if we don't support rc6 itself.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171201113030.18360-1-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_params.c
drivers/gpu/drm/i915/i915_params.h
drivers/gpu/drm/i915/i915_pci.c
drivers/gpu/drm/i915/i915_pmu.c
drivers/gpu/drm/i915/i915_sysfs.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_guc.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_uncore.c

index 43fbff4..962d7c7 100644 (file)
@@ -2527,7 +2527,7 @@ static int intel_runtime_suspend(struct device *kdev)
        struct drm_i915_private *dev_priv = to_i915(dev);
        int ret;
 
-       if (WARN_ON_ONCE(!(dev_priv->gt_pm.rc6.enabled && intel_rc6_enabled())))
+       if (WARN_ON_ONCE(!(dev_priv->gt_pm.rc6.enabled && HAS_RC6(dev_priv))))
                return -ENODEV;
 
        if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv)))
index bddd658..e8dc7b7 100644 (file)
@@ -3213,8 +3213,10 @@ intel_info(const struct drm_i915_private *dev_priv)
 #define HAS_DDI(dev_priv)               ((dev_priv)->info.has_ddi)
 #define HAS_FPGA_DBG_UNCLAIMED(dev_priv) ((dev_priv)->info.has_fpga_dbg)
 #define HAS_PSR(dev_priv)               ((dev_priv)->info.has_psr)
+
 #define HAS_RC6(dev_priv)               ((dev_priv)->info.has_rc6)
 #define HAS_RC6p(dev_priv)              ((dev_priv)->info.has_rc6p)
+#define HAS_RC6pp(dev_priv)             (false) /* HW was never validated */
 
 #define HAS_CSR(dev_priv)      ((dev_priv)->info.has_csr)
 
index 3328147..7bc5386 100644 (file)
@@ -46,13 +46,6 @@ i915_param_named_unsafe(panel_ignore_lid, int, 0600,
        "Override lid status (0=autodetect, 1=autodetect disabled [default], "
        "-1=force lid closed, -2=force lid open)");
 
-i915_param_named_unsafe(enable_rc6, int, 0400,
-       "Enable power-saving render C-state 6. "
-       "Different stages can be selected via bitmask values "
-       "(0 = disable; 1 = enable rc6; 2 = enable deep rc6; 4 = enable deepest rc6). "
-       "For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. "
-       "default: -1 (use per-chip default)");
-
 i915_param_named_unsafe(enable_dc, int, 0400,
        "Enable power-saving display C-states. "
        "(-1=auto [default]; 0=disable; 1=up to DC5; 2=up to DC6)");
index 8321bd8..c48c88b 100644 (file)
@@ -34,7 +34,6 @@
        param(int, lvds_channel_mode, 0) \
        param(int, panel_use_ssc, -1) \
        param(int, vbt_sdvo_panel_type, -1) \
-       param(int, enable_rc6, -1) \
        param(int, enable_dc, -1) \
        param(int, enable_fbc, -1) \
        param(int, enable_ppgtt, -1) \
index 6458c30..fa67d3d 100644 (file)
@@ -209,6 +209,8 @@ static const struct intel_device_info intel_gm45_info __initconst = {
        .has_hotplug = 1, \
        .ring_mask = RENDER_RING | BSD_RING, \
        .has_snoop = true, \
+       /* ilk does support rc6, but we do not implement [power] contexts */ \
+       .has_rc6 = 0, \
        GEN_DEFAULT_PIPEOFFSETS, \
        GEN_DEFAULT_PAGE_SIZES, \
        CURSOR_OFFSETS
index e8e2faf..55a8a1e 100644 (file)
@@ -413,12 +413,12 @@ static u64 __i915_pmu_event_read(struct perf_event *event)
                                                     IS_VALLEYVIEW(i915) ?
                                                     VLV_GT_RENDER_RC6 :
                                                     GEN6_GT_GFX_RC6);
-                       if (HAS_RC6p(i915)) {
+                       if (HAS_RC6p(i915))
                                val += intel_rc6_residency_ns(i915,
                                                              GEN6_GT_GFX_RC6p);
+                       if (HAS_RC6pp(i915))
                                val += intel_rc6_residency_ns(i915,
                                                              GEN6_GT_GFX_RC6pp);
-                       }
                        intel_runtime_pm_put(i915);
                        break;
                }
index c290cb6..c74a20b 100644 (file)
@@ -54,7 +54,18 @@ static u32 calc_residency(struct drm_i915_private *dev_priv,
 static ssize_t
 show_rc6_mask(struct device *kdev, struct device_attribute *attr, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%x\n", intel_rc6_enabled());
+       struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
+       unsigned int mask;
+
+       mask = 0;
+       if (HAS_RC6(dev_priv))
+               mask |= BIT(0);
+       if (HAS_RC6p(dev_priv))
+               mask |= BIT(1);
+       if (HAS_RC6pp(dev_priv))
+               mask |= BIT(2);
+
+       return snprintf(buf, PAGE_SIZE, "%x\n", mask);
 }
 
 static ssize_t
index 82d637d..30f791f 100644 (file)
@@ -1908,15 +1908,10 @@ bool skl_ddb_allocation_overlaps(struct drm_i915_private *dev_priv,
                                 const struct skl_ddb_entry *ddb,
                                 int ignore);
 bool ilk_disable_lp_wm(struct drm_device *dev);
-int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6);
 int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
                                  struct intel_crtc_state *cstate);
 void intel_init_ipc(struct drm_i915_private *dev_priv);
 void intel_enable_ipc(struct drm_i915_private *dev_priv);
-static inline int intel_rc6_enabled(void)
-{
-       return i915_modparams.enable_rc6;
-}
 
 /* intel_sdvo.c */
 bool intel_sdvo_init(struct drm_i915_private *dev_priv,
index 823d0c2..d08e760 100644 (file)
@@ -231,8 +231,7 @@ int intel_guc_sample_forcewake(struct intel_guc *guc)
 
        action[0] = INTEL_GUC_ACTION_SAMPLE_FORCEWAKE;
        /* WaRsDisableCoarsePowerGating:skl,bxt */
-       if (!intel_rc6_enabled() ||
-           NEEDS_WaRsDisableCoarsePowerGating(dev_priv))
+       if (!HAS_RC6(dev_priv) || NEEDS_WaRsDisableCoarsePowerGating(dev_priv))
                action[1] = 0;
        else
                /* bit 0 and 1 are for Render and Media domain separately */
index a80c322..67f3262 100644 (file)
@@ -52,9 +52,6 @@
  * which brings the most power savings; deeper states save more power, but
  * require higher latency to switch to and wake up.
  */
-#define INTEL_RC6_ENABLE                       (1<<0)
-#define INTEL_RC6p_ENABLE                      (1<<1)
-#define INTEL_RC6pp_ENABLE                     (1<<2)
 
 static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
 {
@@ -6417,26 +6414,6 @@ static void valleyview_disable_rps(struct drm_i915_private *dev_priv)
        I915_WRITE(GEN6_RP_CONTROL, 0);
 }
 
-static void intel_print_rc6_info(struct drm_i915_private *dev_priv, u32 mode)
-{
-       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
-               if (mode & (GEN7_RC_CTL_TO_MODE | GEN6_RC_CTL_EI_MODE(1)))
-                       mode = GEN6_RC_CTL_RC6_ENABLE;
-               else
-                       mode = 0;
-       }
-       if (HAS_RC6p(dev_priv))
-               DRM_DEBUG_DRIVER("Enabling RC6 states: "
-                                "RC6 %s RC6p %s RC6pp %s\n",
-                                onoff(mode & GEN6_RC_CTL_RC6_ENABLE),
-                                onoff(mode & GEN6_RC_CTL_RC6p_ENABLE),
-                                onoff(mode & GEN6_RC_CTL_RC6pp_ENABLE));
-
-       else
-               DRM_DEBUG_DRIVER("Enabling RC6 states: RC6 %s\n",
-                                onoff(mode & GEN6_RC_CTL_RC6_ENABLE));
-}
-
 static bool bxt_check_bios_rc6_setup(struct drm_i915_private *dev_priv)
 {
        struct i915_ggtt *ggtt = &dev_priv->ggtt;
@@ -6499,42 +6476,30 @@ static bool bxt_check_bios_rc6_setup(struct drm_i915_private *dev_priv)
        return enable_rc6;
 }
 
-int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6)
+static bool sanitize_rc6(struct drm_i915_private *i915)
 {
-       /* No RC6 before Ironlake and code is gone for ilk. */
-       if (INTEL_INFO(dev_priv)->gen < 6)
-               return 0;
+       struct intel_device_info *info = mkwrite_device_info(i915);
 
-       if (!enable_rc6)
-               return 0;
+       /* Powersaving is controlled by the host when inside a VM */
+       if (intel_vgpu_active(i915))
+               info->has_rc6 = 0;
 
-       if (IS_GEN9_LP(dev_priv) && !bxt_check_bios_rc6_setup(dev_priv)) {
+       if (info->has_rc6 &&
+           IS_GEN9_LP(i915) && !bxt_check_bios_rc6_setup(i915)) {
                DRM_INFO("RC6 disabled by BIOS\n");
-               return 0;
+               info->has_rc6 = 0;
        }
 
-       /* Respect the kernel parameter if it is set */
-       if (enable_rc6 >= 0) {
-               int mask;
-
-               if (HAS_RC6p(dev_priv))
-                       mask = INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE |
-                              INTEL_RC6pp_ENABLE;
-               else
-                       mask = INTEL_RC6_ENABLE;
-
-               if ((enable_rc6 & mask) != enable_rc6)
-                       DRM_DEBUG_DRIVER("Adjusting RC6 mask to %d "
-                                        "(requested %d, valid %d)\n",
-                                        enable_rc6 & mask, enable_rc6, mask);
-
-               return enable_rc6 & mask;
-       }
-
-       if (IS_IVYBRIDGE(dev_priv))
-               return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE);
+       /*
+        * We assume that we do not have any deep rc6 levels if we don't have
+        * have the previous rc6 level supported, i.e. we use HAS_RC6()
+        * as the initial coarse check for rc6 in general, moving on to
+        * progressively finer/deeper levels.
+        */
+       if (!info->has_rc6 && info->has_rc6p)
+               info->has_rc6p = 0;
 
-       return INTEL_RC6_ENABLE;
+       return info->has_rc6;
 }
 
 static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
@@ -6627,7 +6592,7 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv)
 {
        struct intel_engine_cs *engine;
        enum intel_engine_id id;
-       u32 rc6_mode, rc6_mask = 0;
+       u32 rc6_mode;
 
        /* 1a: Software RC state - RC0 */
        I915_WRITE(GEN6_RC_STATE, 0);
@@ -6668,9 +6633,6 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv)
        I915_WRITE(GEN9_RENDER_PG_IDLE_HYSTERESIS, 25);
 
        /* 3a: Enable RC6 */
-       if (intel_rc6_enabled() & INTEL_RC6_ENABLE)
-               rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
-       DRM_INFO("RC6 %s\n", onoff(rc6_mask & GEN6_RC_CTL_RC6_ENABLE));
        I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */
 
        /* WaRsUseTimeoutMode:cnl (pre-prod) */
@@ -6680,7 +6642,9 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv)
                rc6_mode = GEN6_RC_CTL_EI_MODE(1);
 
        I915_WRITE(GEN6_RC_CONTROL,
-                  GEN6_RC_CTL_HW_ENABLE | rc6_mode | rc6_mask);
+                  GEN6_RC_CTL_HW_ENABLE |
+                  GEN6_RC_CTL_RC6_ENABLE |
+                  rc6_mode);
 
        /*
         * 3b: Enable Coarse Power Gating only when RC6 is enabled.
@@ -6689,8 +6653,8 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv)
        if (NEEDS_WaRsDisableCoarsePowerGating(dev_priv))
                I915_WRITE(GEN9_PG_ENABLE, 0);
        else
-               I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
-                               (GEN9_RENDER_PG_ENABLE | GEN9_MEDIA_PG_ENABLE) : 0);
+               I915_WRITE(GEN9_PG_ENABLE,
+                          GEN9_RENDER_PG_ENABLE | GEN9_MEDIA_PG_ENABLE);
 
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
@@ -6699,7 +6663,6 @@ static void gen8_enable_rc6(struct drm_i915_private *dev_priv)
 {
        struct intel_engine_cs *engine;
        enum intel_engine_id id;
-       uint32_t rc6_mask = 0;
 
        /* 1a: Software RC state - RC0 */
        I915_WRITE(GEN6_RC_STATE, 0);
@@ -6721,13 +6684,11 @@ static void gen8_enable_rc6(struct drm_i915_private *dev_priv)
        I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us/1.28 for TO */
 
        /* 3: Enable RC6 */
-       if (intel_rc6_enabled() & INTEL_RC6_ENABLE)
-               rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
-       intel_print_rc6_info(dev_priv, rc6_mask);
 
-       I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
-                       GEN7_RC_CTL_TO_MODE |
-                       rc6_mask);
+       I915_WRITE(GEN6_RC_CONTROL,
+                  GEN6_RC_CTL_HW_ENABLE |
+                  GEN7_RC_CTL_TO_MODE |
+                  GEN6_RC_CTL_RC6_ENABLE);
 
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
@@ -6776,9 +6737,8 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv)
 {
        struct intel_engine_cs *engine;
        enum intel_engine_id id;
-       u32 rc6vids, rc6_mask = 0;
+       u32 rc6vids, rc6_mask;
        u32 gtfifodbg;
-       int rc6_mode;
        int ret;
 
        I915_WRITE(GEN6_RC_STATE, 0);
@@ -6813,22 +6773,12 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv)
        I915_WRITE(GEN6_RC6p_THRESHOLD, 150000);
        I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
 
-       /* Check if we are enabling RC6 */
-       rc6_mode = intel_rc6_enabled();
-       if (rc6_mode & INTEL_RC6_ENABLE)
-               rc6_mask |= GEN6_RC_CTL_RC6_ENABLE;
-
        /* We don't use those on Haswell */
-       if (!IS_HASWELL(dev_priv)) {
-               if (rc6_mode & INTEL_RC6p_ENABLE)
-                       rc6_mask |= GEN6_RC_CTL_RC6p_ENABLE;
-
-               if (rc6_mode & INTEL_RC6pp_ENABLE)
-                       rc6_mask |= GEN6_RC_CTL_RC6pp_ENABLE;
-       }
-
-       intel_print_rc6_info(dev_priv, rc6_mask);
-
+       rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
+       if (HAS_RC6p(dev_priv))
+               rc6_mask |= GEN6_RC_CTL_RC6p_ENABLE;
+       if (HAS_RC6pp(dev_priv))
+               rc6_mask |= GEN6_RC_CTL_RC6pp_ENABLE;
        I915_WRITE(GEN6_RC_CONTROL,
                   rc6_mask |
                   GEN6_RC_CTL_EI_MODE(1) |
@@ -7271,7 +7221,7 @@ static void cherryview_enable_rc6(struct drm_i915_private *dev_priv)
 {
        struct intel_engine_cs *engine;
        enum intel_engine_id id;
-       u32 gtfifodbg, rc6_mode = 0, pcbr;
+       u32 gtfifodbg, rc6_mode, pcbr;
 
        gtfifodbg = I915_READ(GTFIFODBG) & ~(GT_FIFO_SBDEDICATE_FREE_ENTRY_CHV |
                                             GT_FIFO_FREE_ENTRIES_CHV);
@@ -7312,10 +7262,9 @@ static void cherryview_enable_rc6(struct drm_i915_private *dev_priv)
        pcbr = I915_READ(VLV_PCBR);
 
        /* 3: Enable RC6 */
-       if ((intel_rc6_enabled() & INTEL_RC6_ENABLE) &&
-           (pcbr >> VLV_PCBR_ADDR_SHIFT))
+       rc6_mode = 0;
+       if (pcbr >> VLV_PCBR_ADDR_SHIFT)
                rc6_mode = GEN7_RC_CTL_TO_MODE;
-
        I915_WRITE(GEN6_RC_CONTROL, rc6_mode);
 
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
@@ -7367,7 +7316,7 @@ static void valleyview_enable_rc6(struct drm_i915_private *dev_priv)
 {
        struct intel_engine_cs *engine;
        enum intel_engine_id id;
-       u32 gtfifodbg, rc6_mode = 0;
+       u32 gtfifodbg;
 
        valleyview_check_pctx(dev_priv);
 
@@ -7400,12 +7349,8 @@ static void valleyview_enable_rc6(struct drm_i915_private *dev_priv)
                                      VLV_MEDIA_RC6_COUNT_EN |
                                      VLV_RENDER_RC6_COUNT_EN));
 
-       if (intel_rc6_enabled() & INTEL_RC6_ENABLE)
-               rc6_mode = GEN7_RC_CTL_TO_MODE | VLV_RC_CTL_CTX_RST_PARALLEL;
-
-       intel_print_rc6_info(dev_priv, rc6_mode);
-
-       I915_WRITE(GEN6_RC_CONTROL, rc6_mode);
+       I915_WRITE(GEN6_RC_CONTROL,
+                  GEN7_RC_CTL_TO_MODE | VLV_RC_CTL_CTX_RST_PARALLEL);
 
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
@@ -7932,7 +7877,7 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
         * RPM depends on RC6 to save restore the GT HW context, so make RC6 a
         * requirement.
         */
-       if (!i915_modparams.enable_rc6) {
+       if (!sanitize_rc6(dev_priv)) {
                DRM_INFO("RC6 disabled, disabling runtime PM support\n");
                intel_runtime_pm_get(dev_priv);
        }
@@ -7985,7 +7930,7 @@ void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv)
        if (IS_VALLEYVIEW(dev_priv))
                valleyview_cleanup_gt_powersave(dev_priv);
 
-       if (!i915_modparams.enable_rc6)
+       if (!HAS_RC6(dev_priv))
                intel_runtime_pm_put(dev_priv);
 }
 
@@ -8152,7 +8097,8 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
 
        mutex_lock(&dev_priv->pcu_lock);
 
-       intel_enable_rc6(dev_priv);
+       if (HAS_RC6(dev_priv))
+               intel_enable_rc6(dev_priv);
        intel_enable_rps(dev_priv);
        if (HAS_LLC(dev_priv))
                intel_enable_llc_pstate(dev_priv);
@@ -9444,7 +9390,7 @@ u64 intel_rc6_residency_ns(struct drm_i915_private *dev_priv,
        u64 time_hw;
        u32 mul, div;
 
-       if (!intel_rc6_enabled())
+       if (!HAS_RC6(dev_priv))
                return 0;
 
        /* On VLV and CHV, residency time is in CZ units rather than 1.28us */
index b462127..89547b6 100644 (file)
@@ -565,9 +565,6 @@ void intel_uncore_runtime_resume(struct drm_i915_private *dev_priv)
 
 void intel_uncore_sanitize(struct drm_i915_private *dev_priv)
 {
-       i915_modparams.enable_rc6 =
-               sanitize_rc6_option(dev_priv, i915_modparams.enable_rc6);
-
        /* BIOS often leaves RC6 enabled, but disable it for hw init */
        intel_sanitize_gt_powersave(dev_priv);
 }