mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 02:10:11 +01:00
etnaviv: keep references to pending resources
As long as a resource is pending in any context we must not destroy it, otherwise we'll hit a classical use-after-free with fireworks. To avoid this take a reference when the resource is first added to the pending set and put the reference when no longer pending. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Reviewed-by: Jonathan Marek <jonathan@marek.ca>
This commit is contained in:
parent
90e223646b
commit
9e672e4d20
2 changed files with 10 additions and 11 deletions
|
|
@ -425,10 +425,13 @@ etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv)
|
|||
mtx_lock(&screen->lock);
|
||||
set_foreach(ctx->used_resources, entry) {
|
||||
struct etna_resource *rsc = (struct etna_resource *)entry->key;
|
||||
struct pipe_resource *referenced = &rsc->base;
|
||||
|
||||
rsc->status = 0;
|
||||
|
||||
_mesa_set_remove_key(rsc->pending_ctx, ctx);
|
||||
|
||||
pipe_resource_reference(&referenced, NULL);
|
||||
}
|
||||
_mesa_set_clear(ctx->used_resources, NULL);
|
||||
mtx_unlock(&screen->lock);
|
||||
|
|
|
|||
|
|
@ -464,17 +464,9 @@ etna_resource_changed(struct pipe_screen *pscreen, struct pipe_resource *prsc)
|
|||
static void
|
||||
etna_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *prsc)
|
||||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
struct etna_resource *rsc = etna_resource(prsc);
|
||||
|
||||
mtx_lock(&screen->lock);
|
||||
set_foreach(rsc->pending_ctx, entry) {
|
||||
struct etna_context *ctx = (struct etna_context *)entry->key;
|
||||
|
||||
_mesa_set_remove_key(rsc->pending_ctx, ctx);
|
||||
}
|
||||
_mesa_set_destroy(rsc->pending_ctx, NULL);
|
||||
mtx_unlock(&screen->lock);
|
||||
assert(!_mesa_set_next_entry(rsc->pending_ctx, NULL));
|
||||
|
||||
if (rsc->bo)
|
||||
etna_bo_del(rsc->bo);
|
||||
|
|
@ -618,6 +610,7 @@ etna_resource_used(struct etna_context *ctx, struct pipe_resource *prsc,
|
|||
enum etna_resource_status status)
|
||||
{
|
||||
struct etna_screen *screen = ctx->screen;
|
||||
struct pipe_resource *referenced = NULL;
|
||||
struct etna_resource *rsc;
|
||||
|
||||
if (!prsc)
|
||||
|
|
@ -654,8 +647,11 @@ etna_resource_used(struct etna_context *ctx, struct pipe_resource *prsc,
|
|||
|
||||
rsc->status |= status;
|
||||
|
||||
_mesa_set_add(ctx->used_resources, rsc);
|
||||
_mesa_set_add(rsc->pending_ctx, ctx);
|
||||
if (!_mesa_set_search(rsc->pending_ctx, ctx)) {
|
||||
pipe_resource_reference(&referenced, prsc);
|
||||
_mesa_set_add(ctx->used_resources, rsc);
|
||||
_mesa_set_add(rsc->pending_ctx, ctx);
|
||||
}
|
||||
|
||||
mtx_unlock(&screen->lock);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue