[Mesa-dev] [PATCH] i965: Reuse the same single-page bo for all zero sized allocations

Chris Wilson chris at chris-wilson.co.uk
Tue Aug 14 18:21:40 UTC 2018


Similar in principle to how malloc(0) can return the same constant
address knowing that the client is not allowed to access any of its
bytes (as they do not exist!), we can return the same bo for all zero
sized allocation requests. Having a single identifier should help track
down the redundant allocations, while in the mean time making sure that
we do not waste any extra pages on them.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Sergii Romantsov <sergii.romantsov at globallogic.com>
Cc: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Cc: Kenneth Graunke <kenneth at whitecape.org>
---
 src/mesa/drivers/dri/i965/brw_bufmgr.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.c b/src/mesa/drivers/dri/i965/brw_bufmgr.c
index 09d45e30ecc..12d207b36d2 100644
--- a/src/mesa/drivers/dri/i965/brw_bufmgr.c
+++ b/src/mesa/drivers/dri/i965/brw_bufmgr.c
@@ -148,6 +148,8 @@ struct brw_bufmgr {
    int num_buckets;
    time_t time;
 
+   struct brw_bo *bo_zero;
+
    struct hash_table *name_table;
    struct hash_table *handle_table;
 
@@ -504,6 +506,24 @@ bo_alloc_internal(struct brw_bufmgr *bufmgr,
    bool busy = false;
    bool zeroed = false;
 
+   /* Reuse the same bo for all zero-sized requests */
+   if (size == 0) {
+      if (bufmgr->bo_zero == NULL) {
+         bo = bo_alloc_internal(bufmgr, "zero", 4096,
+                                BRW_MEMZONE_OTHER, BO_ALLOC_BUSY, 0, 0);
+         if (!bo)
+            return NULL;
+
+         bo->size = 0;
+
+         if (p_atomic_cmpxchg(&bufmgr->bo_zero, NULL, bo))
+            brw_bo_unreference(bo);
+      }
+
+      brw_bo_reference(bufmgr->bo_zero);
+      return bufmgr->bo_zero;
+   }
+
    if (flags & BO_ALLOC_BUSY)
       busy = true;
 
@@ -1179,6 +1199,8 @@ can_map_cpu(struct brw_bo *bo, unsigned flags)
 void *
 brw_bo_map(struct brw_context *brw, struct brw_bo *bo, unsigned flags)
 {
+   assert(bo->size);
+
    if (bo->tiling_mode != I915_TILING_NONE && !(flags & MAP_RAW))
       return brw_bo_map_gtt(brw, bo, flags);
 
@@ -1297,6 +1319,8 @@ brw_bo_wait(struct brw_bo *bo, int64_t timeout_ns)
 void
 brw_bufmgr_destroy(struct brw_bufmgr *bufmgr)
 {
+   brw_bo_unreference(bufmgr->bo_zero);
+
    mtx_destroy(&bufmgr->lock);
 
    /* Free any cached buffer objects we were going to reuse */
-- 
2.18.0



More information about the mesa-dev mailing list