[packages/Mesa] upstream fixes for redraw freeze on panfrost with xwayland >= 21.1.3

atler atler at pld-linux.org
Tue Feb 22 20:13:10 CET 2022


commit d5a5b39e61527a153cbd0b69f3bc0c867caa4168
Author: Jan Palus <atler at pld-linux.org>
Date:   Tue Feb 22 20:06:51 2022 +0100

    upstream fixes for redraw freeze on panfrost with xwayland >= 21.1.3
    
    from:
    https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15120

 Mesa.spec                    |   2 +
 panfrost_xwayland_hang.patch | 187 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 189 insertions(+)
---
diff --git a/Mesa.spec b/Mesa.spec
index 001bfc6..2ede3f0 100644
--- a/Mesa.spec
+++ b/Mesa.spec
@@ -82,6 +82,7 @@ Group:		X11/Libraries
 Source0:	https://gitlab.freedesktop.org/mesa/mesa/-/archive/mesa-%{version}/mesa-mesa-%{version}.tar.bz2
 # Source0-md5:	83d64d27f9195cb720e7cbd9cab65d26
 Patch0:		zink_x32.patch
+Patch1:		panfrost_xwayland_hang.patch
 URL:		https://www.mesa3d.org/
 %{?with_opencl_spirv:BuildRequires:	SPIRV-LLVM-Translator-devel >= 8.0.1.3}
 %{?with_gallium_zink:BuildRequires:	Vulkan-Loader-devel}
@@ -1507,6 +1508,7 @@ radv - eksperymentalny sterownik Vulkan dla GPU firmy AMD.
 %prep
 %setup -q -n mesa-mesa-%{version}
 %patch0 -p1
+%patch1 -p1
 
 %build
 %if %{with opencl}
