From patchwork Fri Nov 15 19:41:58 2019 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: 11246989 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 45AE713BD for ; Fri, 15 Nov 2019 19:42:17 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2E8A620732 for ; Fri, 15 Nov 2019 19:42:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2E8A620732 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C878E6E7B2; Fri, 15 Nov 2019 19:42:15 +0000 (UTC) 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 ESMTPS id D43B46E7B2; Fri, 15 Nov 2019 19:42:11 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Nov 2019 11:42:11 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,309,1569308400"; d="scan'208";a="208510022" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by orsmga006.jf.intel.com with SMTP; 15 Nov 2019 11:42:08 -0800 Received: by stinkbox (sSMTP sendmail emulation); Fri, 15 Nov 2019 21:42:08 +0200 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Subject: [PATCH 1/7] drm: Move page_flip fb lookup earlier Date: Fri, 15 Nov 2019 21:41:58 +0200 Message-Id: <20191115194204.22244-2-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191115194204.22244-1-ville.syrjala@linux.intel.com> References: <20191115194204.22244-1-ville.syrjala@linux.intel.com> 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: intel-gfx@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Ville Syrjälä No reason that I can see to delay the fb lookup this late. Moving it earlier allows us to keep it outside of the lock retry loop. This makes error handling and whatnot simpler. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/drm_plane.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index d6ad60ab0d38..14a292d7817d 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -1037,7 +1037,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, struct drm_mode_crtc_page_flip_target *page_flip = data; struct drm_crtc *crtc; struct drm_plane *plane; - struct drm_framebuffer *fb = NULL, *old_fb; + struct drm_framebuffer *fb, *old_fb; struct drm_pending_vblank_event *e = NULL; u32 target_vblank = page_flip->sequence; struct drm_modeset_acquire_ctx ctx; @@ -1086,16 +1086,16 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, DRM_DEBUG("Invalid absolute flip target %u, " "must be <= %u\n", target_vblank, current_vblank + 1); - drm_crtc_vblank_put(crtc); - return -EINVAL; + ret = -EINVAL; + goto put_vblank; } break; case DRM_MODE_PAGE_FLIP_TARGET_RELATIVE: if (target_vblank != 0 && target_vblank != 1) { DRM_DEBUG("Invalid relative flip target %u, " "must be 0 or 1\n", target_vblank); - drm_crtc_vblank_put(crtc); - return -EINVAL; + ret = -EINVAL; + goto put_vblank; } target_vblank += current_vblank; break; @@ -1106,7 +1106,14 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, } } else if (crtc->funcs->page_flip == NULL || (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET)) { - return -EINVAL; + ret = -EINVAL; + goto put_vblank; + } + + fb = drm_framebuffer_lookup(dev, file_priv, page_flip->fb_id); + if (!fb) { + ret = -ENOENT; + goto put_vblank; } drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); @@ -1132,12 +1139,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, goto out; } - fb = drm_framebuffer_lookup(dev, file_priv, page_flip->fb_id); - if (!fb) { - ret = -ENOENT; - goto out; - } - if (plane->state) { const struct drm_plane_state *state = plane->state; @@ -1201,8 +1202,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, } out: - if (fb) - drm_framebuffer_put(fb); if (plane->old_fb) drm_framebuffer_put(plane->old_fb); plane->old_fb = NULL; @@ -1216,6 +1215,8 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); + drm_framebuffer_put(fb); +put_vblank: if (ret && crtc->funcs->page_flip_target) drm_crtc_vblank_put(crtc); From patchwork Fri Nov 15 19:41:59 2019 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: 11246995 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 822DB13BD for ; Fri, 15 Nov 2019 19:42:22 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6B52D20732 for ; Fri, 15 Nov 2019 19:42:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6B52D20732 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 21B4D6E7C6; Fri, 15 Nov 2019 19:42:19 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3E5076E7B5; Fri, 15 Nov 2019 19:42:15 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Nov 2019 11:42:14 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,309,1569308400"; d="scan'208";a="236185158" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by fmsmga002.fm.intel.com with SMTP; 15 Nov 2019 11:42:12 -0800 Received: by stinkbox (sSMTP sendmail emulation); Fri, 15 Nov 2019 21:42:11 +0200 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Subject: [PATCH 2/7] drm: Allocate the page flip event earlier Date: Fri, 15 Nov 2019 21:41:59 +0200 Message-Id: <20191115194204.22244-3-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191115194204.22244-1-ville.syrjala@linux.intel.com> References: <20191115194204.22244-1-ville.syrjala@linux.intel.com> 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: intel-gfx@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Ville Syrjälä Can't see why we need to delay the page flip event allocation until the last moment. Move it earlier to simplify error handling. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/drm_plane.c | 45 +++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 14a292d7817d..38878da5b704 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -1116,6 +1116,26 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, goto put_vblank; } + if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { + e = kzalloc(sizeof(*e), GFP_KERNEL); + if (!e) { + ret = -ENOMEM; + goto put_fb; + } + + e->event.base.type = DRM_EVENT_FLIP_COMPLETE; + e->event.base.length = sizeof(e->event); + e->event.vbl.user_data = page_flip->user_data; + e->event.vbl.crtc_id = crtc->base.id; + + ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); + if (ret) { + kfree(e); + e = NULL; + goto put_fb; + } + } + drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); retry: ret = drm_modeset_lock(&crtc->mutex, &ctx); @@ -1160,26 +1180,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, goto out; } - if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { - e = kzalloc(sizeof *e, GFP_KERNEL); - if (!e) { - ret = -ENOMEM; - goto out; - } - - e->event.base.type = DRM_EVENT_FLIP_COMPLETE; - e->event.base.length = sizeof(e->event); - e->event.vbl.user_data = page_flip->user_data; - e->event.vbl.crtc_id = crtc->base.id; - - ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); - if (ret) { - kfree(e); - e = NULL; - goto out; - } - } - plane->old_fb = plane->fb; if (crtc->funcs->page_flip_target) ret = crtc->funcs->page_flip_target(crtc, fb, e, @@ -1190,8 +1190,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags, &ctx); if (ret) { - if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) - drm_event_cancel_free(dev, &e->base); /* Keep the old fb, don't unref it. */ plane->old_fb = NULL; } else { @@ -1215,6 +1213,9 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); + if (ret && e) + drm_event_cancel_free(dev, &e->base); +put_fb: drm_framebuffer_put(fb); put_vblank: if (ret && crtc->funcs->page_flip_target) From patchwork Fri Nov 15 19:42:00 2019 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: 11246997 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CD58D13BD for ; Fri, 15 Nov 2019 19:42:24 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B60A62073B for ; Fri, 15 Nov 2019 19:42:24 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B60A62073B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 72DF06E7D5; Fri, 15 Nov 2019 19:42:22 +0000 (UTC) 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 ESMTPS id 043FF6E7B5; Fri, 15 Nov 2019 19:42:17 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Nov 2019 11:42:17 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,309,1569308400"; d="scan'208";a="199303734" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by orsmga008.jf.intel.com with SMTP; 15 Nov 2019 11:42:15 -0800 Received: by stinkbox (sSMTP sendmail emulation); Fri, 15 Nov 2019 21:42:14 +0200 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Subject: [PATCH 3/7] drm: Extract page_flip_{internal,atomic}() Date: Fri, 15 Nov 2019 21:42:00 +0200 Message-Id: <20191115194204.22244-4-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191115194204.22244-1-ville.syrjala@linux.intel.com> References: <20191115194204.22244-1-ville.syrjala@linux.intel.com> 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: intel-gfx@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Ville Syrjälä Yank out the code for the plane->fb/old_fb/crtc handling from the page flip path into page_flip_internal(), and provide a simpler variant for atomic drivers. We'll also move the fb vs. src viewport checks into the new functions as they are slightly different between the two paths. If the atomic .page_flip() implementations are guaranteed to call drm_atomic_plane_check() we could even drop the check entirely from page_flip_atomic(). For now toss in a FIXME. v2: Bit more polish in page_flip_internal() Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/drm_plane.c | 159 +++++++++++++++++++++++------------- 1 file changed, 102 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 38878da5b704..6052475a20a5 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -1031,13 +1031,109 @@ int drm_mode_cursor2_ioctl(struct drm_device *dev, return drm_mode_cursor_common(dev, req, file_priv); } +static int page_flip_check_fbs(const struct drm_framebuffer *fb, + const struct drm_framebuffer *old_fb) +{ + /* The framebuffer is currently unbound, presumably + * due to a hotplug event, that userspace has not + * yet discovered. + */ + if (!old_fb) + return -EBUSY; + + if (old_fb->format != fb->format) { + DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n"); + return -EINVAL; + } + + return 0; +} + +static int page_flip_internal(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *e, + u32 flags, + u32 target_vblank, + struct drm_modeset_acquire_ctx *ctx) +{ + struct drm_plane *plane = crtc->primary; + int ret; + + WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev)); + + ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y, + &crtc->mode, fb); + if (ret) + return ret; + + ret = page_flip_check_fbs(fb, plane->fb); + if (ret) + return ret; + + plane->old_fb = plane->fb; + if (crtc->funcs->page_flip_target) + ret = crtc->funcs->page_flip_target(crtc, fb, e, flags, + target_vblank, ctx); + else + ret = crtc->funcs->page_flip(crtc, fb, e, flags, ctx); + if (ret) { + plane->old_fb = NULL; + return ret; + } + + plane->fb = fb; + drm_framebuffer_get(plane->fb); + + drm_framebuffer_put(plane->old_fb); + plane->old_fb = NULL; + + return 0; +} + +static int page_flip_atomic(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *e, + u32 flags, + u32 target_vblank, + struct drm_modeset_acquire_ctx *ctx) +{ + struct drm_plane *plane = crtc->primary; + struct drm_plane_state *plane_state = plane->state; + int ret; + + WARN_ON(!drm_drv_uses_atomic_modeset(crtc->dev)); + + /* + * FIXME: Can we assume all drivers end up calling + * drm_atomic_plane_check() in their page flip paths? + * If so we could remove this. + */ + ret = drm_framebuffer_check_src_coords(plane_state->src_x, + plane_state->src_y, + plane_state->src_w, + plane_state->src_h, + fb); + if (ret) + return ret; + + ret = page_flip_check_fbs(fb, plane_state->fb); + if (ret) + return ret; + + if (crtc->funcs->page_flip_target) + return crtc->funcs->page_flip_target(crtc, fb, e, flags, + target_vblank, ctx); + else + return crtc->funcs->page_flip(crtc, fb, e, flags, ctx); +} + int drm_mode_page_flip_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_mode_crtc_page_flip_target *page_flip = data; struct drm_crtc *crtc; struct drm_plane *plane; - struct drm_framebuffer *fb, *old_fb; + struct drm_framebuffer *fb; struct drm_pending_vblank_event *e = NULL; u32 target_vblank = page_flip->sequence; struct drm_modeset_acquire_ctx ctx; @@ -1145,65 +1241,14 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, if (ret) goto out; - if (plane->state) - old_fb = plane->state->fb; + if (drm_drv_uses_atomic_modeset(dev)) + ret = page_flip_atomic(crtc, fb, e, page_flip->flags, + target_vblank, &ctx); else - old_fb = plane->fb; - - if (old_fb == NULL) { - /* The framebuffer is currently unbound, presumably - * due to a hotplug event, that userspace has not - * yet discovered. - */ - ret = -EBUSY; - goto out; - } - - if (plane->state) { - const struct drm_plane_state *state = plane->state; - - ret = drm_framebuffer_check_src_coords(state->src_x, - state->src_y, - state->src_w, - state->src_h, - fb); - } else { - ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y, - &crtc->mode, fb); - } - if (ret) - goto out; - - if (old_fb->format != fb->format) { - DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n"); - ret = -EINVAL; - goto out; - } - - plane->old_fb = plane->fb; - if (crtc->funcs->page_flip_target) - ret = crtc->funcs->page_flip_target(crtc, fb, e, - page_flip->flags, - target_vblank, - &ctx); - else - ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags, - &ctx); - if (ret) { - /* Keep the old fb, don't unref it. */ - plane->old_fb = NULL; - } else { - if (!plane->state) { - plane->fb = fb; - drm_framebuffer_get(fb); - } - } + ret = page_flip_internal(crtc, fb, e, page_flip->flags, + target_vblank, &ctx); out: - if (plane->old_fb) - drm_framebuffer_put(plane->old_fb); - plane->old_fb = NULL; - if (ret == -EDEADLK) { ret = drm_modeset_backoff(&ctx); if (!ret) From patchwork Fri Nov 15 19:42:01 2019 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: 11247003 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8A51913BD for ; Fri, 15 Nov 2019 19:42:30 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6FC1F20732 for ; Fri, 15 Nov 2019 19:42:30 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6FC1F20732 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 42E456E7D3; Fri, 15 Nov 2019 19:42:27 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2A3446E7D3; Fri, 15 Nov 2019 19:42:21 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Nov 2019 11:42:20 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,309,1569308400"; d="scan'208";a="195486622" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by orsmga007.jf.intel.com with SMTP; 15 Nov 2019 11:42:18 -0800 Received: by stinkbox (sSMTP sendmail emulation); Fri, 15 Nov 2019 21:42:17 +0200 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Subject: [PATCH 4/7] drm: Simplify the setplane old_fb handling further Date: Fri, 15 Nov 2019 21:42:01 +0200 Message-Id: <20191115194204.22244-5-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191115194204.22244-1-ville.syrjala@linux.intel.com> References: <20191115194204.22244-1-ville.syrjala@linux.intel.com> 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: intel-gfx@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Ville Syrjälä Instead of doing the things in a convoluted way with the failure and success paths mixed up let's just clear old_fb when we encounter an error and bail out immediately. We already did this for the pageflip path. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/drm_plane.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 6052475a20a5..ef0cc33b43ce 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -688,12 +688,13 @@ static int __setplane_internal(struct drm_plane *plane, if (!fb) { plane->old_fb = plane->fb; ret = plane->funcs->disable_plane(plane, ctx); - if (!ret) { - plane->crtc = NULL; - plane->fb = NULL; - } else { + if (ret) { plane->old_fb = NULL; + return ret; } + + plane->crtc = NULL; + plane->fb = NULL; goto out; } @@ -701,26 +702,27 @@ static int __setplane_internal(struct drm_plane *plane, crtc_x, crtc_y, crtc_w, crtc_h, src_x, src_y, src_w, src_h); if (ret) - goto out; + return ret; plane->old_fb = plane->fb; ret = plane->funcs->update_plane(plane, crtc, fb, crtc_x, crtc_y, crtc_w, crtc_h, src_x, src_y, src_w, src_h, ctx); - if (!ret) { - plane->crtc = crtc; - plane->fb = fb; - drm_framebuffer_get(plane->fb); - } else { + if (ret) { plane->old_fb = NULL; + return ret; } + plane->crtc = crtc; + plane->fb = fb; + drm_framebuffer_get(plane->fb); + out: if (plane->old_fb) drm_framebuffer_put(plane->old_fb); plane->old_fb = NULL; - return ret; + return 0; } static int __setplane_atomic(struct drm_plane *plane, From patchwork Fri Nov 15 19:42:02 2019 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: 11247005 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DA4A413BD for ; Fri, 15 Nov 2019 19:42:32 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C2CAE20732 for ; Fri, 15 Nov 2019 19:42:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C2CAE20732 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 909056EA73; Fri, 15 Nov 2019 19:42:28 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3F8BF6EA5D; Fri, 15 Nov 2019 19:42:23 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Nov 2019 11:42:23 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,309,1569308400"; d="scan'208";a="203474619" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by fmsmga008.fm.intel.com with SMTP; 15 Nov 2019 11:42:21 -0800 Received: by stinkbox (sSMTP sendmail emulation); Fri, 15 Nov 2019 21:42:20 +0200 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Subject: [PATCH 5/7] drm/selftests: Add some selftests for drm_atomic_set_mode_for_crtc() Date: Fri, 15 Nov 2019 21:42:02 +0200 Message-Id: <20191115194204.22244-6-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191115194204.22244-1-ville.syrjala@linux.intel.com> References: <20191115194204.22244-1-ville.syrjala@linux.intel.com> 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: intel-gfx@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Ville Syrjälä Test the basics of drm_atomic_set_mode_for_crtc(), and in particular verify that the function doesn't take the shortcut incorrectly. Cc: Daniel Vetter Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter --- drivers/gpu/drm/selftests/Makefile | 3 +- .../gpu/drm/selftests/drm_modeset_selftests.h | 2 + .../gpu/drm/selftests/test-drm_atomic_uapi.c | 110 ++++++++++++++++++ .../drm/selftests/test-drm_modeset_common.h | 2 + 4 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/selftests/test-drm_atomic_uapi.c diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index d2137342b371..a5adc25bd345 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \ test-drm_format.o test-drm_framebuffer.o \ - test-drm_damage_helper.o test-drm_dp_mst_helper.o + test-drm_damage_helper.o test-drm_dp_mst_helper.o \ + test-drm_atomic_uapi.o obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o test-drm_cmdline_parser.o diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h index 1898de0b4a4d..2cc4e2f43286 100644 --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h @@ -6,6 +6,8 @@ * * Tests are executed in order by igt/drm_selftests_helper */ +selftest(atomic_set_mode_for_crtc, igt_atomic_set_mode_for_crtc) +selftest(atomic_set_zeroed_mode_for_crtc, igt_atomic_set_zeroed_mode_for_crtc) selftest(check_plane_state, igt_check_plane_state) selftest(check_drm_format_block_width, igt_check_drm_format_block_width) selftest(check_drm_format_block_height, igt_check_drm_format_block_height) diff --git a/drivers/gpu/drm/selftests/test-drm_atomic_uapi.c b/drivers/gpu/drm/selftests/test-drm_atomic_uapi.c new file mode 100644 index 000000000000..0f9a4d0d2541 --- /dev/null +++ b/drivers/gpu/drm/selftests/test-drm_atomic_uapi.c @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test cases for the drm_atomic_uapi functions + */ + +#define pr_fmt(fmt) "drm_atomic_uapi: " fmt + +#include +#include +#include +#include + +#include "test-drm_modeset_common.h" + +static const struct drm_display_mode zeroed_mode; + +static struct drm_driver mock_driver; +static struct drm_device mock_device; +static struct drm_crtc mock_crtc; + +static void init(void) +{ + memset(&mock_driver, 0, sizeof(mock_driver)); + memset(&mock_device, 0, sizeof(mock_device)); + memset(&mock_crtc, 0, sizeof(mock_crtc)); + + mock_device.driver = &mock_driver; + mock_crtc.dev = &mock_device; + + drm_mode_config_init(&mock_device); +} + +static void cleanup(void) +{ + drm_mode_config_cleanup(&mock_device); +} + +int igt_atomic_set_mode_for_crtc(void *ignored) +{ + static const struct drm_display_mode mode1 = { + DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, + 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) + }; + static const struct drm_display_mode mode2 = { + DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, + 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) + }; + struct drm_crtc_state crtc_state = { + .crtc = &mock_crtc, + }; + int ret; + + init(); + + /* + * Make sure drm_atomic_set_mode_for_crtc() + * updates the crtc state correctly. + */ + ret = drm_atomic_set_mode_for_crtc(&crtc_state, &mode1); + FAIL(ret < 0, "Unable to set mode on crtc\n"); + FAIL_ON(!crtc_state.enable); + FAIL_ON(memcmp(&crtc_state.mode, &mode1, sizeof(mode1))); + + ret = drm_atomic_set_mode_for_crtc(&crtc_state, &mode2); + FAIL(ret < 0, "Unable to set mode on crtc\n"); + FAIL_ON(!crtc_state.enable); + FAIL_ON(memcmp(&crtc_state.mode, &mode2, sizeof(mode2))); + + ret = drm_atomic_set_mode_for_crtc(&crtc_state, NULL); + FAIL(ret < 0, "Unable to unset mode on crtc\n"); + FAIL_ON(crtc_state.enable); + FAIL_ON(memcmp(&crtc_state.mode, &zeroed_mode, sizeof(zeroed_mode))); + + cleanup(); + + return 0; +} + +int igt_atomic_set_zeroed_mode_for_crtc(void *ignored) +{ + struct drm_crtc_state crtc_state = { + .crtc = &mock_crtc, + }; + int ret; + + init(); + + /* + * Make sure drm_atomic_set_mode_for_crtc() doesn't + * take the shortcut and fail to update crtc_state.enable + * when passed a zeroed mode (which is technically not + * valid, but as drm_atomic_set_mode_for_crtc() does no + * mode validation it should still work). + */ + ret = drm_atomic_set_mode_for_crtc(&crtc_state, &zeroed_mode); + FAIL(ret < 0, "Unable to set mode on crtc\n"); + FAIL_ON(!crtc_state.enable); + FAIL_ON(memcmp(&crtc_state.mode, &zeroed_mode, sizeof(zeroed_mode))); + + ret = drm_atomic_set_mode_for_crtc(&crtc_state, NULL); + FAIL(ret < 0, "Unable to unset mode on crtc\n"); + FAIL_ON(crtc_state.enable); + FAIL_ON(memcmp(&crtc_state.mode, &zeroed_mode, sizeof(zeroed_mode))); + + cleanup(); + + return 0; +} diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h index 0fcb8bbc6a1b..a1248abf86f9 100644 --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h @@ -13,6 +13,8 @@ #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n") +int igt_atomic_set_mode_for_crtc(void *ignored); +int igt_atomic_set_zeroed_mode_for_crtc(void *ignored); int igt_check_plane_state(void *ignored); int igt_check_drm_format_block_width(void *ignored); int igt_check_drm_format_block_height(void *ignored); From patchwork Fri Nov 15 19:42:03 2019 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: 11247007 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 014CC6C1 for ; Fri, 15 Nov 2019 19:42:35 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DDE7E20732 for ; Fri, 15 Nov 2019 19:42:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DDE7E20732 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 70E336EA75; Fri, 15 Nov 2019 19:42:29 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id 922796E7D3; Fri, 15 Nov 2019 19:42:26 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Nov 2019 11:42:26 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,309,1569308400"; d="scan'208";a="257849847" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by FMSMGA003.fm.intel.com with SMTP; 15 Nov 2019 11:42:24 -0800 Received: by stinkbox (sSMTP sendmail emulation); Fri, 15 Nov 2019 21:42:23 +0200 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Subject: [PATCH 6/7] drm/atomic: Fix the early return in drm_atomic_set_mode_for_crtc() Date: Fri, 15 Nov 2019 21:42:03 +0200 Message-Id: <20191115194204.22244-7-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191115194204.22244-1-ville.syrjala@linux.intel.com> References: <20191115194204.22244-1-ville.syrjala@linux.intel.com> 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: intel-gfx@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Ville Syrjälä The early return in drm_atomic_set_mode_for_crtc() isn't quite right. It would mistakenly return and fail to update crtc_state->enable if someone actually tried to set a zeroed mode on a currently disabled crtc. That should never actually happen in response to any userspace request as the zeroed mode would get rejected earlier. However there is some chance of this happening internally (eg. during hw state readout) so it seems best to not let the state become totally inconsistent. Additionally the early return will not be taken if we're trying to disable an already disabled crtc. While that is not actually harmful it is inconsistent, so let's handle that case as well. Testcase: igt/kms_selftest/check_atomic_set_mode_for_crtc Testcase: igt/kms_selftest/check_atomic_set_zeroed_mode_fort_crtc Reviewed-by: Daniel Vetter Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic_uapi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 0d466d3b0809..a3a6a8137af4 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -68,8 +68,13 @@ int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, struct drm_mode_modeinfo umode; /* Early return for no change. */ - if (mode && memcmp(&state->mode, mode, sizeof(*mode)) == 0) - return 0; + if (state->enable) { + if (mode && memcmp(&state->mode, mode, sizeof(*mode)) == 0) + return 0; + } else { + if (!mode) + return 0; + } drm_property_blob_put(state->mode_blob); state->mode_blob = NULL; From patchwork Fri Nov 15 19:42:04 2019 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: 11247011 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E181413BD for ; Fri, 15 Nov 2019 19:42:37 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CAB9E20732 for ; Fri, 15 Nov 2019 19:42:37 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CAB9E20732 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 75E0A6EA71; Fri, 15 Nov 2019 19:42:33 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 06A7B6EA71; Fri, 15 Nov 2019 19:42:29 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Nov 2019 11:42:29 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,309,1569308400"; d="scan'208";a="214834407" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by fmsmga001.fm.intel.com with SMTP; 15 Nov 2019 11:42:27 -0800 Received: by stinkbox (sSMTP sendmail emulation); Fri, 15 Nov 2019 21:42:26 +0200 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Subject: [PATCH 7/7] drm/atomic: Reduce setplane locking Date: Fri, 15 Nov 2019 21:42:04 +0200 Message-Id: <20191115194204.22244-8-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191115194204.22244-1-ville.syrjala@linux.intel.com> References: <20191115194204.22244-1-ville.syrjala@linux.intel.com> 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: intel-gfx@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Ville Syrjälä Currently setplane grabs all modeset locks, which seems a bit excessive. Let's reduce that to just the locks we really need on atomic drivers. For non-atomic drivers let's stick to the current scheme for now. Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_plane.c | 56 +++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index ef0cc33b43ce..e40d8a93294b 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -680,10 +680,14 @@ static int __setplane_internal(struct drm_plane *plane, uint32_t src_w, uint32_t src_h, struct drm_modeset_acquire_ctx *ctx) { - int ret = 0; + int ret; WARN_ON(drm_drv_uses_atomic_modeset(plane->dev)); + ret = drm_modeset_lock_all_ctx(plane->dev, ctx); + if (ret) + return ret; + /* No fb means shut it down */ if (!fb) { plane->old_fb = plane->fb; @@ -767,32 +771,24 @@ static int setplane_internal(struct drm_plane *plane, uint32_t crtc_w, uint32_t crtc_h, /* src_{x,y,w,h} values are 16.16 fixed point */ uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) + uint32_t src_w, uint32_t src_h, + struct drm_modeset_acquire_ctx *ctx) { - struct drm_modeset_acquire_ctx ctx; - int ret; - - DRM_MODESET_LOCK_ALL_BEGIN(plane->dev, ctx, - DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret); - if (drm_drv_uses_atomic_modeset(plane->dev)) - ret = __setplane_atomic(plane, crtc, fb, - crtc_x, crtc_y, crtc_w, crtc_h, - src_x, src_y, src_w, src_h, &ctx); + return __setplane_atomic(plane, crtc, fb, + crtc_x, crtc_y, crtc_w, crtc_h, + src_x, src_y, src_w, src_h, ctx); else - ret = __setplane_internal(plane, crtc, fb, - crtc_x, crtc_y, crtc_w, crtc_h, - src_x, src_y, src_w, src_h, &ctx); - - DRM_MODESET_LOCK_ALL_END(ctx, ret); - - return ret; + return __setplane_internal(plane, crtc, fb, + crtc_x, crtc_y, crtc_w, crtc_h, + src_x, src_y, src_w, src_h, ctx); } int drm_mode_setplane(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_mode_set_plane *plane_req = data; + struct drm_modeset_acquire_ctx ctx; struct drm_plane *plane; struct drm_crtc *crtc = NULL; struct drm_framebuffer *fb = NULL; @@ -829,11 +825,22 @@ int drm_mode_setplane(struct drm_device *dev, void *data, } } + drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); + +retry: ret = setplane_internal(plane, crtc, fb, plane_req->crtc_x, plane_req->crtc_y, plane_req->crtc_w, plane_req->crtc_h, plane_req->src_x, plane_req->src_y, - plane_req->src_w, plane_req->src_h); + plane_req->src_w, plane_req->src_h, &ctx); + if (ret == -EDEADLK) { + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry; + } + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); if (fb) drm_framebuffer_put(fb); @@ -907,14 +914,9 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc, src_h = fb->height << 16; } - if (drm_drv_uses_atomic_modeset(dev)) - ret = __setplane_atomic(plane, crtc, fb, - crtc_x, crtc_y, crtc_w, crtc_h, - 0, 0, src_w, src_h, ctx); - else - ret = __setplane_internal(plane, crtc, fb, - crtc_x, crtc_y, crtc_w, crtc_h, - 0, 0, src_w, src_h, ctx); + ret = setplane_internal(plane, crtc, fb, + crtc_x, crtc_y, crtc_w, crtc_h, + 0, 0, src_w, src_h, ctx); if (fb) drm_framebuffer_put(fb);