From patchwork Thu Jun 8 09:51:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 9774319 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5A83A6034B for ; Thu, 8 Jun 2017 09:52:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 42B552848F for ; Thu, 8 Jun 2017 09:52:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 35F112850E; Thu, 8 Jun 2017 09:52: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=-4.2 required=2.0 tests=BAYES_00, 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 219922848F for ; Thu, 8 Jun 2017 09:52:00 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BC6CE6E37F; Thu, 8 Jun 2017 09:51:58 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from fireflyinternet.com (mail.fireflyinternet.com [109.228.58.192]) by gabe.freedesktop.org (Postfix) with ESMTPS id D9D5A6E37F for ; Thu, 8 Jun 2017 09:51:56 +0000 (UTC) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.65.138; Received: from haswell.alporthouse.com (unverified [78.156.65.138]) by fireflyinternet.com (Firefly Internet (M1)) with ESMTP id 7176794-1500050 for multiple; Thu, 08 Jun 2017 10:51:39 +0100 Received: by haswell.alporthouse.com (sSMTP sendmail emulation); Thu, 08 Jun 2017 10:51:38 +0100 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Thu, 8 Jun 2017 10:51:35 +0100 Message-Id: <20170608095135.21825-2-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170608095135.21825-1-chris@chris-wilson.co.uk> References: <20170608095135.21825-1-chris@chris-wilson.co.uk> X-Originating-IP: 78.156.65.138 X-Country: code=GB country="United Kingdom" ip=78.156.65.138 Subject: [Intel-gfx] [PATCH 2/2] drm/i915: Defer cleanup of active KMS state X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP During cleanup we release the VMA of the previous framebuffer. This requires taking a struct_mutex, and potential recursion when handling a reset. A simple device here is to move that locking into its own work and we can avoid blocking on it for the reset by waiting on the flip completion (and not cleanup completion) instead. Ideally this reduces the duration of a blocking KMS operation by offloading the cleanup. Once again we dream of the legendary vblank worker. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 53 +++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 121fdd278fcd..0a1170de96e2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12982,7 +12982,23 @@ static void intel_atomic_helper_free_state_worker(struct work_struct *work) intel_atomic_helper_free_state(dev_priv); } -static void intel_atomic_commit_tail(struct drm_atomic_state *state) +static void intel_atomic_commit_cleanup(struct work_struct *work) +{ + struct drm_atomic_state *state = + container_of(work, struct drm_atomic_state, commit_work); + struct drm_device *dev = state->dev; + struct drm_i915_private *dev_priv = to_i915(dev); + + drm_atomic_helper_cleanup_planes(dev, state); + drm_atomic_helper_commit_cleanup_done(state); + + drm_atomic_state_put(state); + + intel_atomic_helper_free_state(dev_priv); +} + +static void intel_atomic_commit_tail(struct drm_atomic_state *state, + bool nonblock) { struct drm_device *dev = state->dev; struct intel_atomic_state *intel_state = to_intel_atomic_state(state); @@ -13134,13 +13150,12 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET); } - drm_atomic_helper_cleanup_planes(dev, state); - - drm_atomic_helper_commit_cleanup_done(state); - - drm_atomic_state_put(state); - - intel_atomic_helper_free_state(dev_priv); + if (!nonblock) { + INIT_WORK(&state->commit_work, intel_atomic_commit_cleanup); + schedule_work(&state->commit_work); + } else { + intel_atomic_commit_cleanup(&state->commit_work); + } } static void intel_atomic_commit_work(struct work_struct *work) @@ -13148,7 +13163,7 @@ static void intel_atomic_commit_work(struct work_struct *work) struct drm_atomic_state *state = container_of(work, struct drm_atomic_state, commit_work); - intel_atomic_commit_tail(state); + intel_atomic_commit_tail(state, true); } static int __i915_sw_fence_call @@ -13190,6 +13205,23 @@ static void intel_atomic_track_fbs(struct drm_atomic_state *state) to_intel_plane(plane)->frontbuffer_bit); } +static void intel_atomic_state_wait_for_flips(struct intel_atomic_state *state) +{ + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + int i; + + for_each_new_crtc_in_state(&state->base, crtc, crtc_state, i) { + struct drm_crtc_commit *commit = state->base.crtcs[i].commit; + long ret; + + ret = wait_for_completion_timeout(&commit->flip_done, HZ); + if (ret == 0) + DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n", + crtc->base.id, crtc->name); + } +} + /** * intel_atomic_commit - commit validated state object * @dev: DRM device @@ -13265,7 +13297,8 @@ static int intel_atomic_commit(struct drm_device *dev, i915_sw_fence_commit(&intel_state->commit_ready); if (!nonblock) { i915_sw_fence_wait(&intel_state->commit_ready); - intel_atomic_commit_tail(state); + intel_atomic_commit_tail(state, false); + intel_atomic_state_wait_for_flips(intel_state); } return 0;