[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