From d0db21101bf6cc0130a9f33382368ca59a488eb1 Mon Sep 17 00:00:00 2001 From: Guchun Chen Date: Fri, 20 Oct 2017 16:51:20 +0800 Subject: [PATCH] drm: msm: fix list corruption problem When multiple worker threads compete to update event_list, with current vblank_ctrl_worker mechanism, there is one risk which can casue list node is deleted for twice. This is because, due to the protected scope by the spin_lock, mutex can exit when one thread is transvering the list, but another queue thread may continue to add new event to the list. This brings conflict risk. This patch is to correct this. Change-Id: Ice31462d196c57ce18d7b998c1a1f0b7feeb08fc Signed-off-by: Xiaowen Wu Signed-off-by: Guchun Chen --- drivers/gpu/drm/msm/msm_drv.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index b245a4c7c826..6f968e93d959 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -185,12 +185,16 @@ static void vblank_ctrl_worker(struct kthread_work *work) struct msm_kms *kms = priv->kms; struct vblank_event *vbl_ev, *tmp; unsigned long flags; + LIST_HEAD(tmp_head); spin_lock_irqsave(&vbl_ctrl->lock, flags); list_for_each_entry_safe(vbl_ev, tmp, &vbl_ctrl->event_list, node) { list_del(&vbl_ev->node); - spin_unlock_irqrestore(&vbl_ctrl->lock, flags); + list_add_tail(&vbl_ev->node, &tmp_head); + } + spin_unlock_irqrestore(&vbl_ctrl->lock, flags); + list_for_each_entry_safe(vbl_ev, tmp, &tmp_head, node) { if (vbl_ev->enable) kms->funcs->enable_vblank(kms, priv->crtcs[vbl_ev->crtc_id]); @@ -199,11 +203,7 @@ static void vblank_ctrl_worker(struct kthread_work *work) priv->crtcs[vbl_ev->crtc_id]); kfree(vbl_ev); - - spin_lock_irqsave(&vbl_ctrl->lock, flags); } - - spin_unlock_irqrestore(&vbl_ctrl->lock, flags); } static int vblank_ctrl_queue_work(struct msm_drm_private *priv,