Module: Mesa
Branch: main
Commit: 8087f784e4268476411a6c3b944731bee2315d10
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=8087f784e4268476411a6c3b944731bee2315d10

Author: Robert Beckett <[email protected]>
Date:   Wed Apr 26 13:28:40 2023 +0100

winsys/panfrost: Fix a scanout resource leak

Use ro->bo_map to alloc scanout and make sure we initialize the refcnt
to one.

This fixes leaking the scanout object and the underlying dumb-buffer.

Fixes: ad4d7ca83324 ("kmsro: Fix renderonly_scanout BO aliasing")
Cc: mesa-stable
Signed-off-by: Robert Beckett <[email protected]>
Reviewed-by: Italo Nicola <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23746>

---

 .../winsys/panfrost/drm/panfrost_drm_winsys.c      | 25 ++++++++++++----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/src/gallium/winsys/panfrost/drm/panfrost_drm_winsys.c 
b/src/gallium/winsys/panfrost/drm/panfrost_drm_winsys.c
index b5ec50d49ef..2710217a5b4 100644
--- a/src/gallium/winsys/panfrost/drm/panfrost_drm_winsys.c
+++ b/src/gallium/winsys/panfrost/drm/panfrost_drm_winsys.c
@@ -63,26 +63,32 @@ panfrost_create_kms_dumb_buffer_for_resource(struct 
pipe_resource *rsc,
    };
    struct drm_mode_destroy_dumb destroy_dumb = {0};
 
-   /* Align width to end up with a buffer that's aligned on 64 bytes. */
-
-   struct renderonly_scanout *scanout = CALLOC_STRUCT(renderonly_scanout);
-   if (!scanout)
-      return NULL;
-
    /* create dumb buffer at scanout GPU */
    int err = drmIoctl(ro->kms_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
    if (err < 0) {
       fprintf(stderr, "DRM_IOCTL_MODE_CREATE_DUMB failed: %s\n",
               strerror(errno));
-      goto free_scanout;
+      return NULL;
    }
 
    if (create_dumb.pitch % 64)
       goto free_dumb;
 
+   struct renderonly_scanout *scanout;
+
+   simple_mtx_lock(&ro->bo_map_lock);
+   scanout = util_sparse_array_get(&ro->bo_map, create_dumb.handle);
+   simple_mtx_unlock(&ro->bo_map_lock);
+
+   if (!scanout)
+      goto free_dumb;
+
    scanout->handle = create_dumb.handle;
    scanout->stride = create_dumb.pitch;
 
+   assert(p_atomic_read(&scanout->refcnt) == 0);
+   p_atomic_set(&scanout->refcnt, 1);
+
    if (!out_handle)
       return scanout;
 
@@ -101,12 +107,9 @@ panfrost_create_kms_dumb_buffer_for_resource(struct 
pipe_resource *rsc,
    return scanout;
 
 free_dumb:
-   destroy_dumb.handle = scanout->handle;
+   destroy_dumb.handle = create_dumb.handle;
    drmIoctl(ro->kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb);
 
-free_scanout:
-   FREE(scanout);
-
    return NULL;
 }
 

Reply via email to