summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDhaval Patel <pdhaval@codeaurora.org>2015-12-30 15:12:35 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-25 12:33:55 -0700
commita521f8040d0397718f6dc113dbb6e57d484a3869 (patch)
tree7c1c2ce855b7aeb276432e358eff7d58816ab5c8
parentc747f82604b0f102b8e7ae5a2e4e9c30ba65818a (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.c18
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)