<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 21 October 2017 at 02:54, Bas Nieuwenhuizen <span dir="ltr"><<a href="mailto:bas@basnieuwenhuizen.nl" target="_blank">bas@basnieuwenhuizen.nl</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">For radv_create_shader_variants_<wbr>from_pipeline_cache I'm not really<br>
sure why this would cause corruption. Yes we might create the variants<br>
a few times too much, but that should not cause any corruption.<br></blockquote><div><br></div><div>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.</div><div><br></div><div>Alex</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Either way, it is a fix, so<br>
Reviewed-by: Bas Nieuwenhuizen <<a href="mailto:bas@basnieuwenhuizen.nl">bas@basnieuwenhuizen.nl</a>><br>
<br>
and pushed. Thanks.<br>
<div class="HOEnZb"><div class="h5"><br>
On Thu, Oct 19, 2017 at 12:49 PM, Alex Smith<br>
<<a href="mailto:asmith@feralinteractive.com">asmith@feralinteractive.com</a>> wrote:<br>
> Need to lock around the whole process of retrieving cached shaders, and<br>
> around GetPipelineCacheData.<br>
><br>
> This fixes GPU hangs observed when creating multiple pipelines in<br>
> parallel, which appeared to be due to invalid shader code being pulled<br>
> from the cache.<br>
><br>
> Signed-off-by: Alex Smith <<a href="mailto:asmith@feralinteractive.com">asmith@feralinteractive.com</a>><br>
> ---<br>
>  src/amd/vulkan/radv_pipeline_<wbr>cache.c | 30 +++++++++++++++++++++++-------<br>
>  1 file changed, 23 insertions(+), 7 deletions(-)<br>
><br>
> diff --git a/src/amd/vulkan/radv_<wbr>pipeline_cache.c b/src/amd/vulkan/radv_<wbr>pipeline_cache.c<br>
> index 034dc35af8..a75356b822 100644<br>
> --- a/src/amd/vulkan/radv_<wbr>pipeline_cache.c<br>
> +++ b/src/amd/vulkan/radv_<wbr>pipeline_cache.c<br>
> @@ -177,15 +177,20 @@ radv_create_shader_variants_<wbr>from_pipeline_cache(struct radv_device *device,<br>
>                                                 struct radv_shader_variant **variants)<br>
>  {<br>
>         struct cache_entry *entry;<br>
> -       if (cache)<br>
> -               entry = radv_pipeline_cache_search(<wbr>cache, sha1);<br>
> -       else<br>
> -               entry = radv_pipeline_cache_search(<wbr>device->mem_cache, sha1);<br>
> +<br>
> +       if (!cache)<br>
> +               cache = device->mem_cache;<br>
> +<br>
> +       pthread_mutex_lock(&cache-><wbr>mutex);<br>
> +<br>
> +       entry = radv_pipeline_cache_search_<wbr>unlocked(cache, sha1);<br>
><br>
>         if (!entry) {<br>
>                 if (!device->physical_device-><wbr>disk_cache ||<br>
> -                   (device->instance->debug_flags & RADV_DEBUG_NO_CACHE))<br>
> +                   (device->instance->debug_flags & RADV_DEBUG_NO_CACHE)) {<br>
> +                       pthread_mutex_unlock(&cache-><wbr>mutex);<br>
>                         return false;<br>
> +               }<br>
><br>
>                 uint8_t disk_sha1[20];<br>
>                 disk_cache_compute_key(device-<wbr>>physical_device->disk_cache,<br>
> @@ -193,8 +198,10 @@ radv_create_shader_variants_<wbr>from_pipeline_cache(struct radv_device *device,<br>
>                 entry = (struct cache_entry *)<br>
>                         disk_cache_get(device-><wbr>physical_device->disk_cache,<br>
>                                        disk_sha1, NULL);<br>
> -               if (!entry)<br>
> +               if (!entry) {<br>
> +                       pthread_mutex_unlock(&cache-><wbr>mutex);<br>
>                         return false;<br>
> +               }<br>
>         }<br>
><br>
>         char *p = entry->code;<br>
> @@ -204,8 +211,10 @@ radv_create_shader_variants_<wbr>from_pipeline_cache(struct radv_device *device,<br>
>                         struct cache_entry_variant_info info;<br>
><br>
>                         variant = calloc(1, sizeof(struct radv_shader_variant));<br>
> -                       if (!variant)<br>
> +                       if (!variant) {<br>
> +                               pthread_mutex_unlock(&cache-><wbr>mutex);<br>
>                                 return false;<br>
> +                       }<br>
><br>
>                         memcpy(&info, p, sizeof(struct cache_entry_variant_info));<br>
>                         p += sizeof(struct cache_entry_variant_info);<br>
> @@ -231,6 +240,7 @@ radv_create_shader_variants_<wbr>from_pipeline_cache(struct radv_device *device,<br>
>                         p_atomic_inc(&entry->variants[<wbr>i]->ref_count);<br>
><br>
>         memcpy(variants, entry->variants, sizeof(entry->variants));<br>
> +       pthread_mutex_unlock(&cache-><wbr>mutex);<br>
>         return true;<br>
>  }<br>
><br>
> @@ -509,12 +519,17 @@ VkResult radv_GetPipelineCacheData(<br>
>         RADV_FROM_HANDLE(radv_<wbr>pipeline_cache, cache, _cache);<br>
>         struct cache_header *header;<br>
>         VkResult result = VK_SUCCESS;<br>
> +<br>
> +       pthread_mutex_lock(&cache-><wbr>mutex);<br>
> +<br>
>         const size_t size = sizeof(*header) + cache->total_size;<br>
>         if (pData == NULL) {<br>
> +               pthread_mutex_unlock(&cache-><wbr>mutex);<br>
>                 *pDataSize = size;<br>
>                 return VK_SUCCESS;<br>
>         }<br>
>         if (*pDataSize < sizeof(*header)) {<br>
> +               pthread_mutex_unlock(&cache-><wbr>mutex);<br>
>                 *pDataSize = 0;<br>
>                 return VK_INCOMPLETE;<br>
>         }<br>
> @@ -545,6 +560,7 @@ VkResult radv_GetPipelineCacheData(<br>
>         }<br>
>         *pDataSize = p - pData;<br>
><br>
> +       pthread_mutex_unlock(&cache-><wbr>mutex);<br>
>         return result;<br>
>  }<br>
><br>
> --<br>
> 2.13.6<br>
><br>
</div></div></blockquote></div><br></div></div>