[Mesa-dev] [PATCH 12.5/18] anv/allocator: Tweak the block pool growing algorithm

Jason Ekstrand jason at jlekstrand.net
Wed Apr 26 17:01:00 UTC 2017


The old algorithm worked fine assuming a constant block size.  We're
about to break that assumption so we need an algorithm that's a bit more
robust against suddenly growing by a huge amount compared to the
currently allocated quantity of memory.
---
 src/intel/vulkan/anv_allocator.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/src/intel/vulkan/anv_allocator.c b/src/intel/vulkan/anv_allocator.c
index 05666ec..8728d42 100644
--- a/src/intel/vulkan/anv_allocator.c
+++ b/src/intel/vulkan/anv_allocator.c
@@ -433,7 +433,6 @@ static uint32_t
 anv_block_pool_grow(struct anv_block_pool *pool, struct anv_block_state *state,
                     uint32_t block_size)
 {
-   uint32_t size;
    VkResult result = VK_SUCCESS;
 
    pthread_mutex_lock(&pool->device->mutex);
@@ -458,9 +457,19 @@ anv_block_pool_grow(struct anv_block_pool *pool, struct anv_block_state *state,
 
    uint32_t old_size = pool->bo.size;
 
-   if (old_size != 0 &&
-       back_used * 2 <= pool->center_bo_offset &&
-       front_used * 2 <= (old_size - pool->center_bo_offset)) {
+   /* The block pool is always initialized to a nonzero size and this function
+    * is always called after initialization.
+    */
+   assert(old_size > 0);
+
+   /* The back_used and front_used may actually be smaller than the actual
+    * requirement because they are based on the next pointers which are
+    * updated prior to calling this function.
+    */
+   uint32_t back_required = MAX2(back_used, pool->center_bo_offset);
+   uint32_t front_required = MAX2(front_used, old_size - pool->center_bo_offset);
+
+   if (back_used * 2 <= back_required && front_used * 2 <= front_required) {
       /* If we're in this case then this isn't the firsta allocation and we
        * already have enough space on both sides to hold double what we
        * have allocated.  There's nothing for us to do.
@@ -468,12 +477,11 @@ anv_block_pool_grow(struct anv_block_pool *pool, struct anv_block_state *state,
       goto done;
    }
 
-   if (old_size == 0) {
-      /* This is the first allocation */
-      size = MAX2(32 * block_size, PAGE_SIZE);
-   } else {
-      size = old_size * 2;
-   }
+   uint32_t size = old_size * 2;
+   while (size < back_required + front_required)
+      size *= 2;
+
+   assert(size > pool->bo.size);
 
    /* We can't have a block pool bigger than 1GB because we use signed
     * 32-bit offsets in the free list and we don't want overflow.  We
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list