freedreno/drm: Inline the fence-table
authorRob Clark <robdclark@chromium.org>
Mon, 26 Apr 2021 20:39:04 +0000 (13:39 -0700)
committerMarge Bot <eric+marge@anholt.net>
Wed, 28 Apr 2021 15:36:42 +0000 (15:36 +0000)
In the common case, a bo will have no more than a single fence attached.
We can inline the storage to avoid a separate allocation in this case.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10444>

src/freedreno/drm/freedreno_bo.c
src/freedreno/drm/freedreno_priv.h

index 84ede2e..41203f1 100644 (file)
@@ -106,6 +106,9 @@ bo_new(struct fd_device *dev, uint32_t size, uint32_t flags,
    bo = bo_from_handle(dev, size, handle);
    simple_mtx_unlock(&table_lock);
 
+   bo->max_fences = 1;
+   bo->fences = &bo->_inline_fence;
+
    VG_BO_ALLOC(bo);
 
    return bo;
@@ -332,7 +335,8 @@ bo_del(struct fd_bo *bo)
    simple_mtx_assert_locked(&table_lock);
 
    cleanup_fences(bo, false);
-   free(bo->fences);
+   if (bo->fences != &bo->_inline_fence)
+      free(bo->fences);
 
    if (bo->map)
       os_munmap(bo->map, bo->size);
@@ -485,6 +489,17 @@ fd_bo_add_fence(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t fence)
 
    cleanup_fences(bo, true);
 
+   /* The first time we grow past a single fence, we need some special
+    * handling, as we've been using the embedded _inline_fence to avoid
+    * a separate allocation:
+    */
+   if (unlikely((bo->nr_fences == 1) &&
+                (bo->fences == &bo->_inline_fence))) {
+      bo->nr_fences = bo->max_fences = 0;
+      bo->fences = NULL;
+      APPEND(bo, fences, bo->_inline_fence);
+   }
+
    APPEND(bo, fences, (struct fd_bo_fence){
       .pipe = fd_pipe_ref_locked(pipe),
       .fence = fence,
index 21dcb7d..19abcc1 100644 (file)
@@ -253,6 +253,12 @@ struct fd_bo {
    time_t free_time;      /* time when added to bucket-list */
 
    DECLARE_ARRAY(struct fd_bo_fence, fences);
+
+   /* In the common case, there is no more than one fence attached.
+    * This provides storage for the fences table until it grows to
+    * be larger than a single element.
+    */
+   struct fd_bo_fence _inline_fence;
 };
 
 void fd_bo_add_fence(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t fence);