diff options
author | Thierry Reding <treding@nvidia.com> | 2014-12-16 16:33:27 +0100 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2014-12-17 14:27:36 +0100 |
commit | 6b59cc1c86e90cccf8fb0b4dee5fbc226bb82d3e (patch) | |
tree | 4150f757c48d659fc7d1c6c15e64e8de2069fd66 /drivers | |
parent | drm/tegra: dc: Consistently use the same pipe (diff) | |
download | linux-6b59cc1c86e90cccf8fb0b4dee5fbc226bb82d3e.tar.xz linux-6b59cc1c86e90cccf8fb0b4dee5fbc226bb82d3e.zip |
drm/tegra: dc: Fix a potential race on page-flip completion
Page-flip completion could race with page-flip submission, so extend the
critical section to include all accesses to page-flip related data.
Reported-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/tegra/dc.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 5a6d43dfeb8d..ef36f9d5e35e 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -814,8 +814,12 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc) unsigned long flags, base; struct tegra_bo *bo; - if (!dc->event) + spin_lock_irqsave(&drm->event_lock, flags); + + if (!dc->event) { + spin_unlock_irqrestore(&drm->event_lock, flags); return; + } bo = tegra_fb_get_plane(crtc->primary->fb, 0); @@ -825,12 +829,12 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc) tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS); if (base == bo->paddr + crtc->primary->fb->offsets[0]) { - spin_lock_irqsave(&drm->event_lock, flags); drm_crtc_send_vblank_event(crtc, dc->event); drm_crtc_vblank_put(crtc); dc->event = NULL; - spin_unlock_irqrestore(&drm->event_lock, flags); } + + spin_unlock_irqrestore(&drm->event_lock, flags); } void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) |