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

Author: Dmitry Baryshkov <dmitry.barysh...@linaro.org>
Date:   Sun Nov 19 14:36:28 2023 +0200

freedreno/drm: don't crash in heap allocator when run under valgrind

If Mesa is executed under valgrind, fd_bo_init_common() calls
fd_bo_map() internally. For the heap (sub-block) allocator this causes a
segfault in fd_bo_map(), when this function tries to call the offset()
callback.

To prevent this from happening, preallocate fb->map before calling into
fd_bo_init_common(), stop calling VG_BO_ALLOC() if the memory map is
already initialised and disable the VG_BO_FREE call for the heap
allocator.

Signed-off-by: Dmitry Baryshkov <dmitry.barysh...@linaro.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26277>

---

 src/freedreno/drm/freedreno_bo.c      |  3 ++-
 src/freedreno/drm/freedreno_bo_heap.c | 11 +++++++----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/src/freedreno/drm/freedreno_bo.c b/src/freedreno/drm/freedreno_bo.c
index 33780d824b9..6b90c1e6dfe 100644
--- a/src/freedreno/drm/freedreno_bo.c
+++ b/src/freedreno/drm/freedreno_bo.c
@@ -105,7 +105,8 @@ fd_bo_init_common(struct fd_bo *bo, struct fd_device *dev)
    bo->max_fences = 1;
    bo->fences = &bo->_inline_fence;
 
-   VG_BO_ALLOC(bo);
+   if (!bo->map)
+      VG_BO_ALLOC(bo);
 }
 
 /* allocate a new buffer object, call w/ table_lock held */
diff --git a/src/freedreno/drm/freedreno_bo_heap.c 
b/src/freedreno/drm/freedreno_bo_heap.c
index 64c498255e6..4782218726f 100644
--- a/src/freedreno/drm/freedreno_bo_heap.c
+++ b/src/freedreno/drm/freedreno_bo_heap.c
@@ -123,7 +123,10 @@ sa_release(struct fd_bo *bo)
 
    simple_mtx_assert_locked(&s->heap->lock);
 
-   VG_BO_FREE(bo);
+   /*
+    * We don't track heap allocs in valgrind
+    * VG_BO_FREE(bo);
+    */
 
    fd_bo_fini_fences(bo);
 
@@ -258,12 +261,12 @@ fd_bo_heap_alloc(struct fd_bo_heap *heap, uint32_t size)
    bo->handle = 1; /* dummy handle to make fd_bo_init_common() happy */
    bo->alloc_flags = heap->flags;
 
+   /* Pre-initialize mmap ptr, to avoid trying to os_mmap() */
+   bo->map = ((uint8_t *)fd_bo_map(heap->blocks[idx])) + block_offset(s);
+
    fd_bo_init_common(bo, heap->dev);
 
    bo->handle = FD_BO_SUBALLOC_HANDLE;
 
-   /* Pre-initialize mmap ptr, to avoid trying to os_mmap() */
-   bo->map = ((uint8_t *)fd_bo_map(heap->blocks[idx])) + block_offset(s);
-
    return bo;
 }

Reply via email to