diff options
author | Mario Kleiner <mario.kleiner@tuebingen.mpg.de> | 2011-02-20 23:42:01 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-02-22 19:08:46 -0500 |
commit | bc21512835a72bc1eab7abd7d8a1bff0435591d7 (patch) | |
tree | 015b9212d6fbd176dcbe141d5d96ee30d4bf1a76 /drivers/gpu/drm/drm_irq.c | |
parent | c4cc383915549cf14f027f374904e30c13653dac (diff) |
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: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
-rw-r--r-- | drivers/gpu/drm/drm_irq.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 6d2d4faf8678..22f3bf5ecbd2 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -164,8 +164,10 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) | |||
164 | * available. In that case we can't account for this and just | 164 | * available. In that case we can't account for this and just |
165 | * hope for the best. | 165 | * hope for the best. |
166 | */ | 166 | */ |
167 | if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) | 167 | if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) { |
168 | atomic_inc(&dev->_vblank_count[crtc]); | 168 | atomic_inc(&dev->_vblank_count[crtc]); |
169 | smp_mb__after_atomic_inc(); | ||
170 | } | ||
169 | 171 | ||
170 | /* Invalidate all timestamps while vblank irq's are off. */ | 172 | /* Invalidate all timestamps while vblank irq's are off. */ |
171 | clear_vblank_timestamps(dev, crtc); | 173 | clear_vblank_timestamps(dev, crtc); |
@@ -858,10 +860,11 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) | |||
858 | if (rc) { | 860 | if (rc) { |
859 | tslot = atomic_read(&dev->_vblank_count[crtc]) + diff; | 861 | tslot = atomic_read(&dev->_vblank_count[crtc]) + diff; |
860 | vblanktimestamp(dev, crtc, tslot) = t_vblank; | 862 | vblanktimestamp(dev, crtc, tslot) = t_vblank; |
861 | smp_wmb(); | ||
862 | } | 863 | } |
863 | 864 | ||
865 | smp_mb__before_atomic_inc(); | ||
864 | atomic_add(diff, &dev->_vblank_count[crtc]); | 866 | atomic_add(diff, &dev->_vblank_count[crtc]); |
867 | smp_mb__after_atomic_inc(); | ||
865 | } | 868 | } |
866 | 869 | ||
867 | /** | 870 | /** |
@@ -1296,12 +1299,13 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) | |||
1296 | if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) { | 1299 | if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) { |
1297 | /* Store new timestamp in ringbuffer. */ | 1300 | /* Store new timestamp in ringbuffer. */ |
1298 | vblanktimestamp(dev, crtc, vblcount + 1) = tvblank; | 1301 | vblanktimestamp(dev, crtc, vblcount + 1) = tvblank; |
1299 | smp_wmb(); | ||
1300 | 1302 | ||
1301 | /* Increment cooked vblank count. This also atomically commits | 1303 | /* Increment cooked vblank count. This also atomically commits |
1302 | * the timestamp computed above. | 1304 | * the timestamp computed above. |
1303 | */ | 1305 | */ |
1306 | smp_mb__before_atomic_inc(); | ||
1304 | atomic_inc(&dev->_vblank_count[crtc]); | 1307 | atomic_inc(&dev->_vblank_count[crtc]); |
1308 | smp_mb__after_atomic_inc(); | ||
1305 | } else { | 1309 | } else { |
1306 | DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", | 1310 | DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", |
1307 | crtc, (int) diff_ns); | 1311 | crtc, (int) diff_ns); |