msm: mdss: avoid race conditions during fb release
During fb release we should release all resources that are associated to that process. However, in current release function this can lead to kickoff being done, if this is done while display thread is running there can be race condition between the updates from two different threads. Fix this by pushing the commit through the display thread in cases where display thread should be running, or otherwise shutdown this thread and do it along with panel blanking. Change-Id: I9ff6316c18adfdb67d0250a144ddc2f9f2634273 Signed-off-by: Adrian Salido-Moreno <adrianm@codeaurora.org>
This commit is contained in:
parent
4cd847cf76
commit
f44a833d60
2 changed files with 19 additions and 30 deletions
|
@ -2174,7 +2174,7 @@ static int mdss_fb_release_all(struct fb_info *info, bool release_all)
|
|||
unknown_pid = false;
|
||||
|
||||
pr_debug("found process %s pid=%d mfd->ref=%d pinfo->ref=%d\n",
|
||||
task->comm, mfd->ref_cnt, pinfo->pid, pinfo->ref_cnt);
|
||||
task->comm, pinfo->pid, mfd->ref_cnt, pinfo->ref_cnt);
|
||||
|
||||
proc_info = mdss_fb_release_file_entry(info, pinfo,
|
||||
release_all);
|
||||
|
@ -2199,10 +2199,6 @@ static int mdss_fb_release_all(struct fb_info *info, bool release_all)
|
|||
pm_runtime_put(info->dev);
|
||||
} while (release_all && pinfo->ref_cnt);
|
||||
|
||||
/* we need to stop display thread before release */
|
||||
if (release_all && mfd->disp_thread)
|
||||
mdss_fb_stop_disp_thread(mfd);
|
||||
|
||||
if (pinfo->ref_cnt == 0) {
|
||||
list_del(&pinfo->list);
|
||||
kfree(pinfo);
|
||||
|
@ -2233,27 +2229,10 @@ static int mdss_fb_release_all(struct fb_info *info, bool release_all)
|
|||
}
|
||||
}
|
||||
|
||||
if (release_needed) {
|
||||
pr_debug("current process=%s pid=%d known pid=%d mfd->ref=%d\n",
|
||||
task->comm, current->tgid, pid, mfd->ref_cnt);
|
||||
|
||||
if (mfd->mdp.release_fnc) {
|
||||
ret = mfd->mdp.release_fnc(mfd, false, pid);
|
||||
if (ret)
|
||||
pr_err("error releasing fb%d for current pid=%d known pid=%d\n",
|
||||
mfd->index, current->tgid, pid);
|
||||
}
|
||||
} else if (release_all && mfd->ref_cnt) {
|
||||
pr_err("reference count mismatch with proc list entries\n");
|
||||
}
|
||||
|
||||
if (!mfd->ref_cnt) {
|
||||
if (mfd->mdp.release_fnc) {
|
||||
ret = mfd->mdp.release_fnc(mfd, true, pid);
|
||||
if (ret)
|
||||
pr_err("error fb%d release current process=%s pid=%d known pid=%d\n",
|
||||
mfd->index, task->comm, current->tgid, pid);
|
||||
}
|
||||
if (!mfd->ref_cnt || release_all) {
|
||||
/* resources (if any) will be released during blank */
|
||||
if (mfd->mdp.release_fnc)
|
||||
mfd->mdp.release_fnc(mfd, true, pid);
|
||||
|
||||
if (mfd->fb_ion_handle)
|
||||
mdss_fb_free_fb_ion_memory(mfd);
|
||||
|
@ -2266,6 +2245,17 @@ static int mdss_fb_release_all(struct fb_info *info, bool release_all)
|
|||
return ret;
|
||||
}
|
||||
atomic_set(&mfd->ioctl_ref_cnt, 0);
|
||||
} else if (release_needed) {
|
||||
pr_debug("current process=%s pid=%d known pid=%d mfd->ref=%d\n",
|
||||
task->comm, current->tgid, pid, mfd->ref_cnt);
|
||||
|
||||
if (mfd->mdp.release_fnc) {
|
||||
ret = mfd->mdp.release_fnc(mfd, false, pid);
|
||||
|
||||
/* display commit is needed to release resources */
|
||||
if (ret)
|
||||
mdss_fb_pan_display(&mfd->fbi->var, mfd->fbi);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -1683,6 +1683,8 @@ done:
|
|||
*
|
||||
* Release any resources allocated by calling process, this can be called
|
||||
* on fb_release to release any overlays/rotator sessions left open.
|
||||
*
|
||||
* Return number of resources released
|
||||
*/
|
||||
static int __mdss_mdp_overlay_release_all(struct msm_fb_data_type *mfd,
|
||||
bool release_all, uint32_t pid)
|
||||
|
@ -1721,9 +1723,6 @@ static int __mdss_mdp_overlay_release_all(struct msm_fb_data_type *mfd,
|
|||
}
|
||||
mutex_unlock(&mdp5_data->ov_lock);
|
||||
|
||||
if (cnt)
|
||||
mfd->mdp.kickoff_fnc(mfd, NULL);
|
||||
|
||||
list_for_each_entry_safe(rot, tmp, &mdp5_data->rot_proc_list, list) {
|
||||
if (rot->pid == pid) {
|
||||
if (!list_empty(&rot->list))
|
||||
|
@ -1732,7 +1731,7 @@ static int __mdss_mdp_overlay_release_all(struct msm_fb_data_type *mfd,
|
|||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static int mdss_mdp_overlay_play_wait(struct msm_fb_data_type *mfd,
|
||||
|
|
Loading…
Add table
Reference in a new issue