mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 13:58:04 +02:00
panfrost: Fix Panfrost BO leak in error handling path
When panfrost_resource_init_afbc_headers() fails, freeing the newly created resource is not enough, because we need to unreference its BOs. This will also take care of freeing its resource label. Also replace instances of FREE() in error-handling paths with panfrost_resource_destroy(), as it is capable of handling partially initialised resources. Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> Fixes:e3f2bc7963("panfrost: handle mmap failures") Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34224> (cherry picked from commit32b128be01)
This commit is contained in:
parent
c76a7410dc
commit
e1f6a0c4df
2 changed files with 32 additions and 32 deletions
|
|
@ -4764,7 +4764,7 @@
|
|||
"description": "panfrost: Fix Panfrost BO leak in error handling path",
|
||||
"nominated": true,
|
||||
"nomination_type": 2,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": "e3f2bc7963748096f7b4018cffe058a73081a760",
|
||||
"notes": null
|
||||
|
|
|
|||
|
|
@ -101,6 +101,31 @@ panfrost_clear_render_target(struct pipe_context *pipe,
|
|||
height);
|
||||
}
|
||||
|
||||
static void
|
||||
panfrost_resource_destroy(struct pipe_screen *screen, struct pipe_resource *pt)
|
||||
{
|
||||
MESA_TRACE_FUNC();
|
||||
|
||||
struct panfrost_device *dev = pan_device(screen);
|
||||
struct panfrost_resource *rsrc = (struct panfrost_resource *)pt;
|
||||
|
||||
if (rsrc->scanout)
|
||||
renderonly_scanout_destroy(rsrc->scanout, dev->ro);
|
||||
|
||||
if (rsrc->shadow_image)
|
||||
pipe_resource_reference(
|
||||
(struct pipe_resource **)&rsrc->shadow_image, NULL);
|
||||
|
||||
if (rsrc->bo)
|
||||
panfrost_bo_unreference(rsrc->bo);
|
||||
|
||||
free(rsrc->index_cache);
|
||||
free(rsrc->damage.tile_map.data);
|
||||
|
||||
util_range_destroy(&rsrc->valid_buffer_range);
|
||||
free(rsrc);
|
||||
}
|
||||
|
||||
static struct pipe_resource *
|
||||
panfrost_resource_from_handle(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *templat,
|
||||
|
|
@ -150,7 +175,7 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen,
|
|||
pan_image_layout_init(dev->arch, &rsc->image.layout, &explicit_layout);
|
||||
|
||||
if (!valid) {
|
||||
FREE(rsc);
|
||||
panfrost_resource_destroy(pscreen, &rsc->base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -159,7 +184,7 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen,
|
|||
* memory space to mmap it etc.
|
||||
*/
|
||||
if (!rsc->bo) {
|
||||
FREE(rsc);
|
||||
panfrost_resource_destroy(pscreen, &rsc->base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -830,7 +855,7 @@ panfrost_resource_create_with_modifier(struct pipe_screen *screen,
|
|||
|
||||
if (!so->scanout) {
|
||||
mesa_loge("Failed to create scanout resource\n");
|
||||
FREE(so);
|
||||
panfrost_resource_destroy(screen, &so->base);
|
||||
return NULL;
|
||||
}
|
||||
assert(handle.type == WINSYS_HANDLE_TYPE_FD);
|
||||
|
|
@ -838,7 +863,7 @@ panfrost_resource_create_with_modifier(struct pipe_screen *screen,
|
|||
close(handle.handle);
|
||||
|
||||
if (!so->bo) {
|
||||
FREE(so);
|
||||
panfrost_resource_destroy(screen, &so->base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -856,7 +881,7 @@ panfrost_resource_create_with_modifier(struct pipe_screen *screen,
|
|||
panfrost_bo_create(dev, so->image.layout.data_size, flags, label);
|
||||
|
||||
if (!so->bo) {
|
||||
FREE(so);
|
||||
panfrost_resource_destroy(screen, &so->base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -867,7 +892,7 @@ panfrost_resource_create_with_modifier(struct pipe_screen *screen,
|
|||
|
||||
if (drm_is_afbc(so->image.layout.modifier)) {
|
||||
if (panfrost_resource_init_afbc_headers(so)) {
|
||||
FREE(so);
|
||||
panfrost_resource_destroy(screen, &so->base);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -910,31 +935,6 @@ panfrost_resource_create_with_modifiers(struct pipe_screen *screen,
|
|||
return panfrost_resource_create(screen, template);
|
||||
}
|
||||
|
||||
static void
|
||||
panfrost_resource_destroy(struct pipe_screen *screen, struct pipe_resource *pt)
|
||||
{
|
||||
MESA_TRACE_FUNC();
|
||||
|
||||
struct panfrost_device *dev = pan_device(screen);
|
||||
struct panfrost_resource *rsrc = (struct panfrost_resource *)pt;
|
||||
|
||||
if (rsrc->scanout)
|
||||
renderonly_scanout_destroy(rsrc->scanout, dev->ro);
|
||||
|
||||
if (rsrc->shadow_image)
|
||||
pipe_resource_reference(
|
||||
(struct pipe_resource **)&rsrc->shadow_image, NULL);
|
||||
|
||||
if (rsrc->bo)
|
||||
panfrost_bo_unreference(rsrc->bo);
|
||||
|
||||
free(rsrc->index_cache);
|
||||
free(rsrc->damage.tile_map.data);
|
||||
|
||||
util_range_destroy(&rsrc->valid_buffer_range);
|
||||
free(rsrc);
|
||||
}
|
||||
|
||||
/* Most of the time we can do CPU-side transfers, but sometimes we need to use
|
||||
* the 3D pipe for this. Let's wrap u_blitter to blit to/from staging textures.
|
||||
* Code adapted from freedreno */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue