Messages in this thread |  | | Date | Tue, 5 May 2026 13:31:16 -0500 | | Subject | Re: [PATCH v6 1/2] drm/atomic: attempt full modeset on page flip timeout | | From | Mario Limonciello <> |
| |
On 5/5/26 13:20, 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 <someguy@effective-light.com> Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org> > --- > 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); > + 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)
|  |