From patchwork Wed Dec 12 13:06:54 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 1867101 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 3D0073FC81 for ; Wed, 12 Dec 2012 14:34:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 20F9AE6617 for ; Wed, 12 Dec 2012 06:34:30 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-ee0-f49.google.com (mail-ee0-f49.google.com [74.125.83.49]) by gabe.freedesktop.org (Postfix) with ESMTP id 6059BE613D for ; Wed, 12 Dec 2012 05:15:29 -0800 (PST) Received: by mail-ee0-f49.google.com with SMTP id c4so430653eek.36 for ; Wed, 12 Dec 2012 05:15:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=3d02hvgOuIzCf8QqPWGDU1WWDFCAzcM5sbGi4dNrFrk=; b=LUkafbAw3+6J211/ma7kFgRLZkffAk6IqGTT3pJbLbh6XWwT3IBhr/buz9gfCdJnhS bVmY8jzhJDVLSEojm32xQrYy7BwXt6IjX+a5BNYZofRhB5Ljgbp4C2p9jJ72uEZDrSo/ 8ksNZlJBupPso4zwaxCUiyGM8Vnkgz08JKRm4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=3d02hvgOuIzCf8QqPWGDU1WWDFCAzcM5sbGi4dNrFrk=; b=WUzobUrRCZYhN3EomDEOMdlCRIPHtq2X05U4jTIXhBkMkvcsqtu97Rl14/nAdFDuLJ Y97MlupnmgrKR5HXP3IKxkT+UpZbqp/e6OBGkdVf977UjlLVma8gFGDtanRCbuVCy0sX WRd1MlmSB7tlqLedwTvFE+4f/ljfhqIVb0+9qeacqMKItaLqdJ9irBo3sVSvPnixp+hR f3T6cESz3WClyYVSvx+TYEAFMkN9pqNLXG5l+YUxLxR07b5//6beft/jYagqZvXKFGA7 rBr33E16Ra6ANYEFE8DyqjvAJ3WXKziHgWfJdzeItlASMIcUnAnv3oiCJbc/rCo7Lys8 7kDw== Received: by 10.14.203.8 with SMTP id e8mr2717659eeo.2.1355317658255; Wed, 12 Dec 2012 05:07:38 -0800 (PST) Received: from biers.ffwll.local (178-83-130-250.dynamic.hispeed.ch. [178.83.130.250]) by mx.google.com with ESMTPS id r1sm55868541eeo.2.2012.12.12.05.07.37 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 12 Dec 2012 05:07:37 -0800 (PST) From: Daniel Vetter To: DRI Development Subject: [PATCH 14/37] drm: only take the crtc lock for ->cursor_set Date: Wed, 12 Dec 2012 14:06:54 +0100 Message-Id: <1355317637-16742-15-git-send-email-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1355317637-16742-1-git-send-email-daniel.vetter@ffwll.ch> References: <1355317637-16742-1-git-send-email-daniel.vetter@ffwll.ch> X-Gm-Message-State: ALoCoQlj3sInC5aUeoBMFiUGpy57SLzHqwqAQY6S4sGsBm8mny+ogkufPfim0Dp7fsM1ALsbTC0R Cc: Nouveau Dev , Intel Graphics Development , Radeon Dev , Daniel Vetter 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: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org First convert ->cursor_set to only take the crtc lock, since that seems to be the function with the least amount of state - the core ioctl function doesn't check anything which can change at runtime, so we don't have any object lifetime issues to contend. The only thing which is important is that the driver's implementation doesn't touch any state outside of that single crtc which is not yet properly protected by other locking: - ast: access the global ast->cache_kmap. Luckily we only have on crtc on this driver, so this is fine. Add a comment. - gma500: calls gma_power_begin|and and psb_gtt_pin|unpin, both which have their own locking to protect their state. Everything else is crtc-local. - i915: touches a bit of global gem state, all protected by the One Lock to Rule Them All (dev->struct_mutex). - nouveau: Pre-nv50 is all nice, nv50+ uses the evo channels to queue up all display changes. And some of these channels are device global. But this is fine now since the previous patch introduced an evo channel mutex. - radeon: Uses some indirect register access for cursor updates, but with the previous patches to protect these indirect 2-register access patterns with a spinlock, this should be fine now, too. - vmwgfx: I have no idea how that works - update_cursor_position doesn't take any per-crtc argument and I haven't figured out any other place where this could be set in some form of a side-channel. But vmwgfx definitely has more than one crtc (or at least can register more than one), so I have no idea how this is supposed to not fail with the current code already. Hence take the easy way out and simply acquire all locks (which requires dropping the crtc lock the core acquired for us). That way it's not worse off for consistency than the old code. Signed-off-by: Daniel Vetter --- drivers/gpu/drm/ast/ast_drv.h | 2 ++ drivers/gpu/drm/drm_crtc.c | 6 ++++-- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 32 ++++++++++++++++++++++++++------ 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 5ccf984..5284292 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -98,6 +98,8 @@ struct ast_private { struct drm_gem_object *cursor_cache; uint64_t cursor_cache_gpu_addr; + /* Acces to this cache is protected by the crtc->mutex of the only crtc + * we have. */ struct ttm_bo_kmap_obj cache_kmap; int next_cursor; }; diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 91e8068..62b5002 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2023,7 +2023,6 @@ int drm_mode_cursor_ioctl(struct drm_device *dev, if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags)) return -EINVAL; - drm_modeset_lock_all(dev); obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC); if (!obj) { DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id); @@ -2038,20 +2037,23 @@ int drm_mode_cursor_ioctl(struct drm_device *dev, goto out; } /* Turns off the cursor if handle is 0 */ + mutex_lock(&crtc->mutex); ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle, req->width, req->height); + mutex_unlock(&crtc->mutex); } if (req->flags & DRM_MODE_CURSOR_MOVE) { if (crtc->funcs->cursor_move) { + drm_modeset_lock_all(dev); ret = crtc->funcs->cursor_move(crtc, req->x, req->y); + drm_modeset_unlock_all(dev); } else { ret = -EFAULT; goto out; } } out: - drm_modeset_unlock_all(dev); return ret; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 5474394..74b6734 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -180,16 +180,29 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, struct vmw_dma_buffer *dmabuf = NULL; int ret; + /* + * FIXME: Unclear whether there's any global state touched by the + * cursor_set function, especially vmw_cursor_update_position looks + * suspicious. For now take the easy route and reacquire all locks. We + * can do this since the caller in the drm core doesn't check anything + * which is protected by any looks. + */ + mutex_unlock(&crtc->mutex); + drm_modeset_lock_all(dev_priv->dev); + /* A lot of the code assumes this */ - if (handle && (width != 64 || height != 64)) - return -EINVAL; + if (handle && (width != 64 || height != 64)) { + ret = -EINVAL; + goto out; + } if (handle) { ret = vmw_user_lookup_handle(dev_priv, tfile, handle, &surface, &dmabuf); if (ret) { DRM_ERROR("failed to find surface or dmabuf: %i\n", ret); - return -EINVAL; + ret = -EINVAL; + goto out; } } @@ -197,7 +210,8 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, if (surface && !surface->snooper.image) { DRM_ERROR("surface not suitable for cursor\n"); vmw_surface_unreference(&surface); - return -EINVAL; + ret = -EINVAL; + goto out; } /* takedown old cursor */ @@ -225,14 +239,20 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, du->hotspot_x, du->hotspot_y); } else { vmw_cursor_update_position(dev_priv, false, 0, 0); - return 0; + ret = 0; + goto out; } vmw_cursor_update_position(dev_priv, true, du->cursor_x + du->hotspot_x, du->cursor_y + du->hotspot_y); - return 0; + ret = 0; +out: + drm_modeset_unlock_all(dev_priv->dev); + mutex_lock(&crtc->mutex); + + return ret; } int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)