From patchwork Fri Feb 21 19:03:35 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 3699471 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id CE5ACBF13A for ; Fri, 21 Feb 2014 19:04:06 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D032320179 for ; Fri, 21 Feb 2014 19:04:05 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id CAEEF2018A for ; Fri, 21 Feb 2014 19:04:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8D1CEFB62B; Fri, 21 Feb 2014 11:04:01 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id C0A2FFB626; Fri, 21 Feb 2014 11:03:58 -0800 (PST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 21 Feb 2014 11:03:58 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,520,1389772800"; d="scan'208";a="459600647" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.65]) by orsmga001.jf.intel.com with SMTP; 21 Feb 2014 11:03:56 -0800 Received: by stinkbox (sSMTP sendmail emulation); Fri, 21 Feb 2014 21:03:55 +0200 From: ville.syrjala@linux.intel.com To: dri-devel@lists.freedesktop.org Subject: [PATCH 5/5] drm/i915: Allow vblank interrupts during modeset and eliminate some vblank races Date: Fri, 21 Feb 2014 21:03:35 +0200 Message-Id: <1393009415-27651-6-git-send-email-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1393009415-27651-1-git-send-email-ville.syrjala@linux.intel.com> References: <1393009415-27651-1-git-send-email-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Cc: intel-gfx@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org X-Spam-Status: No, score=-5.2 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 From: Ville Syrjälä Tell the drm core vblank code to reject drm_vblank_get()s only between drm_vblank_off() and drm_vblank_on() calls, and sprinkle the appropriate drm_vblank_on() calls to the .crtc_enable() hooks. At this time I kept the off calls in their current position, and added the on calls to the end of .crtc_enable(). Later on these will be moved inwards a bit to allow vblank interrupts during plane enable/disable steps. We can kill of the drm_vblank_{pre,post}_modeset() calls since those are there simply to make drm_vblank_get() fail during a modeset. The way they do it is by grabbing a vblank reference, and after drm_vblank_off() gets called this will results in drm_vblank_get() failing due to the elevated refcount while vblank interrupts are disabled. Unfortunately this means there's no point during modeset where the behaviour can be restored back to the normal state until the vblank refcount drops to 0. There's no gurantee of that happening even after the modeset has completed, so simply dropping the drm_vblank_{pre,post}_modeset() calls is the best option. The new reject mechanism will take care of things in a much more consistent and race free manner. Testcase: igt/kms_flip/{dpms,modeset}-vs-vblank-race Signed-off-by: Ville Syrjälä Reviewed-by: Jesse Barnes --- drivers/gpu/drm/i915/i915_dma.c | 6 ++++++ drivers/gpu/drm/i915/intel_display.c | 23 +++++++++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7688abc..d5e27bb 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1293,6 +1293,12 @@ static int i915_load_modeset_init(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; int ret; + /* + * Allow the use of vblank interrupts during modeset, + * and make the vblank code behaviour more consistent + */ + dev->vblank_always_enable_on_get = true; + ret = intel_parse_bios(dev); if (ret) DRM_INFO("failed to find VBIOS tables\n"); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bab0d08..2933540 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3607,6 +3607,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) * happening. */ intel_wait_for_vblank(dev, intel_crtc->pipe); + + drm_vblank_on(dev, pipe); } /* IPS only exists on ULT machines and is tied to pipe A. */ @@ -3632,6 +3634,8 @@ static void haswell_crtc_enable_planes(struct drm_crtc *crtc) mutex_lock(&dev->struct_mutex); intel_update_fbc(dev); mutex_unlock(&dev->struct_mutex); + + drm_vblank_on(dev, pipe); } static void haswell_crtc_disable_planes(struct drm_crtc *crtc) @@ -3643,7 +3647,7 @@ static void haswell_crtc_disable_planes(struct drm_crtc *crtc) int plane = intel_crtc->plane; intel_crtc_wait_for_pending_flips(crtc); - drm_vblank_off(dev, pipe, false); + drm_vblank_off(dev, pipe, true); /* FBC must be disabled before disabling the plane on HSW. */ if (dev_priv->fbc.plane == plane) @@ -3774,7 +3778,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) encoder->disable(encoder); intel_crtc_wait_for_pending_flips(crtc); - drm_vblank_off(dev, pipe, false); + drm_vblank_off(dev, pipe, true); if (dev_priv->fbc.plane == plane) intel_disable_fbc(dev); @@ -4160,6 +4164,8 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) for_each_encoder_on_crtc(dev, crtc, encoder) encoder->enable(encoder); + + drm_vblank_on(dev, pipe); } static void i9xx_crtc_enable(struct drm_crtc *crtc) @@ -4205,6 +4211,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) for_each_encoder_on_crtc(dev, crtc, encoder) encoder->enable(encoder); + + drm_vblank_on(dev, pipe); } static void i9xx_pfit_disable(struct intel_crtc *crtc) @@ -4239,7 +4247,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) /* Give the overlay scaler a chance to disable if it's on this pipe */ intel_crtc_wait_for_pending_flips(crtc); - drm_vblank_off(dev, pipe, false); + drm_vblank_off(dev, pipe, true); if (dev_priv->fbc.plane == plane) intel_disable_fbc(dev); @@ -7035,15 +7043,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, struct intel_encoder *encoder; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_display_mode *mode = &intel_crtc->config.requested_mode; - int pipe = intel_crtc->pipe; int ret; - drm_vblank_pre_modeset(dev, pipe); - ret = dev_priv->display.crtc_mode_set(crtc, x, y, fb); - drm_vblank_post_modeset(dev, pipe); - if (ret != 0) return ret; @@ -11380,6 +11383,10 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); intel_sanitize_crtc(crtc); intel_dump_pipe_config(crtc, &crtc->config, "[setup_hw_state]"); + if (crtc->active) + drm_vblank_on(dev, crtc->pipe); + else + drm_vblank_off(dev, crtc->pipe, true); } for (i = 0; i < dev_priv->num_shared_dpll; i++) {