mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
drm/msm/sde: queue display failure work to event thread
There are possibilities of deadlock if esd trigger work is queued to display thread. There is a corner case where during bridge disable, display thread is waiting for esd trigger work to complete to cancel esd thread, while esd trigger work is blocked on display thread. To fix this queue esd trigger work to event thread. Below is the call stack of both threads: ESD thread ---------- __switch_to+0xb8/0xec kthread_flush_work+0xdc/0x150 sde_encoder_display_failure_notification+0xc0/0x1e8 _sde_connector_report_panel_dead.part.8+0x6c/0xd4 sde_connector_check_status_work+0x10c/0x1d4 process_one_work+0x168/0x468 worker_thread+0x140/0x460 kthread+0xf4/0x108 ret_from_fork+0x10/0x50 0xffffffffffffffff Commit thread ------------- __switch_to+0xb8/0xec flush_work+0x44/0x68 __cancel_work_timer+0x138/0x1e0 cancel_delayed_work_sync+0x24/0x30 sde_connector_schedule_status_work.part.16+0xc0/0x114 _sde_connector_update_power_locked+0x1c4/0x224 _sde_connector_update_dirty_properties+0x80/0x100 sde_connector_helper_bridge_disable+0x24/0x100 dsi_bridge_disable+0x30/0x98 drm_bridge_disable+0x128/0x144 msm_atomic_helper_commit_modeset_disables+0x148/0x578 complete_commit+0x74/0x668 _msm_drm_commit_work_cb+0x4c/0x1c4 kthread_worker_fn+0xc0/0x1e4 kthread+0xf4/0x108 ret_from_fork+0x10/0x50 0xffffffffffffffff Change-Id: Ifd95664113857fd5c06098a3a2f87f28c1975513 Signed-off-by: Jayant Shekhar <jshekhar@codeaurora.org>
This commit is contained in:
parent
a087e2b7b3
commit
0e138412af
@ -1782,6 +1782,14 @@ static void _sde_connector_report_panel_dead(struct sde_connector *conn)
|
||||
if (!conn)
|
||||
return;
|
||||
|
||||
/* Panel dead notification can come:
|
||||
* 1) ESD thread
|
||||
* 2) Commit thread (if TE stops coming)
|
||||
* So such case, avoid failure notification twice.
|
||||
*/
|
||||
if (conn->panel_dead)
|
||||
return;
|
||||
|
||||
conn->panel_dead = true;
|
||||
event.type = DRM_EVENT_PANEL_DEAD;
|
||||
event.length = sizeof(bool);
|
||||
|
@ -5251,7 +5251,7 @@ int sde_encoder_update_caps_for_cont_splash(struct drm_encoder *encoder)
|
||||
|
||||
int sde_encoder_display_failure_notification(struct drm_encoder *enc)
|
||||
{
|
||||
struct msm_drm_thread *disp_thread = NULL;
|
||||
struct msm_drm_thread *event_thread = NULL;
|
||||
struct msm_drm_private *priv = NULL;
|
||||
struct sde_encoder_virt *sde_enc = NULL;
|
||||
|
||||
@ -5263,7 +5263,7 @@ int sde_encoder_display_failure_notification(struct drm_encoder *enc)
|
||||
priv = enc->dev->dev_private;
|
||||
sde_enc = to_sde_encoder_virt(enc);
|
||||
if (!sde_enc->crtc || (sde_enc->crtc->index
|
||||
>= ARRAY_SIZE(priv->disp_thread))) {
|
||||
>= ARRAY_SIZE(priv->event_thread))) {
|
||||
SDE_DEBUG_ENC(sde_enc,
|
||||
"invalid cached CRTC: %d or crtc index: %d\n",
|
||||
sde_enc->crtc == NULL,
|
||||
@ -5273,11 +5273,12 @@ int sde_encoder_display_failure_notification(struct drm_encoder *enc)
|
||||
|
||||
SDE_EVT32_VERBOSE(DRMID(enc));
|
||||
|
||||
disp_thread = &priv->disp_thread[sde_enc->crtc->index];
|
||||
event_thread = &priv->event_thread[sde_enc->crtc->index];
|
||||
|
||||
kthread_queue_work(&disp_thread->worker,
|
||||
&sde_enc->esd_trigger_work);
|
||||
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
|
||||
* hardware may hang without vsync. Avoid rsc hang by generating the
|
||||
|
Loading…
x
Reference in New Issue
Block a user