Commit bc215128 authored by Mario Kleiner's avatar Mario Kleiner Committed by Dave Airlie

drm/vblank: Use memory barriers optimized for atomic_t instead of generics.

Documentation/atomic_ops.txt tells us that there are memory
barriers optimized for atomic_inc and other atomic_t ops.

Use these instead of smp_wmb(), and also to make the required
memory barriers around vblank counter increments more explicit.
Signed-off-by: default avatarMario Kleiner <mario.kleiner@tuebingen.mpg.de>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent c4cc3839
...@@ -164,8 +164,10 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) ...@@ -164,8 +164,10 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
* available. In that case we can't account for this and just * available. In that case we can't account for this and just
* hope for the best. * hope for the best.
*/ */
if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) {
atomic_inc(&dev->_vblank_count[crtc]); atomic_inc(&dev->_vblank_count[crtc]);
smp_mb__after_atomic_inc();
}
/* Invalidate all timestamps while vblank irq's are off. */ /* Invalidate all timestamps while vblank irq's are off. */
clear_vblank_timestamps(dev, crtc); clear_vblank_timestamps(dev, crtc);
...@@ -858,10 +860,11 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) ...@@ -858,10 +860,11 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc)
if (rc) { if (rc) {
tslot = atomic_read(&dev->_vblank_count[crtc]) + diff; tslot = atomic_read(&dev->_vblank_count[crtc]) + diff;
vblanktimestamp(dev, crtc, tslot) = t_vblank; vblanktimestamp(dev, crtc, tslot) = t_vblank;
smp_wmb();
} }
smp_mb__before_atomic_inc();
atomic_add(diff, &dev->_vblank_count[crtc]); atomic_add(diff, &dev->_vblank_count[crtc]);
smp_mb__after_atomic_inc();
} }
/** /**
...@@ -1296,12 +1299,13 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) ...@@ -1296,12 +1299,13 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) { if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) {
/* Store new timestamp in ringbuffer. */ /* Store new timestamp in ringbuffer. */
vblanktimestamp(dev, crtc, vblcount + 1) = tvblank; vblanktimestamp(dev, crtc, vblcount + 1) = tvblank;
smp_wmb();
/* Increment cooked vblank count. This also atomically commits /* Increment cooked vblank count. This also atomically commits
* the timestamp computed above. * the timestamp computed above.
*/ */
smp_mb__before_atomic_inc();
atomic_inc(&dev->_vblank_count[crtc]); atomic_inc(&dev->_vblank_count[crtc]);
smp_mb__after_atomic_inc();
} else { } else {
DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n",
crtc, (int) diff_ns); crtc, (int) diff_ns);
......
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