Reviewed-by: Juan A. Suarez Romero <jasua...@igalia.com>
On Wed, 2017-04-26 at 10:01 -0700, Jason Ekstrand wrote: > 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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev