From 3aef9c94c02b3e66cfacd70492b6604947010d35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 3 Sep 2026 16:01:16 +0300 Subject: [PATCH] drm/i915: Perform full wedge on display reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We lost the proper display reset deadlock handling in commit d59cf7bb73f3 ("drm/i915/display: Use dma_fence interfaces instead of i915_sw_fence"). Currently the only thing that eventually breaks the deadlock is the 10 second fence timeout, which is very slow. I tried to essentially restore the previous mechanism via a custom dma_fence in https://lore.kernel.org/intel-gfx/20260408233458.22666-6-ville.syrjala@linux.intel.com/ but Christian didn't want it. The ideal solution would be to allow the reset time modesets to proceed ahead of any already queued atomic commits, but that is quite involved since we need to be able to track the already committed (to the hardware) atomic states in addition to the userspace queued atomic states. Years ago I did implement something like that in https://lore.kernel.org/intel-gfx/20170629134948.5614-1-ville.syrjala@linux.intel.com/ but Sima didn't want it. In order to get rid of the dependency on the timeout, and make things faster, let's just effectively revert the remainders of commit 9db529aac938 ("drm/i915: More surgically unbreak the modeset vs reset deadlock"). The upside is that the reset is fast again, but the downside is that we now do a full wedge on all display resets, which will also kill innocent batches. But perhaps no one really cares since this is currently only needed for old pre-g4x hardware. But if anyone has plans on using eg. FLR as a backup GPU reset on new hardware then we probably need to come up with something better... Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260903130116.19089-1-ville.syrjala@linux.intel.com Acked-by: Jani Nikula --- drivers/gpu/drm/i915/gt/intel_reset.c | 8 +------- drivers/gpu/drm/i915/i915_dpt.c | 2 -- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/i915_fb_pin.c | 6 ------ drivers/gpu/drm/i915/i915_overlay.c | 5 ----- 5 files changed, 1 insertion(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c index b2cf672564dd..0968932c0b4f 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset.c +++ b/drivers/gpu/drm/i915/gt/intel_reset.c @@ -1433,13 +1433,7 @@ static void intel_gt_reset_global(struct intel_gt *gt, need_display_reset; 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_gt_set_wedged(gt); intel_display_reset_prepare(display); } diff --git a/drivers/gpu/drm/i915/i915_dpt.c b/drivers/gpu/drm/i915/i915_dpt.c index e01dc4de1788..85d872c0f387 100644 --- a/drivers/gpu/drm/i915/i915_dpt.c +++ b/drivers/gpu/drm/i915/i915_dpt.c @@ -139,7 +139,6 @@ 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(&i915->pending_fb_pin); for_i915_gem_ww(&ww, err, true) { err = i915_gem_object_lock(dpt->obj, &ww); @@ -169,7 +168,6 @@ struct i915_vma *i915_dpt_pin_to_ggtt(struct intel_dpt *dpt, unsigned int alignm dpt->obj->mm.dirty = true; - atomic_dec(&i915->pending_fb_pin); intel_runtime_pm_put(&i915->runtime_pm, wakeref); return err ? ERR_PTR(err) : vma; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 844ed79e7211..dafee3dcd1c5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -315,8 +315,6 @@ 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;) /* diff --git a/drivers/gpu/drm/i915/i915_fb_pin.c b/drivers/gpu/drm/i915/i915_fb_pin.c index 1034cb767e9f..63be136f1a05 100644 --- a/drivers/gpu/drm/i915/i915_fb_pin.c +++ b/drivers/gpu/drm/i915/i915_fb_pin.c @@ -35,8 +35,6 @@ intel_fb_pin_to_dpt(struct drm_gem_object *_obj, struct intel_dpt *dpt, if (WARN_ON(!i915_gem_object_is_framebuffer(obj))) return ERR_PTR(-EINVAL); - atomic_inc(&i915->pending_fb_pin); - for_i915_gem_ww(&ww, ret, true) { ret = i915_gem_object_lock(obj, &ww); if (ret) @@ -98,7 +96,6 @@ intel_fb_pin_to_dpt(struct drm_gem_object *_obj, struct intel_dpt *dpt, */ drm_WARN_ON(&i915->drm, i915_dpt_offset(vma)); err: - atomic_dec(&i915->pending_fb_pin); return vma; } @@ -132,8 +129,6 @@ intel_fb_pin_to_ggtt(struct drm_gem_object *_obj, */ wakeref = intel_runtime_pm_get(&i915->runtime_pm); - atomic_inc(&i915->pending_fb_pin); - pinctl = 0; /* PIN_MAPPABLE limits the address to GMADR size */ if (pin_params->needs_low_address) @@ -206,7 +201,6 @@ err: if (ret) vma = ERR_PTR(ret); - atomic_dec(&i915->pending_fb_pin); intel_runtime_pm_put(&i915->runtime_pm, wakeref); return vma; } diff --git a/drivers/gpu/drm/i915/i915_overlay.c b/drivers/gpu/drm/i915/i915_overlay.c index 6de550a17756..c1a7920c6324 100644 --- a/drivers/gpu/drm/i915/i915_overlay.c +++ b/drivers/gpu/drm/i915/i915_overlay.c @@ -354,14 +354,11 @@ 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); @@ -377,8 +374,6 @@ retry: } i915_gem_ww_ctx_fini(&ww); - atomic_dec(&i915->pending_fb_pin); - if (ret) return ERR_PTR(ret);