diff --git a/panfrost_xwayland_hang.patch b/panfrost_xwayland_hang.patch
new file mode 100644
index 0000000..ba96177
--- /dev/null
+++ b/panfrost_xwayland_hang.patch
@@ -0,0 +1,187 @@
+From 74e4a5018b85af139dca06f3a614667d3d16748d Mon Sep 17 00:00:00 2001
+From: Alyssa Rosenzweig <alyssa at collabora.com>
+Date: Tue, 22 Feb 2022 11:24:58 -0500
+Subject: [PATCH 1/2] panfrost: Fix FD resource_get_handle
+
+When handle->type is WINSYS_HANDLE_TYPE_FD, the caller wants a file descriptor
+for the BO backing the resource. We previously had two paths for this:
+
+1. If rsrc->scanout is available, we prime the GEM handle from the KMS device
+   (rsrc->scanout->handle) to a file descriptor via the KMS device.
+
+2. If rsrc->scanout is not available, we prime the GEM handle from the GPU
+   (bo->gem_handle) to a file descriptor via the GPU device.
+
+In both cases, the caller passes in a resource (with BO) and expects out a file
+descriptor. There are no direct GEM handles in the function signature; the
+caller doesn't care which GEM handle we prime to get the file descriptor. In
+principle, both paths produce the same file descriptor for the same BO, since
+both GEM handles represent the same underlying resource (viewed from different
+devices).
+
+On grounds of redundancy alone, it makes sense to remove the rsrc->scanout path.
+Why have a path that only works sometimes, when we have another path that works
+always?
+
+In fact, the issues with the rsrc->scanout path are deeper. rsrc->scanout is
+populated by renderonly_create_gpu_import_for_resource, which does the
+following:
+
+1. Get a file descriptor for the resource by resource_get_handle with
+   WINSYS_HANDLE_TYPE_FD
+2. Prime the file descriptor to a GEM handle via the KMS device.
+
+Here comes strike number 2: in order to get a file descriptor via the KMS
+device, we had to /already/ get a file descriptor via the GPU device. If we go
+down the KMS device path, we effectively round trip:
+
+   GPU handle -> fd -> KMS handle -> fd
+
+There is no good reason to do this; if everything works, the fd is the same in
+each case. If everything works. If.
+
+The lifetimes of the GPU handle and the KMS handle are not necessarily bound. In
+principle, a resource can be created with scanout (constructing a KMS handle).
+Then the KMS view can be destroyed (invalidating the GEM handle for the KMS
+device), even though the underlying resource is still valid. Notice the GPU
+handle is still valid; its lifetime is tied to the resource itself. Then a
+caller can ask for the FD for the resource; as the resource is still valid, this
+is sensible. Under the scanout path, we try to get the FD by priming the GEM
+handle on the KMS device... but that GEM handle is no longer valid, causing the
+PRIME ioctl to fail with ENOENT. On the other hand, if we primed the GPU GEM
+handle, everything works as expected.
+
+These edge cases are not theoretical; recent versions of Xwayland trigger this
+ENOENT, causing issue #5758 on all Panfrost devices. As far as I can tell, no
+other kmsro driver has this 'special' kmsro path; the only part of
+resource_get_handle that needs special handling for kmsro is getting a KMS
+handle.
+
+Let's remove the broken, useless path, fix Xwayland, bring us in line with other
+drivers, and delete some code.
+
+Thank you for coming to my ted talk.
+
+Closes: #5758
+Fixes: 7da251fc721 ("panfrost: Check in sources for command stream")
+Signed-off-by: Alyssa Rosenzweig <alyssa at collabora.com>
+Reported-and-tested-by: Jan Palus <jpalus at fastmail.com>
+Reviewed-by: Simon Ser <contact at emersion.fr>
+Reviewed-by: James Jones <jajones at nvidia.com>
+Acked-by: Daniel Stone <daniels at collabora.com>
+---
+ src/gallium/drivers/panfrost/pan_resource.c | 30 +++++----------------
+ 1 file changed, 7 insertions(+), 23 deletions(-)
+
+diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c
+index f473f71099e..094332862ff 100644
+--- a/src/gallium/drivers/panfrost/pan_resource.c
++++ b/src/gallium/drivers/panfrost/pan_resource.c
+@@ -165,31 +165,15 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen,
+                         return true;
+                 }
+         } else if (handle->type == WINSYS_HANDLE_TYPE_FD) {
+-                if (scanout) {
+-                        struct drm_prime_handle args = {
+-                                .handle = scanout->handle,
+-                                .flags = DRM_CLOEXEC,
+-                        };
++                int fd = panfrost_bo_export(rsrc->image.data.bo);
+ 
+-                        int ret = drmIoctl(dev->ro->kms_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
+-                        if (ret == -1)
+-                                return false;
+-
+-                        handle->stride = scanout->stride;
+-                        handle->handle = args.fd;
+-
+-                        return true;
+-                } else {
+-                        int fd = panfrost_bo_export(rsrc->image.data.bo);
+-
+-                        if (fd < 0)
+-                                return false;
++                if (fd < 0)
++                        return false;
+ 
+-                        handle->handle = fd;
+-                        handle->stride = rsrc->image.layout.slices[0].line_stride;
+-                        handle->offset = rsrc->image.layout.slices[0].offset;
+-                        return true;
+-                }
++                handle->handle = fd;
++                handle->stride = rsrc->image.layout.slices[0].line_stride;
++                handle->offset = rsrc->image.layout.slices[0].offset;
++                return true;
+         }
+ 
+         return false;
+-- 
+GitLab
+
+
+From 43b5b452e23243ee178e6fd3c3f5b02fa1dabd71 Mon Sep 17 00:00:00 2001
+From: Alyssa Rosenzweig <alyssa at collabora.com>
+Date: Tue, 22 Feb 2022 11:30:05 -0500
+Subject: [PATCH 2/2] panfrost: Simplify panfrost_resource_get_handle
+
+Unify the exit paths to clean up the logic. There are logically three modes we
+support (KMS without renderonly, KMS with renderonly, and FD); these each
+correspond to a leg of a small if statement. Outside of the small if's,
+everything else should be identical.
+
+Signed-off-by: Alyssa Rosenzweig <alyssa at collabora.com>
+Reviewed-by: Simon Ser <contact at emersion.fr>
+Reviewed-by: James Jones <jajones at nvidia.com>
+Acked-by: Daniel Stone <daniels at collabora.com>
+---
+ src/gallium/drivers/panfrost/pan_resource.c | 23 ++++++++-------------
+ 1 file changed, 9 insertions(+), 14 deletions(-)
+
+diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c
+index 094332862ff..477bf1d7ce1 100644
+--- a/src/gallium/drivers/panfrost/pan_resource.c
++++ b/src/gallium/drivers/panfrost/pan_resource.c
+@@ -153,17 +153,10 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen,
+         handle->modifier = rsrc->image.layout.modifier;
+         rsrc->modifier_constant = true;
+ 
+-        if (handle->type == WINSYS_HANDLE_TYPE_SHARED) {
+-                return false;
++        if (handle->type == WINSYS_HANDLE_TYPE_KMS && dev->ro) {
++                return renderonly_get_handle(scanout, handle);
+         } else if (handle->type == WINSYS_HANDLE_TYPE_KMS) {
+-                if (dev->ro) {
+-                        return renderonly_get_handle(scanout, handle);
+-                } else {
+-                        handle->handle = rsrc->image.data.bo->gem_handle;
+-                        handle->stride = rsrc->image.layout.slices[0].line_stride;
+-                        handle->offset = rsrc->image.layout.slices[0].offset;
+-                        return true;
+-                }
++                handle->handle = rsrc->image.data.bo->gem_handle;
+         } else if (handle->type == WINSYS_HANDLE_TYPE_FD) {
+                 int fd = panfrost_bo_export(rsrc->image.data.bo);
+ 
+@@ -171,12 +164,14 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen,
+                         return false;
+ 
+                 handle->handle = fd;
+-                handle->stride = rsrc->image.layout.slices[0].line_stride;
+-                handle->offset = rsrc->image.layout.slices[0].offset;
+-                return true;
++        } else {
++                /* Other handle types not supported */
++                return false;
+         }
+ 
+-        return false;
++        handle->stride = rsrc->image.layout.slices[0].line_stride;
++        handle->offset = rsrc->image.layout.slices[0].offset;
++        return true;
+ }
+ 
+ static bool
+-- 
+GitLab
+
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/Mesa.git/commitdiff/d5a5b39e61527a153cbd0b69f3bc0c867caa4168



More information about the pld-cvs-commit mailing list