From patchwork Wed Sep 3 11:55:04 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 4834761 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 0756F9F314 for ; Wed, 3 Sep 2014 13:43:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DE80A2020E for ; Wed, 3 Sep 2014 13:43:17 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 878A920204 for ; Wed, 3 Sep 2014 13:43:16 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8C0236E576; Wed, 3 Sep 2014 06:43:11 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from bear.ext.ti.com (bear.ext.ti.com [192.94.94.41]) by gabe.freedesktop.org (Postfix) with ESMTP id 014E56E0F9 for ; Wed, 3 Sep 2014 04:55:29 -0700 (PDT) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id s83BtT1f009521; Wed, 3 Sep 2014 06:55:29 -0500 Received: from DLEE70.ent.ti.com (dlemailx.itg.ti.com [157.170.170.113]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id s83BtTI6010661; Wed, 3 Sep 2014 06:55:29 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE70.ent.ti.com (157.170.170.113) with Microsoft SMTP Server id 14.3.174.1; Wed, 3 Sep 2014 06:55:28 -0500 Received: from deskari.lan (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id s83BtNQD004347; Wed, 3 Sep 2014 06:55:27 -0500 From: Tomi Valkeinen To: Rob Clark , Subject: [PATCH 3/9] drm/omap: fix race issue with vsync irq and apply Date: Wed, 3 Sep 2014 14:55:04 +0300 Message-ID: <1409745310-19092-3-git-send-email-tomi.valkeinen@ti.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1409745310-19092-1-git-send-email-tomi.valkeinen@ti.com> References: <1409745310-19092-1-git-send-email-tomi.valkeinen@ti.com> MIME-Version: 1.0 X-Mailman-Approved-At: Wed, 03 Sep 2014 06:43:10 -0700 Cc: Tomi Valkeinen X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-5.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP omap_crtc's apply_worker does: omap_irq_register(dev, &omap_crtc->apply_irq); dispc_mgr_go(channel); This is supposed to enable the vsync irq, and set the GO bit. The vsync handler will later check if the HW has cleared the GO bit and queue apply work. However, what may happen is that the vsync irq is enabled, and it gets ran before the GO bit is set by the apply_worker. In this case the vsync handler will see the GO bit as cleared, and queues the apply work too early. This causes WARN'ings from dispc driver, and possibly other problems. This patch fixes the issue by adding a new variable, 'go_bit_set' which is used to track the supposed state of GO bit and helps the apply worker and irq handler handle the job without a race. Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_crtc.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 0812b0f80167..193979f97bdb 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -47,6 +47,9 @@ struct omap_crtc { bool enabled; bool full_update; + /* tracks the state of GO bit between irq handler and apply worker */ + bool go_bit_set; + struct omap_drm_apply apply; struct omap_drm_irq apply_irq; @@ -442,11 +445,16 @@ static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus) if (!omap_crtc->error_irq.registered) __omap_irq_register(crtc->dev, &omap_crtc->error_irq); - if (!dispc_mgr_go_busy(omap_crtc->channel)) { + /* make sure we see the most recent 'go_bit_set' */ + rmb(); + if (omap_crtc->go_bit_set && !dispc_mgr_go_busy(omap_crtc->channel)) { struct omap_drm_private *priv = crtc->dev->dev_private; DBG("%s: apply done", omap_crtc->name); __omap_irq_unregister(crtc->dev, &omap_crtc->apply_irq); + omap_crtc->go_bit_set = false; + /* make sure apple_worker sees 'go_bit_set = false' */ + wmb(); queue_work(priv->wq, &omap_crtc->apply_work); } } @@ -472,7 +480,9 @@ static void apply_worker(struct work_struct *work) * If we are still pending a previous update, wait.. when the * pending update completes, we get kicked again. */ - if (omap_crtc->apply_irq.registered) + /* make sure we see the most recent 'go_bit_set' */ + rmb(); + if (omap_crtc->go_bit_set) goto out; /* finish up previous apply's: */ @@ -502,6 +512,9 @@ static void apply_worker(struct work_struct *work) if (dispc_mgr_is_enabled(channel)) { omap_irq_register(dev, &omap_crtc->apply_irq); dispc_mgr_go(channel); + omap_crtc->go_bit_set = true; + /* make sure the irq handler sees 'go_bit_set' */ + wmb(); } else { struct omap_drm_private *priv = dev->dev_private; queue_work(priv->wq, &omap_crtc->apply_work);