From patchwork Tue Nov 27 22:46:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 10701559 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B1BD3109C for ; Tue, 27 Nov 2018 22:47:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9E2BF2B6C3 for ; Tue, 27 Nov 2018 22:47:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8E39F2B6DB; Tue, 27 Nov 2018 22:47:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,SUBJ_OBFU_PUNCT_FEW autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 21F932B6C3 for ; Tue, 27 Nov 2018 22:47:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8D6CE6E062; Tue, 27 Nov 2018 22:46:58 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yb1-xb42.google.com (mail-yb1-xb42.google.com [IPv6:2607:f8b0:4864:20::b42]) by gabe.freedesktop.org (Postfix) with ESMTPS id BDAF26E062 for ; Tue, 27 Nov 2018 22:46:56 +0000 (UTC) Received: by mail-yb1-xb42.google.com with SMTP id g192-v6so9810321ybf.3 for ; Tue, 27 Nov 2018 14:46:56 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=edhWJYU+Biw6ylCCNKPfa7O+O6wgMom6hxIloiyj6r8=; b=ooit8PghMvbUZhglJ5Zfm/j5V3TK2eih37nSMtnGxH+OMi5+1b3eL9D70V9QcTvM6f SXQSQKbpPVqIel2FZylvpXXC4rk+x0VfMGu0qefSB4ovzrpKq282huLn2bGBK2ePClKY jaFSZTnPOja+Ei5TrOkQWty5sfLztFF5ipf15hHj0eea3HCqrOKSCR7mrfZRX98B4qmj vv6QkzRjPU4+bDoDh18Ww3gpmQLion2QtW6V+tB+TcPVHmoV0Mw43PGZcknwrMRDs8tP KtnRW7B8FtXqaulE1M9uQI2u16/OIOgXP72n4lB83bI2leRBUw0VZwVrOMC2QjS0wQrX 9m0Q== X-Gm-Message-State: AA+aEWYt6U4tfvTh7FYmq7qXckX7ciwqwHWcLrfxR4sm4yc1kv2o8oAS pSZ64gdHQWVY8q3nc91LRt0hFIo6ddJXTQ== X-Google-Smtp-Source: AFSGD/Vrd4dTmwbqlfxgkFeGhfCJ2IjFOtJWiz7Qa0WK/1Pm2wu3kyWKAOn/er8DjssUyS1aLLz8yQ== X-Received: by 2002:a25:ae51:: with SMTP id g17-v6mr30783346ybe.338.1543358815767; Tue, 27 Nov 2018 14:46:55 -0800 (PST) Received: from rosewood.cam.corp.google.com ([2620:0:1013:11:ad55:b1db:adfe:3b9f]) by smtp.gmail.com with ESMTPSA id r193-v6sm1615157ywg.32.2018.11.27.14.46.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 Nov 2018 14:46:55 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org Subject: [PATCH 1/3] drm: Move drm_mode_setcrtc() local re-init to failure path Date: Tue, 27 Nov 2018 17:46:38 -0500 Message-Id: <20181127224654.48331-1-sean@poorly.run> X-Mailer: git-send-email 2.20.0.rc0.387.gc7a69e6b6c-goog MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Maxime Ripard , David Airlie , Sean Paul , Sean Paul Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Sean Paul Instead of always re-initializing the variables we need to clean up on out, move the re-initialization into the branch that goes back to retry label. This is a lateral move right now, but will allow us to pull out the modeset locking into common code. I kept this change separate to make things easier to review. Cc: Daniel Vetter Signed-off-by: Sean Paul Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 268a182ae1893..af4b94ce8e942 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -570,9 +570,9 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, struct drm_mode_crtc *crtc_req = data; struct drm_crtc *crtc; struct drm_plane *plane; - struct drm_connector **connector_set, *connector; - struct drm_framebuffer *fb; - struct drm_display_mode *mode; + struct drm_connector **connector_set = NULL, *connector; + struct drm_framebuffer *fb = NULL; + struct drm_display_mode *mode = NULL; struct drm_mode_set set; uint32_t __user *set_connectors_ptr; struct drm_modeset_acquire_ctx ctx; @@ -601,10 +601,6 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, mutex_lock(&crtc->dev->mode_config.mutex); drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); retry: - connector_set = NULL; - fb = NULL; - mode = NULL; - ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx); if (ret) goto out; @@ -766,6 +762,12 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, } kfree(connector_set); drm_mode_destroy(dev, mode); + + /* In case we need to retry... */ + connector_set = NULL; + fb = NULL; + mode = NULL; + if (ret == -EDEADLK) { ret = drm_modeset_backoff(&ctx); if (!ret) From patchwork Tue Nov 27 22:46:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 10701561 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E9EC7109C for ; Tue, 27 Nov 2018 22:47:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DB45C2B6C3 for ; Tue, 27 Nov 2018 22:47:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CEE6F2B6DB; Tue, 27 Nov 2018 22:47:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 918232B6C3 for ; Tue, 27 Nov 2018 22:47:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 76E8B6E09F; Tue, 27 Nov 2018 22:47:03 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yw1-xc42.google.com (mail-yw1-xc42.google.com [IPv6:2607:f8b0:4864:20::c42]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3DA5C6E09F for ; Tue, 27 Nov 2018 22:47:00 +0000 (UTC) Received: by mail-yw1-xc42.google.com with SMTP id d190so9871239ywd.12 for ; Tue, 27 Nov 2018 14:47:00 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=aEHY8Jpb0Yl4KBqq9tV4WKNeVQq0/DXsou66Lwsm058=; b=NqqPWO8iKnMDiQXOz2HidRHyFStQ1uL/ACUgyNcePQBWwfNHTS821hrpvkrcvhdmcH 5Vp73Fy14E04pHYrTFiTKbXSslSAET93vOMikWhYp795XnyxCCbVc8N8p67qrM7HuVpU RMelkTIK50pN3Um9IZvCxxBQq8ksc0pl+KmAFz1ZUtnHWrvHZvgYEJLvviWyGRi0jXYq qhL6+WIVXir8skGV+1TEHcphaQqukbw/OUEgHBA0SR3yo1ykKEmCq0OkM41ym2PrLVtO G9zeTAEeR88XmU3+C/MsOw/LT1draCO+/88f5LOMgT5aAWO6KhwLx+G45X09P4ja9v7Z GSfA== X-Gm-Message-State: AGRZ1gJDiVxe+RamgPuIhPPOEcUtBTMLYjjiE2WPYLgFZgyc08Yf1pIz sL1uS6TY1mVvuV2KLehvuipbAGeqgKtC3Q== X-Google-Smtp-Source: AJdET5cEt3vnUfzbln0CQlKg0msCeVTej164xZ/WmAdREiP7ppd5U2bN3HJNtGqJpF58WGOKt1uNdw== X-Received: by 2002:a81:b619:: with SMTP id u25mr36492492ywh.129.1543358819303; Tue, 27 Nov 2018 14:46:59 -0800 (PST) Received: from rosewood.cam.corp.google.com ([2620:0:1013:11:ad55:b1db:adfe:3b9f]) by smtp.gmail.com with ESMTPSA id r193-v6sm1615157ywg.32.2018.11.27.14.46.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 Nov 2018 14:46:58 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org Subject: [PATCH 2/3] drm: Move atomic_state_put after locks are dropped Date: Tue, 27 Nov 2018 17:46:39 -0500 Message-Id: <20181127224654.48331-2-sean@poorly.run> X-Mailer: git-send-email 2.20.0.rc0.387.gc7a69e6b6c-goog In-Reply-To: <20181127224654.48331-1-sean@poorly.run> References: <20181127224654.48331-1-sean@poorly.run> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Maxime Ripard , David Airlie , Sean Paul , Sean Paul Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Sean Paul drm_atomic_state_put doesn't require any locking, and this makes things easier for switching to modeset_lock_all helpers in a future patch Cc: Daniel Vetter Signed-off-by: Sean Paul --- drivers/gpu/drm/drm_atomic_helper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index fe8dd8aa4ae40..15a75b9f185fa 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3286,9 +3286,10 @@ int drm_atomic_helper_resume(struct drm_device *dev, drm_modeset_backoff(&ctx); } - drm_atomic_state_put(state); + state->acquire_ctx = NULL; drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); + drm_atomic_state_put(state); return err; } From patchwork Tue Nov 27 22:46:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 10701563 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BD8E2109C for ; Tue, 27 Nov 2018 22:47:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AC9BA2B6C3 for ; Tue, 27 Nov 2018 22:47:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9DE532B6DB; Tue, 27 Nov 2018 22:47:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 090432B6C3 for ; Tue, 27 Nov 2018 22:47:09 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0633C6E22F; Tue, 27 Nov 2018 22:47:09 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yw1-xc42.google.com (mail-yw1-xc42.google.com [IPv6:2607:f8b0:4864:20::c42]) by gabe.freedesktop.org (Postfix) with ESMTPS id B0BC56E0F4 for ; Tue, 27 Nov 2018 22:47:03 +0000 (UTC) Received: by mail-yw1-xc42.google.com with SMTP id h193so8654394ywc.4 for ; Tue, 27 Nov 2018 14:47:03 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BIHbAJKsZKvpuIUUnM72rruGWGsokpueqKk489r5GQw=; b=ZyK5jzUqhUV54POP+Ot19kIu8wadp3An+QxhfjnMsCtrLlr/8/ncm1cB/+WzaTuG9n 5NdRuaD08RyRb5WluqOkxHmO+o36qa4jwHF3YvnBDgV7YpEiVb65BrFrNMXYNqek9I64 RDUYXDj0FaUTy7K26955axaNOKPuzxtXAlxttwmYQWduuB93Q9jNW45LCC+HqZSDLCLa iDEjc+JcEaqnipQzGEU3ZejWx/tkYFP34efF4UNS6zp9hM3q4trl7LDHKVpK0y/JonW4 apSqy/loLaoOmwc0QTCkU468gSwq8RpRX4T59KoF0NX+8rUSWnxaRMGniyo0x8OzqqGH ZYRw== X-Gm-Message-State: AGRZ1gJ9L/UA0nalOBxveJYv1F91hxGwweVGgB4Y1mTriK7D6NlN3hRV SCDgn9Y3l3A1jHlvaCLUel/94F7jAtpliA== X-Google-Smtp-Source: AJdET5dYbWxwOfrrs5lGtrSLGBnZO2BBmPaAly8RVaXCMG0UsYvPXPI52lbfNM+Xg4NqlrOOu9pj7w== X-Received: by 2002:a0d:e24b:: with SMTP id l72mr36804184ywe.25.1543358822723; Tue, 27 Nov 2018 14:47:02 -0800 (PST) Received: from rosewood.cam.corp.google.com ([2620:0:1013:11:ad55:b1db:adfe:3b9f]) by smtp.gmail.com with ESMTPSA id r193-v6sm1615157ywg.32.2018.11.27.14.47.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 Nov 2018 14:47:02 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org Subject: [PATCH 3/3] drm: Add DRM_MODESET_LOCK_BEGIN/END helpers Date: Tue, 27 Nov 2018 17:46:40 -0500 Message-Id: <20181127224654.48331-3-sean@poorly.run> X-Mailer: git-send-email 2.20.0.rc0.387.gc7a69e6b6c-goog In-Reply-To: <20181127224654.48331-1-sean@poorly.run> References: <20181127224654.48331-1-sean@poorly.run> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Maxime Ripard , David Airlie , Sean Paul , Sean Paul Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Sean Paul This patch adds a couple of helpers to remove the boilerplate involved in grabbing all of the modeset locks. I've also converted the obvious cases in drm core to use the helpers. The only remaining instance of drm_modeset_lock_all_ctx() is in drm_framebuffer. It's complicated by the state clear that occurs on deadlock. ATM, there's no way to inject code in the deadlock path with the helpers, so it's unfit for conversion. Cc: Daniel Vetter Signed-off-by: Sean Paul Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic_helper.c | 52 ++++++--------------------- drivers/gpu/drm/drm_color_mgmt.c | 14 ++------ drivers/gpu/drm/drm_crtc.c | 15 ++------ drivers/gpu/drm/drm_plane.c | 16 ++------- include/drm/drm_modeset_lock.h | 54 +++++++++++++++++++++++++++++ 5 files changed, 72 insertions(+), 79 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 15a75b9f185fa..997735eea9abc 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3124,23 +3124,13 @@ void drm_atomic_helper_shutdown(struct drm_device *dev) struct drm_modeset_acquire_ctx ctx; int ret; - drm_modeset_acquire_init(&ctx, 0); - while (1) { - ret = drm_modeset_lock_all_ctx(dev, &ctx); - if (!ret) - ret = __drm_atomic_helper_disable_all(dev, &ctx, true); - - if (ret != -EDEADLK) - break; - - drm_modeset_backoff(&ctx); - } + DRM_MODESET_LOCK_ALL_BEGIN(dev, ret, ctx, 0); + ret = __drm_atomic_helper_disable_all(dev, &ctx, true); if (ret) DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret); - drm_modeset_drop_locks(&ctx); - drm_modeset_acquire_fini(&ctx); + DRM_MODESET_LOCK_ALL_END(ret, ctx); } EXPORT_SYMBOL(drm_atomic_helper_shutdown); @@ -3175,14 +3165,7 @@ struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev) struct drm_atomic_state *state; int err; - drm_modeset_acquire_init(&ctx, 0); - -retry: - err = drm_modeset_lock_all_ctx(dev, &ctx); - if (err < 0) { - state = ERR_PTR(err); - goto unlock; - } + DRM_MODESET_LOCK_ALL_BEGIN(dev, err, ctx, 0); state = drm_atomic_helper_duplicate_state(dev, &ctx); if (IS_ERR(state)) @@ -3191,18 +3174,14 @@ struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev) err = drm_atomic_helper_disable_all(dev, &ctx); if (err < 0) { drm_atomic_state_put(state); - state = ERR_PTR(err); goto unlock; } unlock: - if (PTR_ERR(state) == -EDEADLK) { - drm_modeset_backoff(&ctx); - goto retry; - } + DRM_MODESET_LOCK_ALL_END(err, ctx); + if (err) + return ERR_PTR(err); - drm_modeset_drop_locks(&ctx); - drm_modeset_acquire_fini(&ctx); return state; } EXPORT_SYMBOL(drm_atomic_helper_suspend); @@ -3272,23 +3251,12 @@ int drm_atomic_helper_resume(struct drm_device *dev, drm_mode_config_reset(dev); - drm_modeset_acquire_init(&ctx, 0); - while (1) { - err = drm_modeset_lock_all_ctx(dev, &ctx); - if (err) - goto out; + DRM_MODESET_LOCK_ALL_BEGIN(dev, err, ctx, 0); - err = drm_atomic_helper_commit_duplicated_state(state, &ctx); -out: - if (err != -EDEADLK) - break; - - drm_modeset_backoff(&ctx); - } + err = drm_atomic_helper_commit_duplicated_state(state, &ctx); state->acquire_ctx = NULL; - drm_modeset_drop_locks(&ctx); - drm_modeset_acquire_fini(&ctx); + DRM_MODESET_LOCK_ALL_END(err, ctx); drm_atomic_state_put(state); return err; diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 581cc37882230..9c6827171d795 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -255,11 +255,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev, if (crtc_lut->gamma_size != crtc->gamma_size) return -EINVAL; - drm_modeset_acquire_init(&ctx, 0); -retry: - ret = drm_modeset_lock_all_ctx(dev, &ctx); - if (ret) - goto out; + DRM_MODESET_LOCK_ALL_BEGIN(dev, ret, ctx, 0); size = crtc_lut->gamma_size * (sizeof(uint16_t)); r_base = crtc->gamma_store; @@ -284,13 +280,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev, crtc->gamma_size, &ctx); out: - if (ret == -EDEADLK) { - drm_modeset_backoff(&ctx); - goto retry; - } - drm_modeset_drop_locks(&ctx); - drm_modeset_acquire_fini(&ctx); - + DRM_MODESET_LOCK_ALL_END(ret, ctx); return ret; } diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index af4b94ce8e942..4b3d45239407e 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -599,11 +599,8 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, plane = crtc->primary; mutex_lock(&crtc->dev->mode_config.mutex); - drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); -retry: - ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx); - if (ret) - goto out; + DRM_MODESET_LOCK_ALL_BEGIN(dev, ret, ctx, + DRM_MODESET_ACQUIRE_INTERRUPTIBLE); if (crtc_req->mode_valid) { /* If we have a mode we need a framebuffer. */ @@ -768,13 +765,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, fb = NULL; mode = NULL; - if (ret == -EDEADLK) { - ret = drm_modeset_backoff(&ctx); - if (!ret) - goto retry; - } - drm_modeset_drop_locks(&ctx); - drm_modeset_acquire_fini(&ctx); + DRM_MODESET_LOCK_ALL_END(ret, ctx); mutex_unlock(&crtc->dev->mode_config.mutex); return ret; diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 679455e368298..37472edb4f303 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -767,11 +767,8 @@ static int setplane_internal(struct drm_plane *plane, struct drm_modeset_acquire_ctx ctx; int ret; - drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); -retry: - ret = drm_modeset_lock_all_ctx(plane->dev, &ctx); - if (ret) - goto fail; + DRM_MODESET_LOCK_ALL_BEGIN(plane->dev, ret, ctx, + DRM_MODESET_ACQUIRE_INTERRUPTIBLE); if (drm_drv_uses_atomic_modeset(plane->dev)) ret = __setplane_atomic(plane, crtc, fb, @@ -782,14 +779,7 @@ static int setplane_internal(struct drm_plane *plane, crtc_x, crtc_y, crtc_w, crtc_h, src_x, src_y, src_w, src_h, &ctx); -fail: - if (ret == -EDEADLK) { - ret = drm_modeset_backoff(&ctx); - if (!ret) - goto retry; - } - drm_modeset_drop_locks(&ctx); - drm_modeset_acquire_fini(&ctx); + DRM_MODESET_LOCK_ALL_END(ret, ctx); return ret; } diff --git a/include/drm/drm_modeset_lock.h b/include/drm/drm_modeset_lock.h index a685d1bb21f26..6213a11445633 100644 --- a/include/drm/drm_modeset_lock.h +++ b/include/drm/drm_modeset_lock.h @@ -130,4 +130,58 @@ void drm_warn_on_modeset_not_all_locked(struct drm_device *dev); int drm_modeset_lock_all_ctx(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx); +/** + * DRM_MODESET_LOCK_ALL_BEGIN - Helper to acquire modeset locks + * @dev: drm device + * @ret: local ret/err/etc variable to track error status + * @ctx: local modeset acquire context, will be dereferenced + * @flags: DRM_MODESET_ACQUIRE_* flags to pass to acquire_init() + * + * Use these macros to simplify grabbing all modeset locks using a local + * context. This has the advantage of reducing boilerplate, but also properly + * checking return values where appropriate. + * + * Any code run between BEGIN and END will be holding the modeset locks. + * + * This must be paired with DRM_MODESET_LOCAL_ALL_END. We will jump back and + * forth between the labels on deadlock and error conditions. + * + * Returns: The only possible value of ret immediately after + * DRM_MODESET_LOCK_ALL_BEGIN is 0, so no error checking is necessary. + */ +#define DRM_MODESET_LOCK_ALL_BEGIN(dev, ret, ctx, flags) \ + drm_modeset_acquire_init(&ctx, flags); \ +modeset_lock_retry: \ + ret = drm_modeset_lock_all_ctx(dev, &ctx); \ + if (ret) \ + goto modeset_lock_fail; + +/** + * DRM_MODESET_LOCK_ALL_END - Helper to release and cleanup modeset locks + * @ret: local ret/err/etc variable to track error status + * @ctx: local modeset acquire context, will be dereferenced + * + * The other side of DRM_MODESET_LOCK_ALL_BEGIN. It will bounce back to BEGIN if + * ret is -EDEADLK. + * + * It's important that you use the same ret variable for begin and end so + * deadlock conditions are properly handled. + * + * Returns: ret will be untouched unless it is -EDEADLK. That means that if you + * successfully acquire the locks, ret will be whatever your code sets + * it to. If there is a deadlock or other failure with acquire or + * backoff, ret will be set to that failure. In both of these cases the + * code between BEGIN/END will not be run, so the failure will reflect + * the inability to grab the locks. + */ +#define DRM_MODESET_LOCK_ALL_END(ret, ctx) \ +modeset_lock_fail: \ + if (ret == -EDEADLK) { \ + ret = drm_modeset_backoff(&ctx); \ + if (!ret) \ + goto modeset_lock_retry; \ + } \ + drm_modeset_drop_locks(&ctx); \ + drm_modeset_acquire_fini(&ctx); + #endif /* DRM_MODESET_LOCK_H_ */