From patchwork Sun Sep 8 12:37:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: bugzilla-daemon@freedesktop.org X-Patchwork-Id: 11136911 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 A30E0912 for ; Sun, 8 Sep 2019 12:37:42 +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 844132081B for ; Sun, 8 Sep 2019 12:37:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 844132081B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=freedesktop.org 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 34F8F898C4; Sun, 8 Sep 2019 12:37:40 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from culpepper.freedesktop.org (culpepper.freedesktop.org [IPv6:2610:10:20:722:a800:ff:fe98:4b55]) by gabe.freedesktop.org (Postfix) with ESMTP id 23F41898C4 for ; Sun, 8 Sep 2019 12:37:39 +0000 (UTC) Received: by culpepper.freedesktop.org (Postfix, from userid 33) id D08C672167; Sun, 8 Sep 2019 12:37:38 +0000 (UTC) From: bugzilla-daemon@freedesktop.org To: dri-devel@lists.freedesktop.org Subject: [Bug 111588] Framebuffer corruption when a fb which is not being scanned out gets removed Date: Sun, 08 Sep 2019 12:37:39 +0000 X-Bugzilla-Reason: AssignedTo X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: DRI X-Bugzilla-Component: DRM/AMDgpu X-Bugzilla-Version: DRI git X-Bugzilla-Keywords: X-Bugzilla-Severity: not set X-Bugzilla-Who: jwrdegoede@fedoraproject.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: not set X-Bugzilla-Assigned-To: dri-devel@lists.freedesktop.org X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: X-Bugzilla-URL: http://bugs.freedesktop.org/ Auto-Submitted: auto-generated 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: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" https://bugs.freedesktop.org/show_bug.cgi?id=111588 --- Comment #1 from Hans de Goede --- I just realized I left out one bit of info which might be useful, to debug this I added the following change to the kernel: } @@ -863,6 +868,8 @@ static int atomic_remove_fb(struct drm_framebuffer *fb) if (plane->state->fb != fb) continue; + pr_err("atomic_remove_fb found plane still using fb\n"); + plane_state = drm_atomic_get_plane_state(state, plane); if (IS_ERR(plane_state)) { ret = PTR_ERR(plane_state); In the working case, so where we let the kernel do the fb cleanup itself, I see: Plymouth removes fb it creates to test for 32bpp support: kernel: drm_modr_rmfb calling drm_framebuffer_put gdm starts, does page-flipping, resulting in a number of: kernel: drm_modr_rmfb calling drm_framebuffer_put kernel: drm_modr_rmfb calling drm_framebuffer_put ... lines And then plymouth exits without any cleanup, so we get: kernel: drm_fb_release calling drm_framebuffer_put Followed by more: kernel: drm_modr_rmfb calling drm_framebuffer_put kernel: drm_modr_rmfb calling drm_framebuffer_put ... From gdm. In the broken case, where ply_renderer_buffer_free() gets called on plymouth-quit, I only see: kernel: drm_modr_rmfb calling drm_framebuffer_put kernel: drm_modr_rmfb calling drm_framebuffer_put ... lines, wihch is expected as the fb is rmfb-ed before the fd is closed. Note that we never hit: @@ -863,6 +868,8 @@ static int atomic_remove_fb(struct drm_framebuffer *fb) if (plane->state->fb != fb) continue; + pr_err("atomic_remove_fb found plane still using fb\n"); + plane_state = drm_atomic_get_plane_state(state, plane); if (IS_ERR(plane_state)) { ret = PTR_ERR(plane_state); So AFAICT userspace is doing everything correctly even in the broken case. diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 57564318ceea..4712bfb9ae05 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -464,6 +464,7 @@ int drm_mode_rmfb(struct drm_device *dev, u32 fb_id, if (drm_framebuffer_read_refcount(fb) > 1) { struct drm_mode_rmfb_work arg; + pr_err("drm_modr_rmfb calling drm_framebuffer_remove\n"); INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn); INIT_LIST_HEAD(&arg.fbs); list_add_tail(&fb->filp_head, &arg.fbs); @@ -471,8 +472,10 @@ int drm_mode_rmfb(struct drm_device *dev, u32 fb_id, schedule_work(&arg.work); flush_work(&arg.work); destroy_work_on_stack(&arg.work); - } else + } else { + pr_err("drm_modr_rmfb calling drm_framebuffer_put\n"); drm_framebuffer_put(fb); + } return 0; @@ -669,11 +672,13 @@ void drm_fb_release(struct drm_file *priv) */ list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) { if (drm_framebuffer_read_refcount(fb) > 1) { + pr_err("drm_fb_release calling drm_framebuffer_remove\n"); list_move_tail(&fb->filp_head, &arg.fbs); } else { list_del_init(&fb->filp_head); /* This drops the fpriv->fbs reference. */ + pr_err("drm_fb_release calling drm_framebuffer_put\n"); drm_framebuffer_put(fb); }