[igt-dev] [PATCH i-g-t 3/3] lib/intel_allocator: Add support for regions of allocation

Andrzej Turko andrzej.turko at linux.intel.com
Thu May 27 19:27:50 UTC 2021


Enable creating allocators managing only a given interval
of available gtt for all implementations, not just the
simple allocator. Additinally, set a universal lower
bound on alignment to 4096.

Signed-off-by: Andrzej Turko <andrzej.turko at linux.intel.com>
Cc: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
---
 lib/intel_allocator.c        | 14 +++++++++-----
 lib/intel_allocator_random.c | 30 +++++++++++++++++++-----------
 lib/intel_allocator_reloc.c  | 18 ++++++++++++------
 lib/intel_allocator_simple.c |  1 -
 4 files changed, 40 insertions(+), 23 deletions(-)

diff --git a/lib/intel_allocator.c b/lib/intel_allocator.c
index a78a661b1..82875224d 100644
--- a/lib/intel_allocator.c
+++ b/lib/intel_allocator.c
@@ -64,8 +64,10 @@ struct handle_entry {
 	struct allocator *al;
 };
 
-struct intel_allocator *intel_allocator_reloc_create(int fd, uint64_t end);
-struct intel_allocator *intel_allocator_random_create(int fd, uint64_t end);
+struct intel_allocator *
+intel_allocator_reloc_create(int fd, uint64_t start, uint64_t end);
+struct intel_allocator *
+intel_allocator_random_create(int fd, uint64_t start, uint64_t end);
 struct intel_allocator *
 intel_allocator_simple_create(int fd, uint64_t start, uint64_t end,
 			      enum allocator_strategy strategy);
@@ -291,10 +293,10 @@ static struct intel_allocator *intel_allocator_create(int fd,
 			     "We cannot use NONE allocator\n");
 		break;
 	case INTEL_ALLOCATOR_RELOC:
-		ial = intel_allocator_reloc_create(fd, end);
+		ial = intel_allocator_reloc_create(fd, start, end);
 		break;
 	case INTEL_ALLOCATOR_RANDOM:
