diff options
author | Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> | 2021-04-02 11:15:39 +0200 |
---|---|---|
committer | Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> | 2021-04-13 15:44:38 +0200 |
commit | 35b7416e7f458ad7aa61af2a840982db1d2dd451 (patch) | |
tree | ea2ee1fc13067340cd7a25104796a4636f8ed0e0 | |
parent | 572dfb13332ac607b8cd8eba73a3a58db3fe948b (diff) |
lib/intel_allocator: Add alloc function which allows passing strategy argument
To use spinners with no-reloc we need to alloc offsets for them
from already opened allocator. As we don't know what strategy
is chosen for open (likely HIGH_TO_LOW for SIMPLE allocator) we
want to overwrite it for spinners (there's expectation they
will reside on low addresses).
Extend allocator API adding intel_allocator_alloc_with_strategy()
to support spinners rewriting.
v2: add change in api_intel_allocator test to compile properly
whole series.
Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: Petri Latvala <petri.latvala@intel.com>
-rw-r--r-- | lib/intel_allocator.c | 47 | ||||
-rw-r--r-- | lib/intel_allocator.h | 10 | ||||
-rw-r--r-- | lib/intel_allocator_msgchannel.h | 1 | ||||
-rw-r--r-- | lib/intel_allocator_random.c | 4 | ||||
-rw-r--r-- | lib/intel_allocator_reloc.c | 4 | ||||
-rw-r--r-- | lib/intel_allocator_simple.c | 39 | ||||
-rw-r--r-- | tests/i915/api_intel_allocator.c | 11 |
7 files changed, 86 insertions, 30 deletions
diff --git a/lib/intel_allocator.c b/lib/intel_allocator.c index 0b33b8b24..8a2e607c3 100644 --- a/lib/intel_allocator.c +++ b/lib/intel_allocator.c @@ -579,15 +579,17 @@ static int handle_request(struct alloc_req *req, struct alloc_resp *resp) resp->alloc.offset = ial->alloc(ial, req->alloc.handle, req->alloc.size, - req->alloc.alignment); + req->alloc.alignment, + req->alloc.strategy); alloc_info("<alloc> [tid: %ld] ahnd: %" PRIx64 ", ctx: %u, vm: %u, handle: %u" ", size: 0x%" PRIx64 ", offset: 0x%" PRIx64 - ", alignment: 0x%" PRIx64 "\n", + ", alignment: 0x%" PRIx64 ", strategy: %u\n", (long) req->tid, req->allocator_handle, al->ctx, al->vm, req->alloc.handle, req->alloc.size, - resp->alloc.offset, req->alloc.alignment); + resp->alloc.offset, req->alloc.alignment, + req->alloc.strategy); break; case REQ_FREE: @@ -1040,13 +1042,15 @@ void intel_allocator_get_address_range(uint64_t allocator_handle, * range returns ALLOC_INVALID_ADDRESS. */ uint64_t __intel_allocator_alloc(uint64_t allocator_handle, uint32_t handle, - uint64_t size, uint64_t alignment) + uint64_t size, uint64_t alignment, + enum allocator_strategy strategy) { struct alloc_req req = { .request_type = REQ_ALLOC, .allocator_handle = allocator_handle, .alloc.handle = handle, .alloc.size = size, - .alloc.alignment = alignment }; + .alloc.alignment = alignment, + .alloc.strategy = strategy }; struct alloc_resp resp; igt_assert(handle_request(&req, &resp) == 0); @@ -1063,7 +1067,8 @@ uint64_t __intel_allocator_alloc(uint64_t allocator_handle, uint32_t handle, * @alignment: determines object alignment * * Same as __intel_allocator_alloc() but asserts if allocator can't return - * valid address. + * valid address. Uses default allocation strategy chosen during opening + * the allocator. */ uint64_t intel_allocator_alloc(uint64_t allocator_handle, uint32_t handle, uint64_t size, uint64_t alignment) @@ -1071,13 +1076,41 @@ uint64_t intel_allocator_alloc(uint64_t allocator_handle, uint32_t handle, uint64_t offset; offset = __intel_allocator_alloc(allocator_handle, handle, - size, alignment); + size, alignment, + ALLOC_STRATEGY_NONE); igt_assert(offset != ALLOC_INVALID_ADDRESS); return offset; } /** + * intel_allocator_alloc_with_strategy: + * @allocator_handle: handle to an allocator + * @handle: handle to an object + * @size: size of an object + * @alignment: determines object alignment + * @strategy: strategy of allocation + * + * Same as __intel_allocator_alloc() but asserts if allocator can't return + * valid address. Use @strategy instead of default chosen during opening + * the allocator. + */ +uint64_t intel_allocator_alloc_with_strategy(uint64_t allocator_handle, + uint32_t handle, + uint64_t size, uint64_t alignment, + enum allocator_strategy strategy) +{ + uint64_t offset; + + offset = __intel_allocator_alloc(allocator_handle, handle, + size, alignment, strategy); + igt_assert(offset != ALLOC_INVALID_ADDRESS); + + return offset; +} + + +/** * intel_allocator_free: * @allocator_handle: handle to an allocator * @handle: handle to an object to be freed diff --git a/lib/intel_allocator.h b/lib/intel_allocator.h index 9b7bd0908..c14f57b4d 100644 --- a/lib/intel_allocator.h +++ b/lib/intel_allocator.h @@ -141,7 +141,8 @@ struct intel_allocator { void (*get_address_range)(struct intel_allocator *ial, uint64_t *startp, uint64_t *endp); uint64_t (*alloc)(struct intel_allocator *ial, uint32_t handle, - uint64_t size, uint64_t alignment); + uint64_t size, uint64_t alignment, + enum allocator_strategy strategy); bool (*is_allocated)(struct intel_allocator *ial, uint32_t handle, uint64_t size, uint64_t alignment); bool (*reserve)(struct intel_allocator *ial, @@ -181,9 +182,14 @@ bool intel_allocator_close(uint64_t allocator_handle); void intel_allocator_get_address_range(uint64_t allocator_handle, uint64_t *startp, uint64_t *endp); uint64_t __intel_allocator_alloc(uint64_t allocator_handle, uint32_t handle, - uint64_t size, uint64_t alignment); + uint64_t size, uint64_t alignment, + enum allocator_strategy strategy); uint64_t intel_allocator_alloc(uint64_t allocator_handle, uint32_t handle, uint64_t size, uint64_t alignment); +uint64_t intel_allocator_alloc_with_strategy(uint64_t allocator_handle, + uint32_t handle, + uint64_t size, uint64_t alignment, + enum allocator_strategy strategy); bool intel_allocator_free(uint64_t allocator_handle, uint32_t handle); bool intel_allocator_is_allocated(uint64_t allocator_handle, uint32_t handle, uint64_t size, uint64_t offset); diff --git a/lib/intel_allocator_msgchannel.h b/lib/intel_allocator_msgchannel.h index ac6edfb9e..c7a738a08 100644 --- a/lib/intel_allocator_msgchannel.h +++ b/lib/intel_allocator_msgchannel.h @@ -65,6 +65,7 @@ struct alloc_req { uint32_t handle; uint64_t size; uint64_t alignment; + uint8_t strategy; } alloc; struct { diff --git a/lib/intel_allocator_random.c b/lib/intel_allocator_random.c index d804e3318..3d9a78f17 100644 --- a/lib/intel_allocator_random.c +++ b/lib/intel_allocator_random.c @@ -45,12 +45,14 @@ static void intel_allocator_random_get_address_range(struct intel_allocator *ial static uint64_t intel_allocator_random_alloc(struct intel_allocator *ial, uint32_t handle, uint64_t size, - uint64_t alignment) + uint64_t alignment, + enum allocator_strategy strategy) { struct intel_allocator_random *ialr = ial->priv; uint64_t offset; (void) handle; + (void) strategy; /* randomize the address, we try to avoid relocations */ do { diff --git a/lib/intel_allocator_reloc.c b/lib/intel_allocator_reloc.c index abf9c30cd..e8af787b0 100644 --- a/lib/intel_allocator_reloc.c +++ b/lib/intel_allocator_reloc.c @@ -46,12 +46,14 @@ static void intel_allocator_reloc_get_address_range(struct intel_allocator *ial, static uint64_t intel_allocator_reloc_alloc(struct intel_allocator *ial, uint32_t handle, uint64_t size, - uint64_t alignment) + uint64_t alignment, + enum allocator_strategy strategy) { struct intel_allocator_reloc *ialr = ial->priv; uint64_t offset, aligned_offset; (void) handle; + (void) strategy; alignment = max(alignment, 4096); aligned_offset = ALIGN(ialr->offset, alignment); diff --git a/lib/intel_allocator_simple.c b/lib/intel_allocator_simple.c index a419955af..963d8d257 100644 --- a/lib/intel_allocator_simple.c +++ b/lib/intel_allocator_simple.c @@ -25,12 +25,7 @@ intel_allocator_simple_create_full(int fd, uint64_t start, uint64_t end, struct simple_vma_heap { struct igt_list_head holes; - - /* If true, simple_vma_heap_alloc will prefer high addresses - * - * Default is true. - */ - bool alloc_high; + enum allocator_strategy strategy; }; struct simple_vma_hole { @@ -220,14 +215,11 @@ static void simple_vma_heap_init(struct simple_vma_heap *heap, IGT_INIT_LIST_HEAD(&heap->holes); simple_vma_heap_free(heap, start, size); - switch (strategy) { - case ALLOC_STRATEGY_LOW_TO_HIGH: - heap->alloc_high = false; - break; - case ALLOC_STRATEGY_HIGH_TO_LOW: - default: - heap->alloc_high = true; - } + /* Use LOW_TO_HIGH or HIGH_TO_LOW strategy only */ + if (strategy == ALLOC_STRATEGY_LOW_TO_HIGH) + heap->strategy = strategy; + else + heap->strategy = ALLOC_STRATEGY_HIGH_TO_LOW; } static void simple_vma_heap_finish(struct simple_vma_heap *heap) @@ -294,7 +286,8 @@ static void simple_vma_hole_alloc(struct simple_vma_hole *hole, static bool simple_vma_heap_alloc(struct simple_vma_heap *heap, uint64_t *offset, uint64_t size, - uint64_t alignment) + uint64_t alignment, + enum allocator_strategy strategy) { struct simple_vma_hole *hole, *tmp; uint64_t misalign; @@ -305,7 +298,16 @@ static bool simple_vma_heap_alloc(struct simple_vma_heap *heap, simple_vma_heap_validate(heap); - if (heap->alloc_high) { + /* Ensure we support only NONE/LOW_TO_HIGH/HIGH_TO_LOW strategies */ + igt_assert(strategy == ALLOC_STRATEGY_NONE || + strategy == ALLOC_STRATEGY_LOW_TO_HIGH || + strategy == ALLOC_STRATEGY_HIGH_TO_LOW); + + /* Use default strategy chosen on open */ + if (strategy == ALLOC_STRATEGY_NONE) + strategy = heap->strategy; + + if (strategy == ALLOC_STRATEGY_HIGH_TO_LOW) { simple_vma_foreach_hole_safe(hole, heap, tmp) { if (size > hole->size) continue; @@ -412,7 +414,8 @@ static bool simple_vma_heap_alloc_addr(struct intel_allocator_simple *ials, static uint64_t intel_allocator_simple_alloc(struct intel_allocator *ial, uint32_t handle, uint64_t size, - uint64_t alignment) + uint64_t alignment, + enum allocator_strategy strategy) { struct intel_allocator_record *rec; struct intel_allocator_simple *ials; @@ -430,7 +433,7 @@ static uint64_t intel_allocator_simple_alloc(struct intel_allocator *ial, igt_assert(rec->size == size); } else { if (!simple_vma_heap_alloc(&ials->heap, &offset, - size, alignment)) + size, alignment, strategy)) return ALLOC_INVALID_ADDRESS; rec = malloc(sizeof(*rec)); diff --git a/tests/i915/api_intel_allocator.c b/tests/i915/api_intel_allocator.c index 7ff92a174..182d9ba79 100644 --- a/tests/i915/api_intel_allocator.c +++ b/tests/i915/api_intel_allocator.c @@ -50,10 +50,19 @@ static void alloc_simple(int fd) intel_allocator_get_address_range(ahnd, &start, &end); offset0 = intel_allocator_alloc(ahnd, 1, end - start, 0); - offset1 = __intel_allocator_alloc(ahnd, 2, 4096, 0); + offset1 = __intel_allocator_alloc(ahnd, 2, 4096, 0, ALLOC_STRATEGY_NONE); igt_assert(offset1 == ALLOC_INVALID_ADDRESS); intel_allocator_free(ahnd, 1); + offset0 = intel_allocator_alloc_with_strategy(ahnd, 1, 4096, 0, + ALLOC_STRATEGY_HIGH_TO_LOW); + offset1 = intel_allocator_alloc_with_strategy(ahnd, 2, 4096, 0, + ALLOC_STRATEGY_LOW_TO_HIGH); + igt_assert(offset0 > offset1); + + intel_allocator_free(ahnd, 1); + intel_allocator_free(ahnd, 2); + igt_assert_eq(intel_allocator_close(ahnd), true); } |