[Mesa-dev] [PATCH] radv: Fix pipeline cache locking issues

Alex Smith asmith at feralinteractive.com
Mon Oct 23 09:25:48 UTC 2017


On 21 October 2017 at 02:54, Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
wrote:

> For radv_create_shader_variants_from_pipeline_cache I'm not really
> sure why this would cause corruption. Yes we might create the variants
> a few times too much, but that should not cause any corruption.
>

Just had another look and figured out what the actual problem is - if
there's a race between multiple threads to create the variants for a single
entry, then they may not update p inside the loop properly (since they only
do so when the variant isn't already created), so can end up using the
wrong code. I'll send a patch - I don't think it's necessary now that we're
locking around there (we'll only create all or none of the variants), but
may as well fix it in case things change later.

Alex


>
> Either way, it is a fix, so
> Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
>
> and pushed. Thanks.
>
> On Thu, Oct 19, 2017 at 12:49 PM, Alex Smith
> <asmith at feralinteractive.com> wrote:
> > Need to lock around the whole process of retrieving cached shaders, and
> > around GetPipelineCacheData.
> >
> > This fixes GPU hangs observed when creating multiple pipelines in
> > parallel, which appeared to be due to invalid shader code being pulled
> > from the cache.
> >
> > Signed-off-by: Alex Smith <asmith at feralinteractive.com>
> > ---
> >  src/amd/vulkan/radv_pipeline_cache.c | 30
> +++++++++++++++++++++++-------
> >  1 file changed, 23 insertions(+), 7 deletions(-)
> >
> > diff --git a/src/amd/vulkan/radv_pipeline_cache.c b/src/amd/vulkan/radv_
> pipeline_cache.c
> > index 034dc35af8..a75356b822 100644
> > --- a/src/amd/vulkan/radv_pipeline_cache.c
> > +++ b/src/amd/vulkan/radv_pipeline_cache.c
> > @@ -177,15 +177,20 @@ radv_create_shader_variants_from_pipeline_cache(struct
> radv_device *device,
> >                                                 struct
> radv_shader_variant **variants)
> >  {
> >         struct cache_entry *entry;
> > -       if (cache)
> > -               entry = radv_pipeline_cache_search(cache, sha1);
> > -       else
> > -               entry = radv_pipeline_cache_search(device->mem_cache,
> sha1);
> > +
> > +       if (!cache)
> > +               cache = device->mem_cache;
> > +
> > +       pthread_mutex_lock(&cache->mutex);
> > +
> > +       entry = radv_pipeline_cache_search_unlocked(cache, sha1);
> >
> >         if (!entry) {
> >                 if (!device->physical_device->disk_cache ||
> > -                   (device->instance->debug_flags &
> RADV_DEBUG_NO_CACHE))
> > +                   (device->instance->debug_flags &
> RADV_DEBUG_NO_CACHE)) {
> > +                       pthread_mutex_unlock(&cache->mutex);
> >                         return false;
> > +               }
> >
> >                 uint8_t disk_sha1[20];
> >                 disk_cache_compute_key(device-
> >physical_device->disk_cache,
> > @@ -193,8 +198,10 @@ radv_create_shader_variants_from_pipeline_cache(struct
> radv_device *device,
> >                 entry = (struct cache_entry *)
> >                         disk_cache_get(device->
> physical_device->disk_cache,
> >                                        disk_sha1, NULL);
> > -               if (!entry)
> > +               if (!entry) {
> > +                       pthread_mutex_unlock(&cache->mutex);
> >                         return false;
> > +               }
> >         }
> >
> >         char *p = entry->code;
> > @@ -204,8 +211,10 @@ radv_create_shader_variants_from_pipeline_cache(struct
> radv_device *device,
> >                         struct cache_entry_variant_info info;
> >
> >                         variant = calloc(1, sizeof(struct
> radv_shader_variant));
> > -                       if (!variant)
> > +                       if (!variant) {
> > +                               pthread_mutex_unlock(&cache->mutex);
> >                                 return false;
> > +                       }
> >
> >                         memcpy(&info, p, sizeof(struct
> cache_entry_variant_info));
> >                         p += sizeof(struct cache_entry_variant_info);
> > @@ -231,6 +240,7 @@ radv_create_shader_variants_from_pipeline_cache(struct
> radv_device *device,
> >                         p_atomic_inc(&entry->variants[i]->ref_count);
> >
> >         memcpy(variants, entry->variants, sizeof(entry->variants));
> > +       pthread_mutex_unlock(&cache->mutex);
> >         return true;
> >  }
> >
> > @@ -509,12 +519,17 @@ VkResult radv_GetPipelineCacheData(
> >         RADV_FROM_HANDLE(radv_pipeline_cache, cache, _cache);
> >         struct cache_header *header;
> >         VkResult result = VK_SUCCESS;
> > +
> > +       pthread_mutex_lock(&cache->mutex);
> > +
> >         const size_t size = sizeof(*header) + cache->total_size;
> >         if (pData == NULL) {
> > +               pthread_mutex_unlock(&cache->mutex);
> >                 *pDataSize = size;
> >                 return VK_SUCCESS;
> >         }
> >         if (*pDataSize < sizeof(*header)) {
> > +               pthread_mutex_unlock(&cache->mutex);
> >                 *pDataSize = 0;
> >                 return VK_INCOMPLETE;
> >         }
> > @@ -545,6 +560,7 @@ VkResult radv_GetPipelineCacheData(
> >         }
> >         *pDataSize = p - pData;
> >
> > +       pthread_mutex_unlock(&cache->mutex);
> >         return result;
> >  }
> >
> > --
> > 2.13.6
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20171023/cba14a8a/attachment-0001.html>


More information about the mesa-dev mailing list