diff options
author | Dhaval Patel <pdhaval@codeaurora.org> | 2015-12-30 15:12:35 -0800 |
---|---|---|
committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-25 12:33:55 -0700 |
commit | a521f8040d0397718f6dc113dbb6e57d484a3869 (patch) | |
tree | 7c1c2ce855b7aeb276432e358eff7d58816ab5c8 | |
parent | c747f82604b0f102b8e7ae5a2e4e9c30ba65818a (diff) |
msm: mdss: protect retire count with mutex lock
The retire timeline counter in command mode is used
by vsync worker queue, validate/commit ioctl thread
and overlay off. However, this counter is not protected
with any locking mechanism and each thread updates the
value. Race condition with updated value between two
thread can lead to invalid vsync operation or list
corruption. This change protects the counter with
mutex lock to avoid all such race conditions.
Change-Id: Ib3c3f6c839fc82c6d31fa28066df1f23dab19746
Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
-rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_overlay.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index ef640f4c448f..face458be16c 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -4651,6 +4651,7 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd) struct mdss_overlay_private *mdp5_data; struct mdss_mdp_mixer *mixer; int need_cleanup; + int retire_cnt; if (!mfd) return -ENODEV; @@ -4717,13 +4718,19 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd) * for retire fence to be updated. * As a last resort signal the timeline if vsync doesn't arrive. */ - if (mdp5_data->retire_cnt) { + mutex_lock(&mfd->mdp_sync_pt_data.sync_mutex); + retire_cnt = mdp5_data->retire_cnt; + mutex_unlock(&mfd->mdp_sync_pt_data.sync_mutex); + if (retire_cnt) { u32 fps = mdss_panel_get_framerate(mfd->panel_info); u32 vsync_time = 1000 / (fps ? : DEFAULT_FRAME_RATE); msleep(vsync_time); - __vsync_retire_signal(mfd, mdp5_data->retire_cnt); + mutex_lock(&mfd->mdp_sync_pt_data.sync_mutex); + retire_cnt = mdp5_data->retire_cnt; + mutex_unlock(&mfd->mdp_sync_pt_data.sync_mutex); + __vsync_retire_signal(mfd, retire_cnt); /* * the retire work can still schedule after above retire_signal @@ -5008,10 +5015,13 @@ static int __vsync_set_vsync_handler(struct msm_fb_data_type *mfd) struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd); struct mdss_mdp_ctl *ctl; int rc; + int retire_cnt; ctl = mdp5_data->ctl; - if (!mdp5_data->retire_cnt || - mdp5_data->vsync_retire_handler.enabled) + mutex_lock(&mfd->mdp_sync_pt_data.sync_mutex); + retire_cnt = mdp5_data->retire_cnt; + mutex_unlock(&mfd->mdp_sync_pt_data.sync_mutex); + if (!retire_cnt || mdp5_data->vsync_retire_handler.enabled) return 0; if (!ctl->ops.add_vsync_handler) |