From patchwork Fri Apr 29 03:57:06 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: yao mark X-Patchwork-Id: 8976871 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 166DE9F1D3 for ; Fri, 29 Apr 2016 03:59:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4AB8220219 for ; Fri, 29 Apr 2016 03:59:19 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 678B120107 for ; Fri, 29 Apr 2016 03:59:18 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 340416EE38; Fri, 29 Apr 2016 03:59:15 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from regular1.263xmail.com (regular1.263xmail.com [211.150.99.141]) by gabe.freedesktop.org (Postfix) with ESMTPS id 315156EE38 for ; Fri, 29 Apr 2016 03:59:13 +0000 (UTC) Received: from mark.yao?rock-chips.com (unknown [192.168.167.192]) by regular1.263xmail.com (Postfix) with SMTP id 963C31A1; Fri, 29 Apr 2016 11:59:10 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-ABS-CHECKED: 4 X-ADDR-CHECKED: 0 X-KSVirus-check: 0 Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.263.net (Postfix) with ESMTP id 09B9524EFC; Fri, 29 Apr 2016 11:59:04 +0800 (CST) X-RL-SENDER: mark.yao@rock-chips.com X-FST-TO: airlied@linux.ie X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: mark.yao@rock-chips.com X-UNIQUE-TAG: X-ATTACHMENT-NUM: 0 X-SENDER: yzq@rock-chips.com X-DNS-TYPE: 0 Received: from localhost.localdomain (unknown [58.22.7.114]) by smtp.263.net (Postfix) whith ESMTP id 21462P7JSPT; Fri, 29 Apr 2016 11:59:06 +0800 (CST) From: Mark Yao To: David Airlie , Heiko Stuebner , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH] drm/rockchip: vop: fix iommu crash with async atomic Date: Fri, 29 Apr 2016 11:57:06 +0800 Message-Id: <1461902226-19773-1-git-send-email-mark.yao@rock-chips.com> X-Mailer: git-send-email 1.9.1 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-5.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Async atomic_commit callback, drm_atomic_clean_old_fb will clean all old fb, but because async, the old fb may be also on the vop hardware, dma will access the old fb buffer, clean old fb will cause iommu page fault. Reference the fb and unreference it when the fb actuall swap out from vop hardware. Signed-off-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 28596e7..38c4de9 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -560,6 +560,22 @@ static void vop_plane_destroy(struct drm_plane *plane) drm_plane_cleanup(plane); } +static int vop_plane_prepare_fb(struct drm_plane *plane, + const struct drm_plane_state *new_state) +{ + if (plane->state->fb) + drm_framebuffer_reference(plane->state->fb); + + return 0; +} + +static void vop_plane_cleanup_fb(struct drm_plane *plane, + const struct drm_plane_state *old_state) +{ + if (old_state->fb) + drm_framebuffer_unreference(old_state->fb); +} + static int vop_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { @@ -756,6 +772,8 @@ static void vop_plane_atomic_update(struct drm_plane *plane, } static const struct drm_plane_helper_funcs plane_helper_funcs = { + .prepare_fb = vop_plane_prepare_fb, + .cleanup_fb = vop_plane_cleanup_fb, .atomic_check = vop_plane_atomic_check, .atomic_update = vop_plane_atomic_update, .atomic_disable = vop_plane_atomic_disable,