mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-02 05:48:07 +02:00
panfrost: Jobs must be per context, not per screen
Jobs _must_ only be shared across the same context, having the last_job tracked in a screen causes use-after-free issues and memory corruptions. Signed-off-by: Rohan Garg <rohan.garg@collabora.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
This commit is contained in:
parent
bd98470a46
commit
6b0dc3d530
5 changed files with 14 additions and 17 deletions
|
|
@ -1329,9 +1329,6 @@ panfrost_submit_frame(struct panfrost_context *ctx, bool flush_immediate,
|
|||
struct pipe_fence_handle **fence,
|
||||
struct panfrost_job *job)
|
||||
{
|
||||
struct pipe_context *gallium = (struct pipe_context *) ctx;
|
||||
struct panfrost_screen *screen = pan_screen(gallium->screen);
|
||||
|
||||
panfrost_job_submit(ctx, job);
|
||||
|
||||
/* If visual, we can stall a frame */
|
||||
|
|
@ -1339,8 +1336,8 @@ panfrost_submit_frame(struct panfrost_context *ctx, bool flush_immediate,
|
|||
if (!flush_immediate)
|
||||
panfrost_drm_force_flush_fragment(ctx, fence);
|
||||
|
||||
screen->last_fragment_flushed = false;
|
||||
screen->last_job = job;
|
||||
ctx->last_fragment_flushed = false;
|
||||
ctx->last_job = job;
|
||||
|
||||
/* If readback, flush now (hurts the pipelined performance) */
|
||||
if (flush_immediate)
|
||||
|
|
@ -2856,6 +2853,9 @@ panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
|
|||
assert(ctx->blitter);
|
||||
assert(ctx->blitter_wallpaper);
|
||||
|
||||
ctx->last_fragment_flushed = true;
|
||||
ctx->last_job = NULL;
|
||||
|
||||
/* Prepare for render! */
|
||||
|
||||
panfrost_job_init(ctx);
|
||||
|
|
|
|||
|
|
@ -203,6 +203,12 @@ struct panfrost_context {
|
|||
bool is_t6xx;
|
||||
|
||||
uint32_t out_sync;
|
||||
|
||||
/* While we're busy building up the job for frame N, the GPU is
|
||||
* still busy executing frame N-1. So hold a reference to
|
||||
* yesterjob */
|
||||
int last_fragment_flushed;
|
||||
struct panfrost_job *last_job;
|
||||
};
|
||||
|
||||
/* Corresponds to the CSO */
|
||||
|
|
|
|||
|
|
@ -349,12 +349,12 @@ panfrost_drm_force_flush_fragment(struct panfrost_context *ctx,
|
|||
struct pipe_context *gallium = (struct pipe_context *) ctx;
|
||||
struct panfrost_screen *screen = pan_screen(gallium->screen);
|
||||
|
||||
if (!screen->last_fragment_flushed) {
|
||||
if (!ctx->last_fragment_flushed) {
|
||||
drmSyncobjWait(screen->fd, &ctx->out_sync, 1, INT64_MAX, 0, NULL);
|
||||
screen->last_fragment_flushed = true;
|
||||
ctx->last_fragment_flushed = true;
|
||||
|
||||
/* The job finished up, so we're safe to clean it up now */
|
||||
panfrost_free_job(ctx, screen->last_job);
|
||||
panfrost_free_job(ctx, ctx->last_job);
|
||||
}
|
||||
|
||||
if (fence) {
|
||||
|
|
|
|||
|
|
@ -665,9 +665,6 @@ panfrost_create_screen(int fd, struct renderonly *ro)
|
|||
screen->base.fence_finish = panfrost_fence_finish;
|
||||
screen->base.set_damage_region = panfrost_resource_set_damage_region;
|
||||
|
||||
screen->last_fragment_flushed = true;
|
||||
screen->last_job = NULL;
|
||||
|
||||
panfrost_resource_screen_init(screen);
|
||||
|
||||
return &screen->base;
|
||||
|
|
|
|||
|
|
@ -118,12 +118,6 @@ struct panfrost_screen {
|
|||
* Each bucket is a linked list of free panfrost_bo objects. */
|
||||
|
||||
struct list_head bo_cache[NR_BO_CACHE_BUCKETS];
|
||||
|
||||
/* While we're busy building up the job for frame N, the GPU is
|
||||
* still busy executing frame N-1. So hold a reference to
|
||||
* yesterjob */
|
||||
int last_fragment_flushed;
|
||||
struct panfrost_job *last_job;
|
||||
};
|
||||
|
||||
static inline struct panfrost_screen *
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue