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

Commit a9ca184f authored by Dhaval Patel's avatar Dhaval Patel Committed by Steve Cohen
Browse files

disp: msm: sde: avoid rc lock deadlock during esd failure



Each mode_set call makes sure that previous frame is triggered
and triggers the esd check if there is pp_timeout. This may
lead to deadlock between crtc commit and event threads. Crtc
commit thread acquires the rc_lock and triggers the flush_thread
API on event_thread. Event thread again tries to acquire the
rc_lock to wait for frame. This can be prevented by avoiding the
pre_kickoff call from esd_failure notification if it is generated
through pp_timeout.

Change-Id: I561fef0345976ab0cae61aab6718214c47fa1393
Signed-off-by: default avatarDhaval Patel <pdhaval@codeaurora.org>
parent 5ffa8544
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -1819,7 +1819,8 @@ static int sde_connector_atomic_check(struct drm_connector *connector,
	return 0;
}

static void _sde_connector_report_panel_dead(struct sde_connector *conn)
static void _sde_connector_report_panel_dead(struct sde_connector *conn,
	bool skip_pre_kickoff)
{
	struct drm_event event;

@@ -1839,7 +1840,8 @@ static void _sde_connector_report_panel_dead(struct sde_connector *conn)
	event.length = sizeof(bool);
	msm_mode_object_event_notify(&conn->base.base,
		conn->base.dev, &event, (u8 *)&conn->panel_dead);
	sde_encoder_display_failure_notification(conn->encoder);
	sde_encoder_display_failure_notification(conn->encoder,
		skip_pre_kickoff);
	SDE_EVT32(SDE_EVTLOG_ERROR);
	SDE_ERROR("esd check failed report PANEL_DEAD conn_id: %d enc_id: %d\n",
			conn->base.base.id, conn->encoder->base.id);
@@ -1874,7 +1876,7 @@ int sde_connector_esd_status(struct drm_connector *conn)
	if (ret <= 0) {
		/* cancel if any pending esd work */
		sde_connector_schedule_status_work(conn, false);
		_sde_connector_report_panel_dead(sde_conn);
		_sde_connector_report_panel_dead(sde_conn, true);
		ret = -ETIMEDOUT;
	} else {
		SDE_DEBUG("Successfully received TE from panel\n");
@@ -1922,7 +1924,7 @@ static void sde_connector_check_status_work(struct work_struct *work)
		return;
	}

	_sde_connector_report_panel_dead(conn);
	_sde_connector_report_panel_dead(conn, false);
}

static const struct drm_connector_helper_funcs sde_connector_helper_ops = {
+9 −5
Original line number Diff line number Diff line
@@ -5643,7 +5643,8 @@ int sde_encoder_update_caps_for_cont_splash(struct drm_encoder *encoder,
	return ret;
}

int sde_encoder_display_failure_notification(struct drm_encoder *enc)
int sde_encoder_display_failure_notification(struct drm_encoder *enc,
	bool skip_pre_kickoff)
{
	struct msm_drm_thread *event_thread = NULL;
	struct msm_drm_private *priv = NULL;
@@ -5669,9 +5670,11 @@ int sde_encoder_display_failure_notification(struct drm_encoder *enc)

	event_thread = &priv->event_thread[sde_enc->crtc->index];

	if (!skip_pre_kickoff) {
		kthread_queue_work(&event_thread->worker,
				   &sde_enc->esd_trigger_work);
		kthread_flush_work(&sde_enc->esd_trigger_work);
	}

	/**
	 * panel may stop generating te signal (vsync) during esd failure. rsc
@@ -5680,6 +5683,7 @@ int sde_encoder_display_failure_notification(struct drm_encoder *enc)
	 */
	_sde_encoder_switch_to_watchdog_vsync(enc);

	if (!skip_pre_kickoff)
		sde_encoder_wait_for_event(enc, MSM_ENC_TX_COMPLETE);

	return 0;
+4 −1
Original line number Diff line number Diff line
@@ -282,9 +282,12 @@ int sde_encoder_update_caps_for_cont_splash(struct drm_encoder *encoder,
 *
 *      TODO: manage the event at sde_kms level for forward processing.
 * @drm_enc:    Pointer to drm encoder structure
 * @skip_pre_kickoff:    Caller can avoid pre_kickoff if it is triggering this
 *                       event only to switch the panel TE to watchdog mode.
 * @Return:     true if successful in updating the encoder structure
 */
int sde_encoder_display_failure_notification(struct drm_encoder *enc);
int sde_encoder_display_failure_notification(struct drm_encoder *enc,
	bool skip_pre_kickoff);

/**
 * sde_encoder_recovery_events_enabled - checks if client has enabled