From patchwork Tue Jun 28 10:27:47 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 924132 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p5SASHSw028088 for ; Tue, 28 Jun 2011 10:28:37 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 51B2D9F626 for ; Tue, 28 Jun 2011 03:28:16 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from fireflyinternet.com (server109-228-6-236.live-servers.net [109.228.6.236]) by gabe.freedesktop.org (Postfix) with ESMTP id 75E2F9E799 for ; Tue, 28 Jun 2011 03:27:56 -0700 (PDT) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.66.37; Received: from arrandale.alporthouse.com (unverified [78.156.66.37]) by fireflyinternet.com (Firefly Internet SMTP) with ESMTP id 38202891-1500050 for multiple; Tue, 28 Jun 2011 11:27:48 +0100 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Tue, 28 Jun 2011 11:27:47 +0100 Message-Id: <1309256867-26210-1-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 1.7.5.4 X-Originating-IP: 78.156.66.37 Subject: [Intel-gfx] [PATCH] drm/i915/overlay: Fix unpinning along init error paths 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.6 (demeter2.kernel.org [140.211.167.43]); Tue, 28 Jun 2011 10:28:37 +0000 (UTC) As pointed out by Dan Carpenter, it was seemingly possible to hit an error whilst mapping the buffer for the regs (except the only likely error returns should not happen during init) and so leak a pin count on the bo. To handle this we would need to reacquire the struct mutex, so for simplicity rearrange for the lock to be held for the entire function. For extra pedagogy, test that we only call init once. Signed-off-by: Chris Wilson Reviewed-by: Ben Widawsky Reviewed-by: Keith Packard --- drivers/gpu/drm/i915/intel_overlay.c | 17 ++++++++++------- 1 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index cffd3ed..d360380 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -1405,6 +1405,11 @@ void intel_setup_overlay(struct drm_device *dev) overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL); if (!overlay) return; + + mutex_lock(&dev->struct_mutex); + if (WARN_ON(dev_priv->overlay)) + goto out_free; + overlay->dev = dev; reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); @@ -1412,8 +1417,6 @@ void intel_setup_overlay(struct drm_device *dev) goto out_free; overlay->reg_bo = reg_bo; - mutex_lock(&dev->struct_mutex); - if (OVERLAY_NEEDS_PHYSICAL(dev)) { ret = i915_gem_attach_phys_object(dev, reg_bo, I915_GEM_PHYS_OVERLAY_REGS, @@ -1438,8 +1441,6 @@ void intel_setup_overlay(struct drm_device *dev) } } - mutex_unlock(&dev->struct_mutex); - /* init all values */ overlay->color_key = 0x0101fe; overlay->brightness = -19; @@ -1448,7 +1449,7 @@ void intel_setup_overlay(struct drm_device *dev) regs = intel_overlay_map_regs(overlay); if (!regs) - goto out_free_bo; + goto out_unpin_bo; memset(regs, 0, sizeof(struct overlay_registers)); update_polyphase_filter(regs); @@ -1457,15 +1458,17 @@ void intel_setup_overlay(struct drm_device *dev) intel_overlay_unmap_regs(overlay, regs); dev_priv->overlay = overlay; + mutex_unlock(&dev->struct_mutex); DRM_INFO("initialized overlay support\n"); return; out_unpin_bo: - i915_gem_object_unpin(reg_bo); + if (!OVERLAY_NEEDS_PHYSICAL(dev)) + i915_gem_object_unpin(reg_bo); out_free_bo: drm_gem_object_unreference(®_bo->base); - mutex_unlock(&dev->struct_mutex); out_free: + mutex_unlock(&dev->struct_mutex); kfree(overlay); return; }