On Tue, May 05, 2026 at 02:20:57PM -0400, Hamza Mahfooz wrote: > We should try to recover from page flip timeouts. Forcing > a full modeset should be generic across all atomic KMS drivers, > so try that first. > > Signed-off-by: Hamza Mahfooz <[email protected]> > --- > drivers/gpu/drm/drm_atomic_helper.c | 49 +++++++++++++++++++++++++++-- > 1 file changed, 46 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c > b/drivers/gpu/drm/drm_atomic_helper.c > index a768398a1884..7ee9d52f63c5 100644 > --- a/drivers/gpu/drm/drm_atomic_helper.c > +++ b/drivers/gpu/drm/drm_atomic_helper.c > @@ -1926,6 +1926,43 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device > *dev, > } > EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks); > > +static int force_full_modeset(struct drm_crtc *crtc) > +{ > + struct drm_modeset_acquire_ctx ctx; > + struct drm_crtc_state *crtc_state; > + struct drm_atomic_state *state; > + int ret; > + int err; > + > + if (drm_atomic_crtc_needs_modeset(crtc->state)) > + return -EBUSY; > + > + DRM_MODESET_LOCK_ALL_BEGIN(crtc->dev, ctx, 0, err); > + state = drm_atomic_state_alloc(crtc->dev); > + if (!state) > + return -ENOMEM; > + > + state->acquire_ctx = &ctx; > + > + crtc_state = drm_atomic_get_crtc_state(state, crtc); > + if (IS_ERR(crtc_state)) { > + ret = PTR_ERR(crtc_state); > + goto out; > + } > + > + crtc_state->mode_changed = true; > + > + drm_info(crtc->dev, > + "[CRTC:%d:%s] Attempting force full modeset...\n", > + crtc->base.id, crtc->name); > + > + ret = drm_atomic_commit(state); > +out: > + drm_atomic_state_put(state); > + DRM_MODESET_LOCK_ALL_END(crtc->dev, ctx, err); > + return ret; > +} > + > /** > * drm_atomic_helper_wait_for_flip_done - wait for all page flips to be done > * @dev: DRM device > @@ -1949,17 +1986,23 @@ void drm_atomic_helper_wait_for_flip_done(struct > drm_device *dev, > > for (i = 0; i < dev->mode_config.num_crtc; i++) { > struct drm_crtc_commit *commit = state->crtcs[i].commit; > - int ret; > > crtc = state->crtcs[i].ptr; > > if (!crtc || !commit) > continue; > > - ret = wait_for_completion_timeout(&commit->flip_done, 10 * HZ); > - if (ret == 0) > + if (!wait_for_completion_timeout(&commit->flip_done, 10 * HZ)) { > + int ret; > drm_err(dev, "[CRTC:%d:%s] flip_done timed out\n", > crtc->base.id, crtc->name); > + > + ret = force_full_modeset(crtc);
This looks like some kind of ugly hack to paper over a driver bug. I really don't want this for i915/xe because all it'll end up doing is make it harder to debug any real issues. > + if (ret) > + drm_err(dev, > + "[CRTC:%d:%s] force full modeset > failed! ret=%d\n", > + crtc->base.id, crtc->name, ret); > + } > } > > if (state->fake_commit) > -- > 2.54.0 -- Ville Syrjälä Intel
