radv: Search for guilty contexts at radv_check_status
authorAndré Almeida <andrealmeid@igalia.com>
Sun, 23 Apr 2023 20:43:11 +0000 (17:43 -0300)
committerMarge Bot <emma+marge@anholt.net>
Mon, 24 Apr 2023 16:45:40 +0000 (16:45 +0000)
When a GPU hung happens, all contexts are notified. They will receive
INNOCENT_CONTEXT if they are not the context that triggered the reset,
or GUILTY_CONTEXT otherwise.

At radv_check_status(), we return on the first context that was notified
as [GUILTY, INNOCENT]_CONTEXT, without further checks. This can make an
app think that it's innocent if the guilty context is not the first one
on the list of hw_ctx to be checked.

Check every context for a guilty one before returning CONTEXT_INNOCENT.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Signed-off-by: André Almeida <andrealmeid@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22648>

src/amd/vulkan/radv_device.c

index 9a75b2c..3488155 100644 (file)
@@ -608,18 +608,24 @@ radv_check_status(struct vk_device *vk_device)
 {
    struct radv_device *device = container_of(vk_device, struct radv_device, vk);
    enum radv_reset_status status;
+   bool context_reset = false;
 
+   /* If an INNOCENT_CONTEXT_RESET is found in one of the contexts, we need to
+    * keep querying in case there's a guilty one, so we can correctly log if the
+    * hung happened in this app or not */
    for (int i = 0; i < RADV_NUM_HW_CTX; i++) {
       if (device->hw_ctx[i]) {
          status = device->ws->ctx_query_reset_status(device->hw_ctx[i]);
 
          if (status == RADV_GUILTY_CONTEXT_RESET)
             return vk_device_set_lost(&device->vk, "GPU hung detected in this process");
-        if (status == RADV_INNOCENT_CONTEXT_RESET)
-            return vk_device_set_lost(&device->vk, "GPU hung triggered by other process");
+         else if (status == RADV_INNOCENT_CONTEXT_RESET)
+            context_reset = true;
       }
    }
 
+   if (context_reset)
+      return vk_device_set_lost(&device->vk, "GPU hung triggered by other process");
    return VK_SUCCESS;
 }