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: ad4d7ca833 ("kmsro: Fix renderonly_scanout BO aliasing")
Cc: mesa-stable
Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
Reviewed-by: Italo Nicola <italonicola@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23746>
(cherry picked from commit 8087f784e4)
This commit is contained in:
Robert Beckett 2023-04-26 13:28:40 +01:00 committed by Eric Engestrom
parent d766ffcc24
commit b5bc8d8233
2 changed files with 15 additions and 12 deletions

View file

@ -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"
},

View file

@ -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;
}