Module: Mesa
Branch: main
Commit: 798fc2730b4c4928ef70f5a8bac9171f36d308e4
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=798fc2730b4c4928ef70f5a8bac9171f36d308e4

Author: Asahi Lina <[email protected]>
Date:   Wed Mar  1 18:05:00 2023 +0900

asahi: Add agx_debug_fault() helper

We expect to forward GPU fault information to userspace. Since Mesa can
get that information, we can look up the fault address to log what was
the containing or nearest BO. Add a helper for that, so it can be called
from the driver.

Signed-off-by: Asahi Lina <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21662>

---

 src/asahi/lib/agx_device.c | 40 ++++++++++++++++++++++++++++++++++++++++
 src/asahi/lib/agx_device.h |  2 ++
 2 files changed, 42 insertions(+)

diff --git a/src/asahi/lib/agx_device.c b/src/asahi/lib/agx_device.c
index 13cec9bef74..32326912aac 100644
--- a/src/asahi/lib/agx_device.c
+++ b/src/asahi/lib/agx_device.c
@@ -374,3 +374,43 @@ agx_export_sync_file(struct agx_device *dev, struct agx_bo 
*bo)
 
    return ret >= 0 ? export_sync_file_ioctl.fd : ret;
 }
+
+void
+agx_debug_fault(struct agx_device *dev, uint64_t addr)
+{
+   pthread_mutex_lock(&dev->bo_map_lock);
+
+   struct agx_bo *best = NULL;
+
+   for (uint32_t handle = 0; handle < dev->max_handle; handle++) {
+      struct agx_bo *bo = agx_lookup_bo(dev, handle);
+      if (!bo->dev || bo->ptr.gpu > addr)
+         continue;
+
+      if (!best || bo->ptr.gpu > best->ptr.gpu)
+         best = bo;
+   }
+
+   if (!best) {
+      mesa_logw("Address 0x%" PRIx64 " is unknown\n", addr);
+   } else {
+      uint64_t start = best->ptr.gpu;
+      uint64_t end = best->ptr.gpu + best->size;
+      if (addr > (end + 1024 * 1024 * 1024)) {
+         /* 1GiB max as a sanity check */
+         mesa_logw("Address 0x%" PRIx64 " is unknown\n", addr);
+      } else if (addr > end) {
+         mesa_logw("Address 0x%" PRIx64 " is 0x%" PRIx64
+                   " bytes beyond an object at 0x%" PRIx64 "..0x%" PRIx64
+                   " (%s)\n",
+                   addr, addr - end, start, end - 1, best->label);
+      } else {
+         mesa_logw("Address 0x%" PRIx64 " is 0x%" PRIx64
+                   " bytes into an object at 0x%" PRIx64 "..0x%" PRIx64
+                   " (%s)\n",
+                   addr, addr - start, start, end - 1, best->label);
+      }
+   }
+
+   pthread_mutex_unlock(&dev->bo_map_lock);
+}
diff --git a/src/asahi/lib/agx_device.h b/src/asahi/lib/agx_device.h
index 0ed041f1bd7..debf4fb561c 100644
--- a/src/asahi/lib/agx_device.h
+++ b/src/asahi/lib/agx_device.h
@@ -143,4 +143,6 @@ int agx_submit_single(struct agx_device *dev, enum 
drm_asahi_cmd_type cmd_type,
 int agx_import_sync_file(struct agx_device *dev, struct agx_bo *bo, int fd);
 int agx_export_sync_file(struct agx_device *dev, struct agx_bo *bo);
 
+void agx_debug_fault(struct agx_device *dev, uint64_t addr);
+
 #endif

Reply via email to