-		ial = intel_allocator_random_create(fd, end);
+		ial = intel_allocator_random_create(fd, start, end);
 		break;
 	case INTEL_ALLOCATOR_SIMPLE:
 		ial = intel_allocator_simple_create(fd, start, end,
@@ -1078,10 +1080,12 @@ uint64_t __intel_allocator_alloc(uint64_t allocator_handle, uint32_t handle,
 				 .allocator_handle = allocator_handle,
 				 .alloc.handle = handle,
 				 .alloc.size = size,
-				 .alloc.alignment = alignment,
 				 .alloc.strategy = strategy };
 	struct alloc_resp resp;
 
+	igt_assert((alignment & (alignment-1)) == 0);
+	req.alloc.alignment = max(alignment, 1 << 12);
+
 	igt_assert(handle_request(&req, &resp) == 0);
 	igt_assert(resp.response_type == RESP_ALLOC);
 
diff --git a/lib/intel_allocator_random.c b/lib/intel_allocator_random.c
index 85ac2cf4e..e2b2b9474 100644
--- a/lib/intel_allocator_random.c
+++ b/lib/intel_allocator_random.c
@@ -10,12 +10,12 @@
 #include "igt_rand.h"
 #include "intel_allocator.h"
 
-struct intel_allocator *intel_allocator_random_create(int fd, uint64_t end);
+struct intel_allocator *
+intel_allocator_random_create(int fd, uint64_t start, uint64_t end);
 
 struct intel_allocator_random {
-	uint64_t bias;
 	uint32_t prng;
-	uint64_t address_mask;
+	uint64_t size_mask;
 	uint64_t start;
 	uint64_t end;
 
@@ -23,6 +23,7 @@ struct intel_allocator_random {
 	uint64_t allocated_objects;
 };
 
+/* Keep the low 256k clear, for negative deltas */
 #define BIAS 256 << 10
 
 static void intel_allocator_random_get_address_range(struct intel_allocator *ial,
@@ -45,16 +46,22 @@ static uint64_t intel_allocator_random_alloc(struct intel_allocator *ial,
 {
 	struct intel_allocator_random *ialr = ial->priv;
 	uint64_t offset;
+	int cnt = 0;
 
 	(void) handle;
 	(void) strategy;
 
 	/* randomize the address, we try to avoid relocations */
 	do {
+		/* the object won't fit in the managed address range */
+		if (cnt > 5) return ALLOC_INVALID_ADDRESS;
+
 		offset = hars_petruska_f54_1_random64(&ialr->prng);
-		offset += ialr->bias; /* Keep the low 256k clear, for negative deltas */
-		offset &= ialr->address_mask;
-		offset &= ~(alignment - 1);
+		if (++cnt == 5) offset = 0;
+
+		offset &= ialr->size_mask;
+		offset += ialr->start;
+		offset = ALIGN(offset, alignment);
 	} while (offset + size > ialr->end);
 
 	ialr->allocated_objects++;
@@ -145,7 +152,8 @@ static bool intel_allocator_random_is_empty(struct intel_allocator *ial)
 	return !ialr->allocated_objects;
 }
 
-struct intel_allocator *intel_allocator_random_create(int fd, uint64_t end)
+struct intel_allocator *
+intel_allocator_random_create(int fd, uint64_t start, uint64_t end)
 {
 	struct intel_allocator *ial;
 	struct intel_allocator_random *ialr;
@@ -170,10 +178,10 @@ struct intel_allocator *intel_allocator_random_create(int fd, uint64_t end)
 	igt_assert(ial->priv);
 	ialr->prng = (uint32_t) to_user_pointer(ial);
 
-	igt_assert(BIAS < end);
-	ialr->address_mask = (1ULL << (igt_fls(end) - 1)) - 1;
-	ialr->bias = BIAS;
-	ialr->start = ialr->bias;
+	start = max(start, BIAS);
+	igt_assert(start < end);
+	ialr->size_mask = (1ULL << (igt_fls(start - end) - 1)) - 1;
+	ialr->start = start;
 	ialr->end = end;
 
 	ialr->allocated_objects = 0;
diff --git a/lib/intel_allocator_reloc.c b/lib/intel_allocator_reloc.c
index 703d054c6..24b2aeebc 100644
--- a/lib/intel_allocator_reloc.c
+++ b/lib/intel_allocator_reloc.c
@@ -10,10 +10,10 @@
 #include "igt_rand.h"
 #include "intel_allocator.h"
 
-struct intel_allocator *intel_allocator_reloc_create(int fd, uint64_t end);
+struct intel_allocator *
+intel_allocator_reloc_create(int fd, uint64_t start, uint64_t end);
 
 struct intel_allocator_reloc {
-	uint64_t bias;
 	uint32_t prng;
 	uint64_t start;
 	uint64_t end;
@@ -23,6 +23,7 @@ struct intel_allocator_reloc {
 	uint64_t allocated_objects;
 };
 
+/* Keep the low 256k clear, for negative deltas */
 #define BIAS 256 << 10
 
 static void intel_allocator_reloc_get_address_range(struct intel_allocator *ial,
@@ -49,13 +50,16 @@ static uint64_t intel_allocator_reloc_alloc(struct intel_allocator *ial,
 	(void) handle;
 	(void) strategy;
 
-	alignment = max(alignment, 4096);
 	aligned_offset = ALIGN(ialr->offset, alignment);
 
 	/* Check we won't exceed end */
 	if (aligned_offset + size > ialr->end)
 		aligned_offset = ALIGN(ialr->start, alignment);
 
+	/* Check that the object fits in the address range */
+	if (aligned_offset + size > ialr->end)
+		return ALLOC_INVALID_ADDRESS;
+
 	offset = aligned_offset;
 	ialr->offset = offset + size;
 	ialr->allocated_objects++;
@@ -146,7 +150,8 @@ static bool intel_allocator_reloc_is_empty(struct intel_allocator *ial)
 	return !ialr->allocated_objects;
 }
 
-struct intel_allocator *intel_allocator_reloc_create(int fd, uint64_t end)
+struct intel_allocator *
+intel_allocator_reloc_create(int fd, uint64_t start, uint64_t end)
 {
 	struct intel_allocator *ial;
 	struct intel_allocator_reloc *ialr;
@@ -171,8 +176,9 @@ struct intel_allocator *intel_allocator_reloc_create(int fd, uint64_t end)
 	igt_assert(ial->priv);
 	ialr->prng = (uint32_t) to_user_pointer(ial);
 
-	ialr->bias = ialr->offset = BIAS;
-	ialr->start = ialr->bias;
+	start = max(start, BIAS);
+	igt_assert(start < end);
+	ialr->offset = ialr->start = start;
 	ialr->end = end;
 
 	ialr->allocated_objects = 0;
diff --git a/lib/intel_allocator_simple.c b/lib/intel_allocator_simple.c
index 6022e832b..0e6763964 100644
--- a/lib/intel_allocator_simple.c
+++ b/lib/intel_allocator_simple.c
@@ -419,7 +419,6 @@ static uint64_t intel_allocator_simple_alloc(struct intel_allocator *ial,
 	ials = (struct intel_allocator_simple *) ial->priv;
 	igt_assert(ials);
 	igt_assert(handle);
-	alignment = alignment > 0 ? alignment : 1;
 
 	rec = igt_map_search(ials->objects, &handle);
 	if (rec) {
-- 
2.25.1



More information about the igt-dev mailing list