Merge "msm: mdss: release all overlay resources if calling process is unknown"
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 80f7892..96d8be0 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -1176,11 +1176,12 @@
struct mdss_fb_proc_info *pinfo = NULL, *temp_pinfo = NULL;
int ret = 0;
int pid = current->tgid;
- bool unknown_pid = true;
- struct task_struct *task;
+ bool unknown_pid = true, release_needed = false;
+ struct task_struct *task = current->group_leader;
if (!mfd->ref_cnt) {
- pr_info("try to close unopened fb %d!\n", mfd->index);
+ pr_info("try to close unopened fb %d! from %s\n", mfd->index,
+ task->comm);
return -EINVAL;
}
@@ -1193,12 +1194,14 @@
continue;
unknown_pid = false;
- pr_debug("found process entry pid=%d ref=%d\n", pinfo->pid,
- pinfo->ref_cnt);
+
+ pr_debug("found process %s pid=%d mfd->ref=%d pinfo->ref=%d\n",
+ task->comm, mfd->ref_cnt, pinfo->pid, pinfo->ref_cnt);
do {
if (mfd->ref_cnt < pinfo->ref_cnt)
- pr_warn("WARN:mfd->ref_cnt < pinfo->ref_cnt\n");
+ pr_warn("WARN:mfd->ref=%d < pinfo->ref=%d\n",
+ mfd->ref_cnt, pinfo->ref_cnt);
else
mfd->ref_cnt--;
@@ -1207,28 +1210,37 @@
} while (release_all && pinfo->ref_cnt);
if (pinfo->ref_cnt == 0) {
- if (mfd->mdp.release_fnc) {
- ret = mfd->mdp.release_fnc(mfd);
- if (ret)
- pr_err("error releasing fb%d pid=%d\n",
- mfd->index, pinfo->pid);
- }
list_del(&pinfo->list);
kfree(pinfo);
+ release_needed = !release_all;
}
+
+ if (!release_all)
+ break;
}
- if (unknown_pid) {
- task = current->group_leader;
- pr_debug("unknown process %s pid=%d mfd->ref_cnt=%d\n",
+ if (release_needed) {
+ pr_debug("known process %s pid=%d mfd->ref=%d\n",
task->comm, pid, mfd->ref_cnt);
- mfd->ref_cnt--;
if (mfd->mdp.release_fnc) {
- ret = mfd->mdp.release_fnc(mfd);
+ ret = mfd->mdp.release_fnc(mfd, false);
if (ret)
pr_err("error releasing fb%d pid=%d\n",
- mfd->index, pinfo->pid);
+ mfd->index, pid);
+ }
+ } else if (unknown_pid || release_all) {
+ pr_warn("unknown process %s pid=%d mfd->ref=%d\n",
+ task->comm, pid, mfd->ref_cnt);
+
+ if (mfd->ref_cnt)
+ mfd->ref_cnt--;
+
+ if (mfd->mdp.release_fnc) {
+ ret = mfd->mdp.release_fnc(mfd, true);
+ if (ret)
+ pr_err("error fb%d release process %s pid=%d\n",
+ mfd->index, task->comm, pid);
}
}
@@ -1236,8 +1248,8 @@
ret = mdss_fb_blank_sub(FB_BLANK_POWERDOWN, info,
mfd->op_enable);
if (ret) {
- pr_err("can't turn off fb%d! rc=%d\n",
- mfd->index, ret);
+ pr_err("can't turn off fb%d! rc=%d process %s pid=%d\n",
+ mfd->index, ret, task->comm, pid);
return ret;
}
}
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index 8213dbe..80e6581 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -106,7 +106,7 @@
int (*on_fnc)(struct msm_fb_data_type *mfd);
int (*off_fnc)(struct msm_fb_data_type *mfd);
/* called to release resources associated to the process */
- int (*release_fnc)(struct msm_fb_data_type *mfd);
+ int (*release_fnc)(struct msm_fb_data_type *mfd, bool release_all);
int (*kickoff_fnc)(struct msm_fb_data_type *mfd,
struct mdp_display_commit *data);
int (*ioctl_handler)(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 0fb01ad..7f306c5 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -1153,11 +1153,13 @@
/**
* mdss_mdp_overlay_release_all() - release any overlays associated with fb dev
* @mfd: Msm frame buffer structure associated with fb device
+ * @release_all: ignore pid and release all the pipes
*
* Release any resources allocated by calling process, this can be called
* on fb_release to release any overlays/rotator sessions left open.
*/
-static int __mdss_mdp_overlay_release_all(struct msm_fb_data_type *mfd)
+static int __mdss_mdp_overlay_release_all(struct msm_fb_data_type *mfd,
+ bool release_all)
{
struct mdss_mdp_pipe *pipe;
struct mdss_mdp_rotator_session *rot, *tmp;
@@ -1171,7 +1173,7 @@
mutex_lock(&mdp5_data->ov_lock);
mutex_lock(&mfd->lock);
list_for_each_entry(pipe, &mdp5_data->pipes_used, used_list) {
- if (!mfd->ref_cnt || (pipe->pid == pid)) {
+ if (release_all || (pipe->pid == pid)) {
unset_ndx |= pipe->ndx;
cnt++;
}
@@ -1183,6 +1185,9 @@
cnt++;
}
+ pr_debug("release_all=%d mfd->ref_cnt=%d unset_ndx=0x%x cnt=%d\n",
+ release_all, mfd->ref_cnt, unset_ndx, cnt);
+
mutex_unlock(&mfd->lock);
if (unset_ndx) {