Module: Mesa Branch: master Commit: 66125c429fe7ced20e1125b9a439ae98d5fab993 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=66125c429fe7ced20e1125b9a439ae98d5fab993
Author: Boris Brezillon <boris.brezil...@collabora.com> Date: Tue Feb 2 09:32:41 2021 +0100 panfrost: Fix a polygon list corruption in the multi-context case The polygon list is written by tiler jobs and read by fragment ones, and nothing should re-use the heap until the fragment job is done. 4fec6c944817 ("panfrost: Add the tiler heap to fragment jobs") fixed this for the !multi-context case by adding the heap BO to fragment job. But the tiler heap is shared accross contexts, and vertex/tiler+fragment job submission is done through 2 separate ioctls, meaning that vertex/tiler and fragment jobs from 2 different context might be interleaved. Add a lock at the device level to ensure tiler/vertex+fragment jobs are submitted sequentially, with no other jobs using the same tiler heap in-between. Cc: mesa-stable Fixes: d8deb1eb6a22 ("panfrost: Share tiler_heap across batches/contexts") Reported-by: Icecream95 <i...@disroot.org> Signed-off-by: Boris Brezillon <boris.brezil...@collabora.com> Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzw...@collabora.com> Tested-by: Icecream95 <i...@disroot.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8822> --- src/gallium/drivers/panfrost/pan_job.c | 17 ++++++++++++++--- src/panfrost/lib/pan_device.h | 8 ++++++++ src/panfrost/lib/pan_props.c | 3 +++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c index c941ddc8bdb..440ba38bbb5 100644 --- a/src/gallium/drivers/panfrost/pan_job.c +++ b/src/gallium/drivers/panfrost/pan_job.c @@ -1021,10 +1021,19 @@ panfrost_batch_submit_ioctl(struct panfrost_batch *batch, static int panfrost_batch_submit_jobs(struct panfrost_batch *batch, uint32_t in_sync, uint32_t out_sync) { + struct panfrost_device *dev = pan_device(batch->ctx->base.screen); bool has_draws = batch->scoreboard.first_job; - bool has_frag = batch->scoreboard.tiler_dep || batch->clear; + bool has_tiler = batch->scoreboard.first_tiler; + bool has_frag = has_tiler || batch->clear; int ret = 0; + /* Take the submit lock to make sure no tiler jobs from other context + * are inserted between our tiler and fragment jobs, failing to do that + * might result in tiler heap corruption. + */ + if (has_tiler) + pthread_mutex_lock(&dev->submit_lock); + if (has_draws) { ret = panfrost_batch_submit_ioctl(batch, batch->scoreboard.first_job, 0, in_sync, has_frag ? 0 : out_sync); @@ -1039,14 +1048,16 @@ panfrost_batch_submit_jobs(struct panfrost_batch *batch, uint32_t in_sync, uint3 * *only* clears, since otherwise the tiler structures will be * uninitialized leading to faults (or state leaks) */ - mali_ptr fragjob = panfrost_fragment_job(batch, - batch->scoreboard.tiler_dep != 0); + mali_ptr fragjob = panfrost_fragment_job(batch, has_tiler); ret = panfrost_batch_submit_ioctl(batch, fragjob, PANFROST_JD_REQ_FS, 0, out_sync); assert(!ret); } + if (has_tiler) + pthread_mutex_unlock(&dev->submit_lock); + return ret; } diff --git a/src/panfrost/lib/pan_device.h b/src/panfrost/lib/pan_device.h index 3335f3e2db5..e2601d50c89 100644 --- a/src/panfrost/lib/pan_device.h +++ b/src/panfrost/lib/pan_device.h @@ -151,6 +151,14 @@ struct panfrost_device { * costly per-context allocation. */ struct panfrost_bo *tiler_heap; + + /* The tiler heap is shared by all contexts, and is written by tiler + * jobs and read by fragment job. We need to ensure that a + * vertex/tiler job chain from one context is not inserted between + * the vertex/tiler and fragment job of another context, otherwise + * we end up with tiler heap corruption. + */ + pthread_mutex_t submit_lock; }; void diff --git a/src/panfrost/lib/pan_props.c b/src/panfrost/lib/pan_props.c index 38c10183594..bb15c8c5d73 100644 --- a/src/panfrost/lib/pan_props.c +++ b/src/panfrost/lib/pan_props.c @@ -253,11 +253,14 @@ panfrost_open_device(void *memctx, int fd, struct panfrost_device *dev) dev->tiler_heap = panfrost_bo_create(dev, 4096 * 4096, PAN_BO_INVISIBLE | PAN_BO_GROWABLE); + + pthread_mutex_init(&dev->submit_lock, NULL); } void panfrost_close_device(struct panfrost_device *dev) { + pthread_mutex_destroy(&dev->submit_lock); panfrost_bo_unreference(dev->blit_shaders.bo); panfrost_bo_unreference(dev->tiler_heap); panfrost_bo_cache_evict_all(dev); _______________________________________________ mesa-commit mailing list mesa-commit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-commit