// SPDX-License-Identifier: MIT /* * Copyright © 2021 Intel Corporation */ #include #include #include "igt.h" #include "igt_x86.h" #include "igt_rand.h" #include "intel_allocator.h" struct intel_allocator *intel_allocator_reloc_create(int fd); struct intel_allocator_reloc { uint64_t bias; uint32_t prng; uint64_t gtt_size; uint64_t start; uint64_t end; uint64_t offset; /* statistics */ uint64_t allocated_objects; }; static uint64_t get_bias(int fd) { (void) fd; return 256 << 10; } static void intel_allocator_reloc_get_address_range(struct intel_allocator *ial, uint64_t *startp, uint64_t *endp) { struct intel_allocator_reloc *ialr = ial->priv; if (startp) *startp = ialr->start; if (endp) *endp = ialr->end; } static uint64_t intel_allocator_reloc_alloc(struct intel_allocator *ial, uint32_t handle, uint64_t size, 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); /* Check we won't exceed end */ if (aligned_offset + size > ialr->end) aligned_offset = ALIGN(ialr->start, alignment); offset = aligned_offset; ialr->offset = offset + size; ialr->allocated_objects++; return offset; } static bool intel_allocator_reloc_free(struct intel_allocator *ial, uint32_t handle) { struct intel_allocator_reloc *ialr = ial->priv; (void) handle; ialr->allocated_objects--; return false; } static bool intel_allocator_reloc_is_allocated(struct intel_allocator *ial, uint32_t handle, uint64_t size, uint64_t offset) { (void) ial; (void) handle; (void) size; (void) offset; return false; } static void intel_allocator_reloc_destroy(struct intel_allocator *ial) { igt_assert(ial); free(ial->priv); free(ial); } static bool intel_allocator_reloc_reserve(struct intel_allocator *ial, uint32_t handle, uint64_t start, uint64_t end) { (void) ial; (void) handle; (void) start; (void) end; return false; } static bool intel_allocator_reloc_unreserve(struct intel_allocator *ial, uint32_t handle, uint64_t start, uint64_t end) { (void) ial; (void) handle; (void) start; (void) end; return false; } static bool intel_allocator_reloc_is_reserved(struct intel_allocator *ial, uint64_t start, uint64_t end) { (void) ial; (void) start; (void) end; return false; } static void intel_allocator_reloc_print(struct intel_allocator *ial, bool full) { struct intel_allocator_reloc *ialr = ial->priv; (void) full; igt_info(" allocated objects: %" PRIx64 "\n", ial, ial->fd, ialr->allocated_objects); } static bool intel_allocator_reloc_is_empty(struct intel_allocator *ial) { struct intel_allocator_reloc *ialr = ial->priv; return !ialr->allocated_objects; } #define RESERVED 4096 struct intel_allocator *intel_allocator_reloc_create(int fd) { struct intel_allocator *ial; struct intel_allocator_reloc *ialr; igt_debug("Using reloc allocator\n"); ial = calloc(1, sizeof(*ial)); igt_assert(ial); ial->fd = fd; ial->get_address_range = intel_allocator_reloc_get_address_range; ial->alloc = intel_allocator_reloc_alloc; ial->free = intel_allocator_reloc_free; ial->is_allocated = intel_allocator_reloc_is_allocated; ial->reserve = intel_allocator_reloc_reserve; ial->unreserve = intel_allocator_reloc_unreserve; ial->is_reserved = intel_allocator_reloc_is_reserved; ial->destroy = intel_allocator_reloc_destroy; ial->print = intel_allocator_reloc_print; ial->is_empty = intel_allocator_reloc_is_empty; ialr = ial->priv = calloc(1, sizeof(*ialr)); igt_assert(ial->priv); ialr->prng = (uint32_t) to_user_pointer(ial); ialr->gtt_size = gem_aperture_size(fd); igt_debug("Gtt size: %" PRId64 "\n", ialr->gtt_size); if (!gem_uses_full_ppgtt(fd)) ialr->gtt_size /= 2; ialr->bias = ialr->offset = get_bias(fd); ialr->start = ialr->bias; ialr->end = ialr->gtt_size - RESERVED; ialr->allocated_objects = 0; return ial; }