diff options
| -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 6d2d4faf867..22f3bf5ecbd 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); |
