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>
This commit is contained in:
Dhaval Patel 2015-12-30 15:12:35 -08:00 committed by David Keitel
parent c747f82604
commit a521f8040d

View file

@ -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)