]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/reset: Move pending_fb_pin handling to i915
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 15 Apr 2026 21:04:08 +0000 (00:04 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 16 Apr 2026 16:24:22 +0000 (19:24 +0300)
Only i915 uses the pending_fb_pin counter to potentially whack
the GPU harder if the display gets nuked during a GPU reset.
Move the atomic counter into the i915 specific bits of code, so
that we don't need to worry about on the display side.

For some reason the overlay code kept the pending_fb_pin counter
elevated for longer than just for the pin, but from now on it'll
just cover the actual pinning part.

Cc: Jouni Högander <jouni.hogander@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patch.msgid.link/20260415210411.24750-5-ville.syrjala@linux.intel.com
drivers/gpu/drm/i915/display/intel_display_core.h
drivers/gpu/drm/i915/display/intel_display_reset.c
drivers/gpu/drm/i915/display/intel_display_reset.h
drivers/gpu/drm/i915/display/intel_overlay.c
drivers/gpu/drm/i915/gt/intel_reset.c
drivers/gpu/drm/i915/i915_dpt.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_fb_pin.c
drivers/gpu/drm/i915/i915_overlay.c

index d9baca2d5aaf893a8d6f430baa19aed2537bbaba..38296a38372cdebb54731ffb0ceca0a17d83c9e5 100644 (file)
@@ -564,7 +564,6 @@ struct intel_display {
                struct drm_atomic_state *modeset_state;
                struct drm_modeset_acquire_ctx reset_ctx;
                /* modeset stuck tracking for reset */
-               atomic_t pending_fb_pin;
                u32 saveDSPARB;
                u32 saveSWF0[16];
                u32 saveSWF1[16];
index fc661c623cb82037e24dd401233ae01b7ddfc293..be4af74f0275f937f804bdcad9132d088c38fc91 100644 (file)
@@ -27,19 +27,12 @@ bool intel_display_reset_test(struct intel_display *display)
                display->params.force_reset_modeset_test;
 }
 
-void intel_display_reset_prepare(struct intel_display *display,
-                                modeset_stuck_fn modeset_stuck, void *context)
+void intel_display_reset_prepare(struct intel_display *display)
 {
        struct drm_modeset_acquire_ctx *ctx = &display->restore.reset_ctx;
        struct drm_atomic_state *state;
        int ret;
 
-       if (atomic_read(&display->restore.pending_fb_pin)) {
-               drm_dbg_kms(display->drm,
-                           "Modeset potentially stuck, unbreaking through wedging\n");
-               modeset_stuck(context);
-       }
-
        /*
         * Need mode_config.mutex so that we don't
         * trample ongoing ->detect() and whatnot.
index e0f15e757728c9e7ca97a14f7895f0e52faaa3ad..a8aa7729d33f6ca63fbbf5d63c056663873b8a5c 100644 (file)
 
 struct intel_display;
 
-typedef void modeset_stuck_fn(void *context);
-
 bool intel_display_reset_supported(struct intel_display *display);
 bool intel_display_reset_test(struct intel_display *display);
-void intel_display_reset_prepare(struct intel_display *display,
-                                modeset_stuck_fn modeset_stuck, void *context);
+void intel_display_reset_prepare(struct intel_display *display);
 void intel_display_reset_finish(struct intel_display *display, bool test_only);
 
 #endif /* __INTEL_RESET_H__ */
index 12a325ceae6fee6fae5ade3d38e06650ee268705..a809aa2950ac35820abb6df456155c23f21154b9 100644 (file)
@@ -481,13 +481,9 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
        if (ret != 0)
                return ret;
 
-       atomic_inc(&display->restore.pending_fb_pin);
-
        vma = intel_parent_overlay_pin_fb(display, obj, &offset);
-       if (IS_ERR(vma)) {
-               ret = PTR_ERR(vma);
-               goto out_pin_section;
-       }
+       if (IS_ERR(vma))
+               return PTR_ERR(vma);
 
        if (!intel_parent_overlay_is_active(display)) {
                const struct intel_crtc_state *crtc_state =
@@ -571,8 +567,6 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 
 out_unpin:
        intel_parent_overlay_unpin_fb(display, vma);
-out_pin_section:
-       atomic_dec(&display->restore.pending_fb_pin);
 
        return ret;
 }
index ffd11767874fe953a780225f1fcd3ffae9b118fd..a1e6aaca8c9b691fdca403b8c7e7d16c0f53dbb5 100644 (file)
@@ -1398,11 +1398,6 @@ int intel_engine_reset(struct intel_engine_cs *engine, const char *msg)
        return err;
 }
 
-static void display_reset_modeset_stuck(void *gt)
-{
-       intel_gt_set_wedged(gt);
-}
-
 static void intel_gt_reset_global(struct intel_gt *gt,
                                  u32 engine_mask,
                                  const char *reason)
@@ -1434,10 +1429,16 @@ static void intel_gt_reset_global(struct intel_gt *gt,
                        intel_display_reset_test(display) ||
                        need_display_reset;
 
-               if (reset_display)
-                       intel_display_reset_prepare(display,
-                                                   display_reset_modeset_stuck,
-                                                   gt);
+               if (reset_display) {
+                       if (atomic_read(&i915->pending_fb_pin)) {
+                               drm_dbg_kms(&i915->drm,
+                                           "Modeset potentially stuck, unbreaking through wedging\n");
+
+                               intel_gt_set_wedged(gt);
+                       }
+
+                       intel_display_reset_prepare(display);
+               }
 
                intel_gt_reset(gt, engine_mask, reason);
 
index 9f47bb563c858924de4a58731453c711846acd79..fcd7cced771d5281a9c4aa084bf9701fbbbb4e1b 100644 (file)
@@ -129,7 +129,6 @@ static void dpt_cleanup(struct i915_address_space *vm)
 struct i915_vma *i915_dpt_pin_to_ggtt(struct intel_dpt *dpt, unsigned int alignment)
 {
        struct drm_i915_private *i915 = dpt->vm.i915;
-       struct intel_display *display = i915->display;
        struct ref_tracker *wakeref;
        struct i915_vma *vma;
        void __iomem *iomem;
@@ -141,7 +140,7 @@ struct i915_vma *i915_dpt_pin_to_ggtt(struct intel_dpt *dpt, unsigned int alignm
                pin_flags |= PIN_MAPPABLE;
 
        wakeref = intel_runtime_pm_get(&i915->runtime_pm);
-       atomic_inc(&display->restore.pending_fb_pin);
+       atomic_inc(&i915->pending_fb_pin);
 
        for_i915_gem_ww(&ww, err, true) {
                err = i915_gem_object_lock(dpt->obj, &ww);
@@ -171,7 +170,7 @@ struct i915_vma *i915_dpt_pin_to_ggtt(struct intel_dpt *dpt, unsigned int alignm
 
        dpt->obj->mm.dirty = true;
 
-       atomic_dec(&display->restore.pending_fb_pin);
+       atomic_dec(&i915->pending_fb_pin);
        intel_runtime_pm_put(&i915->runtime_pm, wakeref);
 
        return err ? ERR_PTR(err) : vma;
index dafee3dcd1c521b895aac3d0c2895012d6c13284..844ed79e72114eafc0d6834d9f724ddd92813684 100644 (file)
@@ -315,6 +315,8 @@ struct drm_i915_private {
        /* The TTM device structure. */
        struct ttm_device bdev;
 
+       atomic_t pending_fb_pin;
+
        I915_SELFTEST_DECLARE(struct i915_selftest_stash selftest;)
 
        /*
index efd5cb726cf824b806bd31901dded845c64a8b7d..85649bae25fbde3e20765c85c52005cce03f5119 100644 (file)
@@ -28,7 +28,6 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb,
                    unsigned int alignment,
                    struct intel_dpt *dpt)
 {
-       struct intel_display *display = to_intel_display(fb->dev);
        struct drm_i915_private *i915 = to_i915(fb->dev);
        struct drm_gem_object *_obj = intel_fb_bo(fb);
        struct drm_i915_gem_object *obj = to_intel_bo(_obj);
@@ -47,7 +46,7 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb,
        if (WARN_ON(!i915_gem_object_is_framebuffer(obj)))
                return ERR_PTR(-EINVAL);
 
-       atomic_inc(&display->restore.pending_fb_pin);
+       atomic_inc(&i915->pending_fb_pin);
 
        for_i915_gem_ww(&ww, ret, true) {
                ret = i915_gem_object_lock(obj, &ww);
@@ -102,7 +101,7 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb,
 
        i915_vma_get(vma);
 err:
-       atomic_dec(&display->restore.pending_fb_pin);
+       atomic_dec(&i915->pending_fb_pin);
 
        return vma;
 }
@@ -140,7 +139,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
         */
        wakeref = intel_runtime_pm_get(&i915->runtime_pm);
 
-       atomic_inc(&display->restore.pending_fb_pin);
+       atomic_inc(&i915->pending_fb_pin);
 
        /*
         * Valleyview is definitely limited to scanning out the first
@@ -219,7 +218,7 @@ err:
        if (ret)
                vma = ERR_PTR(ret);
 
-       atomic_dec(&display->restore.pending_fb_pin);
+       atomic_dec(&i915->pending_fb_pin);
        intel_runtime_pm_put(&i915->runtime_pm, wakeref);
        return vma;
 }
index 2d7aff51e39b8e743fa435da524923a4885b5f36..6de550a17756718c277e417191ead5f4a8beb1be 100644 (file)
@@ -354,11 +354,14 @@ static struct i915_vma *i915_overlay_pin_fb(struct drm_device *drm,
                                            struct drm_gem_object *obj,
                                            u32 *offset)
 {
+       struct drm_i915_private *i915 = to_i915(drm);
        struct drm_i915_gem_object *new_bo = to_intel_bo(obj);
        struct i915_gem_ww_ctx ww;
        struct i915_vma *vma;
        int ret;
 
+       atomic_inc(&i915->pending_fb_pin);
+
        i915_gem_ww_ctx_init(&ww, true);
 retry:
        ret = i915_gem_object_lock(new_bo, &ww);
@@ -373,6 +376,9 @@ retry:
                        goto retry;
        }
        i915_gem_ww_ctx_fini(&ww);
+
+       atomic_dec(&i915->pending_fb_pin);
+
        if (ret)
                return ERR_PTR(ret);