From 1c1e09249c4b5850c98cb6adf8c2d128c862920c Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Tue, 8 Aug 2023 09:25:35 -0400 Subject: [PATCH] zink: add more locking for pipeline cache this ensures the size remains constant for entry updates fixes #9494 cc: mesa-stable Part-of: --- src/gallium/drivers/zink/zink_pipeline.c | 12 +++++++++++- src/gallium/drivers/zink/zink_program.c | 2 ++ src/gallium/drivers/zink/zink_screen.c | 11 +++++++++-- src/gallium/drivers/zink/zink_types.h | 2 ++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/zink/zink_pipeline.c b/src/gallium/drivers/zink/zink_pipeline.c index dabeec0..91a3257 100644 --- a/src/gallium/drivers/zink/zink_pipeline.c +++ b/src/gallium/drivers/zink/zink_pipeline.c @@ -428,8 +428,10 @@ zink_create_gfx_pipeline(struct zink_screen *screen, } VkPipeline pipeline; + u_rwlock_wrlock(&prog->base.pipeline_cache_lock); VkResult result = VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache, 1, &pci, NULL, &pipeline); + u_rwlock_wrunlock(&prog->base.pipeline_cache_lock); if (result != VK_SUCCESS) { mesa_loge("ZINK: vkCreateGraphicsPipelines failed (%s)", vk_Result_to_str(result)); return VK_NULL_HANDLE; @@ -472,8 +474,10 @@ zink_create_compute_pipeline(struct zink_screen *screen, struct zink_compute_pro pci.stage = stage; VkPipeline pipeline; + u_rwlock_wrlock(&comp->base.pipeline_cache_lock); VkResult result = VKSCR(CreateComputePipelines)(screen->dev, comp->base.pipeline_cache, 1, &pci, NULL, &pipeline); + u_rwlock_wrunlock(&comp->base.pipeline_cache_lock); if (result != VK_SUCCESS) { mesa_loge("ZINK: vkCreateComputePipelines failed (%s)", vk_Result_to_str(result)); return VK_NULL_HANDLE; @@ -813,7 +817,10 @@ create_gfx_pipeline_library(struct zink_screen *screen, struct zink_shader_objec VkPipeline zink_create_gfx_pipeline_library(struct zink_screen *screen, struct zink_gfx_program *prog) { - return create_gfx_pipeline_library(screen, prog->objs, prog->base.layout, prog->base.pipeline_cache); + u_rwlock_wrlock(&prog->base.pipeline_cache_lock); + VkPipeline pipeline = create_gfx_pipeline_library(screen, prog->objs, prog->base.layout, prog->base.pipeline_cache); + u_rwlock_wrunlock(&prog->base.pipeline_cache_lock); + return pipeline; } VkPipeline @@ -851,11 +858,14 @@ zink_create_gfx_pipeline_combined(struct zink_screen *screen, struct zink_gfx_pr pci.flags |= VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; VkPipeline pipeline; + u_rwlock_wrlock(&prog->base.pipeline_cache_lock); if (VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache, 1, &pci, NULL, &pipeline) != VK_SUCCESS) { mesa_loge("ZINK: vkCreateGraphicsPipelines failed"); + u_rwlock_wrunlock(&prog->base.pipeline_cache_lock); return VK_NULL_HANDLE; } + u_rwlock_wrunlock(&prog->base.pipeline_cache_lock); return pipeline; } diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index b8de224..d9abd1aa 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -961,6 +961,7 @@ create_program(struct zink_context *ctx, bool is_compute) return NULL; pipe_reference_init(&pg->reference, 1); + u_rwlock_init(&pg->pipeline_cache_lock); util_queue_fence_init(&pg->cache_fence); pg->is_compute = is_compute; pg->ctx = ctx; @@ -1494,6 +1495,7 @@ deinit_program(struct zink_screen *screen, struct zink_program *pg) if (pg->pipeline_cache) VKSCR(DestroyPipelineCache)(screen->dev, pg->pipeline_cache, NULL); + u_rwlock_destroy(&pg->pipeline_cache_lock); zink_descriptor_program_deinit(screen, pg); } diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 6b7bea4..e706f6f 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -322,17 +322,24 @@ cache_put_job(void *data, void *gdata, int thread_index) struct zink_program *pg = data; struct zink_screen *screen = gdata; size_t size = 0; + u_rwlock_rdlock(&pg->pipeline_cache_lock); VkResult result = VKSCR(GetPipelineCacheData)(screen->dev, pg->pipeline_cache, &size, NULL); if (result != VK_SUCCESS) { + u_rwlock_rdunlock(&pg->pipeline_cache_lock); mesa_loge("ZINK: vkGetPipelineCacheData failed (%s)", vk_Result_to_str(result)); return; } - if (pg->pipeline_cache_size == size) + if (pg->pipeline_cache_size == size) { + u_rwlock_rdunlock(&pg->pipeline_cache_lock); return; + } void *pipeline_data = malloc(size); - if (!pipeline_data) + if (!pipeline_data) { + u_rwlock_rdunlock(&pg->pipeline_cache_lock); return; + } result = VKSCR(GetPipelineCacheData)(screen->dev, pg->pipeline_cache, &size, pipeline_data); + u_rwlock_rdunlock(&pg->pipeline_cache_lock); if (result == VK_SUCCESS) { pg->pipeline_cache_size = size; diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index b764ffa..534e1a3 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -42,6 +42,7 @@ #include "util/hash_table.h" #include "util/list.h" #include "util/log.h" +#include "util/rwlock.h" #include "util/set.h" #include "util/simple_mtx.h" #include "util/slab.h" @@ -995,6 +996,7 @@ struct zink_program { struct zink_context *ctx; unsigned char sha1[20]; struct util_queue_fence cache_fence; + struct u_rwlock pipeline_cache_lock; VkPipelineCache pipeline_cache; size_t pipeline_cache_size; struct zink_batch_usage *batch_uses; -- 2.7.4