From patchwork Sun Aug 22 11:05:24 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 122211 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o7MB7v2K022157 for ; Sun, 22 Aug 2010 11:09:01 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C11A29EB38 for ; Sun, 22 Aug 2010 04:07:57 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id 2AC719E9CC for ; Sun, 22 Aug 2010 04:06:01 -0700 (PDT) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 22 Aug 2010 04:06:00 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.56,251,1280732400"; d="scan'208";a="547572171" Received: from unknown (HELO cantiga.alporthouse.com) ([10.255.17.166]) by orsmga002.jf.intel.com with ESMTP; 22 Aug 2010 04:05:59 -0700 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Sun, 22 Aug 2010 12:05:24 +0100 Message-Id: <1282475148-15951-6-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1282475148-15951-1-git-send-email-chris@chris-wilson.co.uk> References: <1282475148-15951-1-git-send-email-chris@chris-wilson.co.uk> Cc: Daniel Vetter Subject: [Intel-gfx] [PATCH 05/29] drm/i915: unload: fix idle_timer/idle_work races X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Sun, 22 Aug 2010 11:09:01 +0000 (UTC) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4c663a8..ef26839 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -43,7 +43,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type); static void intel_update_watermarks(struct drm_device *dev); -static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule); +static void intel_increase_pllclock(struct drm_crtc *crtc); static void intel_crtc_update_cursor(struct drm_crtc *crtc); typedef struct { @@ -1512,7 +1512,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, intel_update_fbc(crtc, &crtc->mode); intel_wait_for_vblank(dev, intel_crtc->pipe); - intel_increase_pllclock(crtc, true); + intel_increase_pllclock(crtc); return 0; } @@ -1636,7 +1636,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, obj_priv = to_intel_bo(intel_fb->obj); i915_gem_object_unpin(intel_fb->obj); } - intel_increase_pllclock(crtc, true); + intel_increase_pllclock(crtc); mutex_unlock(&dev->struct_mutex); @@ -4719,7 +4719,7 @@ static void intel_crtc_idle_timer(unsigned long arg) queue_work(dev_priv->wq, &dev_priv->idle_work); } -static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule) +static void intel_increase_pllclock(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; drm_i915_private_t *dev_priv = dev->dev_private; @@ -4754,9 +4754,8 @@ static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule) } /* Schedule downclock */ - if (schedule) - mod_timer(&intel_crtc->idle_timer, jiffies + - msecs_to_jiffies(CRTC_IDLE_TIMEOUT)); + mod_timer(&intel_crtc->idle_timer, jiffies + + msecs_to_jiffies(CRTC_IDLE_TIMEOUT)); } static void intel_decrease_pllclock(struct drm_crtc *crtc) @@ -4892,7 +4891,7 @@ void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj) I915_WRITE(FW_BLC_SELF, fw_blc_self | FW_BLC_SELF_EN_MASK); } /* Non-busy -> busy, upclock */ - intel_increase_pllclock(crtc, true); + intel_increase_pllclock(crtc); intel_crtc->busy = true; } else { /* Busy -> busy, put off timer */ @@ -6074,12 +6073,9 @@ void intel_modeset_cleanup(struct drm_device *dev) continue; intel_crtc = to_intel_crtc(crtc); - intel_increase_pllclock(crtc, false); - del_timer_sync(&intel_crtc->idle_timer); + intel_increase_pllclock(crtc); } - del_timer_sync(&dev_priv->idle_timer); - if (dev_priv->display.disable_fbc) dev_priv->display.disable_fbc(dev); @@ -6113,10 +6109,17 @@ void intel_modeset_cleanup(struct drm_device *dev) drm_irq_uninstall(dev); cancel_work_sync(&dev_priv->hotplug_work); + /* Shut off idle work before the crtcs get freed. */ + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + intel_crtc = to_intel_crtc(crtc); + del_timer_sync(&intel_crtc->idle_timer); + } + del_timer_sync(&dev_priv->idle_timer); + cancel_work_sync(&dev_priv->idle_work); + drm_mode_config_cleanup(dev); } - /* * Return which encoder is currently attached for connector. */