Commit fcfb5aa2 authored by Mario Kleiner's avatar Mario Kleiner Committed by Greg Kroah-Hartman

drm: Zero out invalid vblank timestamp in drm_update_vblank_count.

commit fdb68e09 upstream.

Since commit 844b03f2 we make
sure that after vblank irq off, we return the last valid
(vblank count, vblank timestamp) pair to clients, e.g., during
modesets, which is good.

An overlooked side effect of that commit for kms drivers without
support for precise vblank timestamping is that at vblank irq
enable, when we update the vblank counter from the hw counter, we
can't update the corresponding vblank timestamp, so now we have a
totally mismatched timestamp for the new count to confuse clients.

Restore old client visible behaviour from before Linux 3.17, but
zero out the timestamp at vblank counter update (instead of disable
as in original implementation) if we can't generate a meaningful
timestamp immediately for the new vblank counter. This will fix
this regression, so callers know they need to retry again later
if they need a valid timestamp, but at the same time preserves
the improvements made in the commit mentioned above.
Signed-off-by: default avatarMario Kleiner <mario.kleiner.de@gmail.com>
Cc: <stable@vger.kernel.org> #v3.17+
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent a314c7d8
......@@ -131,12 +131,11 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc)
/* Reinitialize corresponding vblank timestamp if high-precision query
* available. Skip this step if query unsupported or failed. Will
* reinitialize delayed at next vblank interrupt in that case.
* reinitialize delayed at next vblank interrupt in that case and
* assign 0 for now, to mark the vblanktimestamp as invalid.
*/
if (rc) {
tslot = atomic_read(&vblank->count) + diff;
vblanktimestamp(dev, crtc, tslot) = t_vblank;
}
tslot = atomic_read(&vblank->count) + diff;
vblanktimestamp(dev, crtc, tslot) = rc ? t_vblank : (struct timeval) {0, 0};
smp_mb__before_atomic();
atomic_add(diff, &vblank->count);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment