From b5bc8d8233724827a1954fc83fbbff4c19a7c225 Mon Sep 17 00:00:00 2001 From: Robert Beckett Date: Wed, 26 Apr 2023 13:28:40 +0100 Subject: [PATCH] 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 Reviewed-by: Italo Nicola Part-of: (cherry picked from commit 8087f784e4268476411a6c3b944731bee2315d10) --- .pick_status.json | 2 +- .../winsys/panfrost/drm/panfrost_drm_winsys.c | 25 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 160cf0dc3b2..4b1d2248045 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -4027,7 +4027,7 @@ "description": "winsys/panfrost: Fix a scanout resource leak", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "ad4d7ca8332488be8a75aff001f00306a9f6402e" }, 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; }