[Mesa-dev] [PATCH 12.5/18] anv/allocator: Tweak the block pool growing algorithm
Juan A. Suarez Romero
jasuarez at igalia.com
Wed May 3 16:33:22 UTC 2017
Reviewed-by: Juan A. Suarez Romero <jasuarez at 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
More information about the mesa-dev
mailing list