On Fri, Feb 12, 2016 at 08:30:32PM +0100, Mario Kleiner wrote: > In the display resume path, move the calls to drm_vblank_on() > after the point when the display engine is running again. > > Since changes were made to drm_update_vblank_count() in Linux 4.4+ > to emulate hw vblank counters via vblank timestamping, the function > drm_vblank_on() now needs working high precision vblank timestamping > and therefore working scanout position queries at time of call. > These don't work before the display engine gets restarted, causing > miscalculation of vblank counter increments and thereby large forward > jumps in vblank count at display resume. These jumps can cause client > hangs on resume, or desktop hangs in the case of composited desktops. > > Fix this Linux 4.4 regression by reordering calls accordingly. > > Signed-off-by: Mario Kleiner <mario.kleiner.de@xxxxxxxxx> > Cc: <stable@xxxxxxxxxxxxxxx> # 4.4+ > Cc: Ben Skeggs <bskeggs@xxxxxxxxxx> > Cc: ville.syrjala@xxxxxxxxxxxxxxx > Cc: daniel.vetter@xxxxxxxx > Cc: dri-devel@xxxxxxxxxxxxxxxxxxxxx > --- > drivers/gpu/drm/nouveau/nouveau_display.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c > index 18676b8..1f8e51b 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_display.c > +++ b/drivers/gpu/drm/nouveau/nouveau_display.c > @@ -634,10 +634,6 @@ nouveau_display_resume(struct drm_device *dev, bool runtime) > nv_crtc->lut.depth = 0; > } > > - /* Make sure that drm and hw vblank irqs get resumed if needed. */ > - for (head = 0; head < dev->mode_config.num_crtc; head++) > - drm_vblank_on(dev, head); > - > /* This should ensure we don't hit a locking problem when someone > * wakes us up via a connector. We should never go into suspend > * while the display is on anyways. > @@ -647,6 +643,10 @@ nouveau_display_resume(struct drm_device *dev, bool runtime) > > drm_helper_resume_force_mode(dev); > > + /* Make sure that drm and hw vblank irqs get resumed if needed. */ > + for (head = 0; head < dev->mode_config.num_crtc; head++) > + drm_vblank_on(dev, head); Hm, imo correct place for these is in the crtc->enable/disable hooks, but those are only guaranteed to be called symmetrically on atomic drivers. Anyway as an interim fix this looks good. Reviewed-by: Daniel Vetter <daniel.vetter@xxxxxxxx> > + > list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { > struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); > > -- > 1.9.1 > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html