Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c71ab383 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mdss: fix race condition between shutdown thread and fb ioctl"

parents 84ab1e55 8b6f44d8
Loading
Loading
Loading
Loading
+33 −5
Original line number Diff line number Diff line
@@ -1301,6 +1301,7 @@ static int mdss_fb_register(struct msm_fb_data_type *mfd)
	mutex_init(&mfd->mdp_sync_pt_data.sync_mutex);
	atomic_set(&mfd->mdp_sync_pt_data.commit_cnt, 0);
	atomic_set(&mfd->commits_pending, 0);
	atomic_set(&mfd->ioctl_ref_cnt, 0);

	init_timer(&mfd->no_update.timer);
	mfd->no_update.timer.function = mdss_fb_no_update_notify_timer_cb;
@@ -1311,6 +1312,7 @@ static int mdss_fb_register(struct msm_fb_data_type *mfd)
	init_completion(&mfd->power_set_comp);
	init_waitqueue_head(&mfd->commit_wait_q);
	init_waitqueue_head(&mfd->idle_wait_q);
	init_waitqueue_head(&mfd->ioctl_q);

	ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
	if (ret)
@@ -1429,6 +1431,12 @@ static int mdss_fb_release_all(struct fb_info *info, bool release_all)
		return -EINVAL;
	}

	if (!wait_event_timeout(mfd->ioctl_q,
		!atomic_read(&mfd->ioctl_ref_cnt) || !release_all,
		msecs_to_jiffies(1000)))
		pr_warn("fb%d ioctl could not finish. waited 1 sec.\n",
			mfd->index);

	mdss_fb_pan_idle(mfd);

	pr_debug("release_all = %s\n", release_all ? "true" : "false");
@@ -1506,6 +1514,7 @@ static int mdss_fb_release_all(struct fb_info *info, bool release_all)
				mfd->index, ret, task->comm, pid);
			return ret;
		}
		atomic_set(&mfd->ioctl_ref_cnt, 0);
	}

	return ret;
@@ -2367,10 +2376,21 @@ int mdss_fb_do_ioctl(struct fb_info *info, unsigned int cmd,
	int ret = -ENOSYS;
	struct mdp_buf_sync buf_sync;
	struct msm_sync_pt_data *sync_pt_data = NULL;

	if (!info || !info->par)
		return -EINVAL;

	mfd = (struct msm_fb_data_type *)info->par;
	if (!mfd)
		return -EINVAL;

	if (mfd->shutdown_pending)
		return -EPERM;

	atomic_inc(&mfd->ioctl_ref_cnt);

	mdss_fb_power_setting_idle(mfd);

	if ((cmd != MSMFB_VSYNC_CTRL) && (cmd != MSMFB_OVERLAY_VSYNC_CTRL) &&
			(cmd != MSMFB_ASYNC_BLIT) && (cmd != MSMFB_BLIT) &&
			(cmd != MSMFB_NOTIFY_UPDATE) &&
@@ -2379,7 +2399,7 @@ int mdss_fb_do_ioctl(struct fb_info *info, unsigned int cmd,
		if (ret) {
			pr_debug("Shutdown pending. Aborting operation %x\n",
				cmd);
			return ret;
			goto exit;
		}
	}

@@ -2398,15 +2418,19 @@ int mdss_fb_do_ioctl(struct fb_info *info, unsigned int cmd,
		ret = copy_to_user(argp, &fb_page_protection,
				   sizeof(fb_page_protection));
		if (ret)
			return ret;
			goto exit;
		break;

	case MSMFB_BUFFER_SYNC:
		ret = copy_from_user(&buf_sync, argp, sizeof(buf_sync));
		if (ret)
			return ret;
		if ((!mfd->op_enable) || (!mfd->panel_power_on))
			return -EPERM;
			goto exit;

		if ((!mfd->op_enable) || (!mfd->panel_power_on)) {
			ret = -EPERM;
			goto exit;
		}

		if (mfd->mdp.get_sync_fnc)
			sync_pt_data = mfd->mdp.get_sync_fnc(mfd, &buf_sync);
		if (!sync_pt_data)
@@ -2435,6 +2459,10 @@ int mdss_fb_do_ioctl(struct fb_info *info, unsigned int cmd,
	if (ret == -ENOSYS)
		pr_err("unsupported ioctl (%x)\n", cmd);

exit:
	if (!atomic_dec_return(&mfd->ioctl_ref_cnt))
		wake_up_all(&mfd->ioctl_q);

	return ret;
}

+3 −0
Original line number Diff line number Diff line
@@ -222,6 +222,9 @@ struct msm_fb_data_type {
	struct task_struct *splash_thread;
	bool splash_logo_enabled;

	wait_queue_head_t ioctl_q;
	atomic_t ioctl_ref_cnt;

	struct msm_fb_backup_type msm_fb_backup;
	struct completion power_set_comp;
	u32 is_power_setting;