Received: by 2002:ac0:aed5:0:0:0:0:0 with SMTP id t21csp2502863imb; Mon, 4 Mar 2019 06:51:20 -0800 (PST) X-Google-Smtp-Source: APXvYqxWOrNTfXciJCzw8SIDKvEaTKGRaTOVystN+FC/uQKsgBq3f0WN6t+WfKivIXu35LGf3HSd X-Received: by 2002:a63:8048:: with SMTP id j69mr18667984pgd.432.1551711079953; Mon, 04 Mar 2019 06:51:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551711079; cv=none; d=google.com; s=arc-20160816; b=bzIXEF9PNTkHYmsOSzkv61GKQPlf4wicg8CIAJD3TybVl2ggGikfEwow2gxxuWgV/p RCUAdl1r+7VdDOMNUxS83TZKZe2O+gOYVo3loI8iyFxFuABZ4NuMhDCloHet0BcTM0C0 UKd1USirgT+6MjG8rp76l0Vi3u5B9RzXbRkvq/Ky/2CKV+DMlKogZGNxocXe6ZAvhAyO mt4nZZAvVHy37gUIus4fPoutCOivpsKhhSrrqxCBeNsYf/ZRfW53aeG83aHErl+oTHDt mz1AVwnh602w6PIGdTMqIjZPFFRbOTz9QKu6dvejrQiu3mvNnOgUFwaF3Nv7eNp9hIXW dJeg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=xfUgxntat6Yg5yeha7LeZ+5fuOPTR1wzTHjYqbUX3/M=; b=Ra7pb61EqN37eSKM7/OD1nSH3L7QxGkBWeYpyPwg/fyWxb8Zv/H1yGtaTENdY5D996 iLV62SQOCovgCVwZlV7QW2o223xPWIvb60rryoihJrx0um2SIp2EKAgLCIO/rLARR2pk aUvpPXgc4X3H5BHWlbmQT96nsmbD8aRFfex5fvUJYUrV8ImsmaIsXeevkGCRY0ksHTfH zuwkfaY7CVlkMJFSKO2mkIVQYt38lHDXXuYp8+2BBz1eIi11u9DVx4aSzHRJnAR9t3b2 FcyYyMj350o5AQJ413z+n5jehvyDZ36G1iQFKX4eENJ5vnjZ3GhyFwT1ujMqN/VCsdso LcXg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k3si5739100pll.57.2019.03.04.06.51.04; Mon, 04 Mar 2019 06:51:19 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727042AbfCDOt3 (ORCPT + 99 others); Mon, 4 Mar 2019 09:49:29 -0500 Received: from bhuna.collabora.co.uk ([46.235.227.227]:49286 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726161AbfCDOt2 (ORCPT ); Mon, 4 Mar 2019 09:49:28 -0500 Received: from localhost.localdomain (unknown [IPv6:2804:431:9718:a1b1:9d17:4c45:79a4:9c61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: koike) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 58BB1261176; Mon, 4 Mar 2019 14:49:23 +0000 (GMT) From: Helen Koike To: dri-devel@lists.freedesktop.org, nicholas.kazlauskas@amd.com Cc: andrey.grodzovsky@amd.com, daniel.vetter@ffwll.ch, linux-kernel@vger.kernel.org, Tomasz Figa , boris.brezillon@collabora.com, David Airlie , Sean Paul , kernel@collabora.com, harry.wentland@amd.com, =?UTF-8?q?St=C3=A9phane=20Marchesin?= Subject: [PATCH 1/5] drm: don't block fb changes for async plane updates Date: Mon, 4 Mar 2019 11:49:05 -0300 Message-Id: <20190304144909.6267-2-helen.koike@collabora.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190304144909.6267-1-helen.koike@collabora.com> References: <20190304144909.6267-1-helen.koike@collabora.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In the case of a normal sync update, the preparation of framebuffers (be it calling drm_atomic_helper_prepare_planes() or doing setups with drm_framebuffer_get()) are performed in the new_state and the respective cleanups are performed in the old_state. In the case of async updates, the preparation is also done in the new_state but the cleanups are done in the new_state (because updates are performed in place, i.e. in the current state). The current code blocks async udpates when the fb is changed, turning async updates into sync updates, slowing down cursor updates and introducing regressions in igt tests with errors of type: "CRITICAL: completed 97 cursor updated in a period of 30 flips, we expect to complete approximately 15360 updates, with the threshold set at 7680" Fb changes in async updates were prevented to avoid the following scenario: - Async update, oldfb = NULL, newfb = fb1, prepare fb1, cleanup fb1 - Async update, oldfb = fb1, newfb = fb2, prepare fb2, cleanup fb2 - Non-async commit, oldfb = fb2, newfb = fb1, prepare fb1, cleanup fb2 (wrong) Where we have a single call to prepare fb2 but double cleanup call to fb2. To solve the above problems, instead of blocking async fb changes, we place the old framebuffer in the new_state object, so when the code performs cleanups in the new_state it will cleanup the old_fb and we will have the following scenario instead: - Async update, oldfb = NULL, newfb = fb1, prepare fb1, no cleanup - Async update, oldfb = fb1, newfb = fb2, prepare fb2, cleanup fb1 - Non-async commit, oldfb = fb2, newfb = fb1, prepare fb1, cleanup fb2 Where calls to prepare/cleanup are ballanced. Cc: # v4.14+: 25dc194b34dd: drm: Block fb changes for async plane updates Fixes: 25dc194b34dd ("drm: Block fb changes for async plane updates") Suggested-by: Boris Brezillon Signed-off-by: Helen Koike --- Hello, As mentioned in the cover letter, I tested on the rockchip and on i915 (with a patch I am still working on for replacing cursors by async update), with igt plane_cursor_legacy and kms_cursor_legacy and I didn't see any regressions. I couldn't test on MSM and AMD because I don't have the hardware (and I am having some issues testing on vc4) and I would appreciate if anyone could help me testing those. I also think it would be a better solution if, instead of having async to do in-place updates in the current state, the async path should be equivalent to a syncronous update, i.e., modifying new_state and performing a flip IMHO, the only difference between sync and async should be that async update doesn't wait for vblank and applies the changes immeditally to the hw, but the code path could be almost the same. But for now I think this solution is ok (swaping new_fb/old_fb), and then we can adjust things little by little, what do you think? Thanks! Helen drivers/gpu/drm/drm_atomic_helper.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 540a77a2ade9..e7eb96f1efc2 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1608,15 +1608,6 @@ int drm_atomic_helper_async_check(struct drm_device *dev, old_plane_state->crtc != new_plane_state->crtc) return -EINVAL; - /* - * FIXME: Since prepare_fb and cleanup_fb are always called on - * the new_plane_state for async updates we need to block framebuffer - * changes. This prevents use of a fb that's been cleaned up and - * double cleanups from occuring. - */ - if (old_plane_state->fb != new_plane_state->fb) - return -EINVAL; - funcs = plane->helper_private; if (!funcs->atomic_async_update) return -EINVAL; @@ -1657,6 +1648,9 @@ void drm_atomic_helper_async_commit(struct drm_device *dev, int i; for_each_new_plane_in_state(state, plane, plane_state, i) { + struct drm_framebuffer *new_fb = plane_state->fb; + struct drm_framebuffer *old_fb = plane->state->fb; + funcs = plane->helper_private; funcs->atomic_async_update(plane, plane_state); @@ -1665,11 +1659,17 @@ void drm_atomic_helper_async_commit(struct drm_device *dev, * plane->state in-place, make sure at least common * properties have been properly updated. */ - WARN_ON_ONCE(plane->state->fb != plane_state->fb); + WARN_ON_ONCE(plane->state->fb != new_fb); WARN_ON_ONCE(plane->state->crtc_x != plane_state->crtc_x); WARN_ON_ONCE(plane->state->crtc_y != plane_state->crtc_y); WARN_ON_ONCE(plane->state->src_x != plane_state->src_x); WARN_ON_ONCE(plane->state->src_y != plane_state->src_y); + + /* + * Make sure the FBs have been swapped so that cleanups in the + * new_state performs a cleanup in the old FB. + */ + WARN_ON_ONCE(plane_state->fb != old_fb); } } EXPORT_SYMBOL(drm_atomic_helper_async_commit); -- 2.20.1