From 9ef1cbc16baa04056f581d4451bf22c333dce263 Mon Sep 17 00:00:00 2001 From: Caterina Shablia Date: Tue, 9 Sep 2025 22:37:19 +0000 Subject: [PATCH] pan/kmod,panvk: rewrite how alignment for an allocation is chosen The current code assumes 2M and 4k pages. If an allocation request is larger than 2M, allocation will be aligned to 2M, otherwise to 4k. The new code is informed by pgsize_bitmap. The allocation is aligned to a particular page boundary, if the request is at least as large as that page boundary. Note that given pgsize_bitmap = PGSIZE_4K | PGSIZE_2M 2M requests will now be aligned to a 2M boundary, rather than 4k, which is the case with the current code. Reviewed-by: Boris Brezillon Part-of: --- src/panfrost/lib/kmod/panthor_kmod.c | 3 ++- src/panfrost/lib/pan_props.c | 15 +++++++++++++++ src/panfrost/lib/pan_props.h | 4 ++++ src/panfrost/vulkan/panvk_device_memory.c | 7 ++++--- src/panfrost/vulkan/panvk_priv_bo.c | 5 +++-- 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/panfrost/lib/kmod/panthor_kmod.c b/src/panfrost/lib/kmod/panthor_kmod.c index c124a133be5..661f7c16cf1 100644 --- a/src/panfrost/lib/kmod/panthor_kmod.c +++ b/src/panfrost/lib/kmod/panthor_kmod.c @@ -21,6 +21,7 @@ #include "drm-uapi/panthor_drm.h" #include "pan_kmod_backend.h" +#include "pan_props.h" /* Maximum kmod BO label length, including NUL-terminator */ #define PANTHOR_BO_LABEL_MAXLEN 4096 @@ -829,7 +830,7 @@ panthor_kmod_vm_alloc_va(struct panthor_kmod_vm *panthor_vm, uint64_t size) simple_mtx_lock(&panthor_vm->auto_va.lock); panthor_kmod_vm_collect_freed_vas(panthor_vm); va = util_vma_heap_alloc(&panthor_vm->auto_va.heap, size, - size > 0x200000 ? 0x200000 : 0x1000); + pan_choose_gpu_va_alignment(&panthor_vm->base, size)); simple_mtx_unlock(&panthor_vm->auto_va.lock); return va; diff --git a/src/panfrost/lib/pan_props.c b/src/panfrost/lib/pan_props.c index 317b230fec2..ebd4673340e 100644 --- a/src/panfrost/lib/pan_props.c +++ b/src/panfrost/lib/pan_props.c @@ -302,3 +302,18 @@ pan_clamp_to_usable_va_range(const struct pan_kmod_dev *dev, uint64_t va) return va; } + +uint64_t +pan_choose_gpu_va_alignment(const struct pan_kmod_vm *vm, uint64_t size) +{ + assert(vm->pgsize_bitmap != 0); + + uint64_t align = 0; + u_foreach_bit64(pgsize_bit, vm->pgsize_bitmap) { + uint64_t pgsize = (uint64_t)1 << pgsize_bit; + if (align > 0 && pgsize > size) + break; + align = pgsize; + } + return align; +} diff --git a/src/panfrost/lib/pan_props.h b/src/panfrost/lib/pan_props.h index 7f7850bcb22..499f718d9bf 100644 --- a/src/panfrost/lib/pan_props.h +++ b/src/panfrost/lib/pan_props.h @@ -34,6 +34,7 @@ struct pan_kmod_dev; struct pan_kmod_dev_props; +struct pan_kmod_vm; /** Implementation-defined tiler features */ struct pan_tiler_features { @@ -155,6 +156,9 @@ pan_query_optimal_z_tib_size(unsigned arch, const struct pan_model *model) uint64_t pan_clamp_to_usable_va_range(const struct pan_kmod_dev *dev, uint64_t va); +uint64_t pan_choose_gpu_va_alignment(const struct pan_kmod_vm *vm, + uint64_t size); + unsigned pan_compute_max_thread_count(const struct pan_kmod_dev_props *props, unsigned work_reg_count); diff --git a/src/panfrost/vulkan/panvk_device_memory.c b/src/panfrost/vulkan/panvk_device_memory.c index 1e0ffaec2da..eaa03f1e21e 100644 --- a/src/panfrost/vulkan/panvk_device_memory.c +++ b/src/panfrost/vulkan/panvk_device_memory.c @@ -12,6 +12,8 @@ #include "panvk_device_memory.h" #include "panvk_entrypoints.h" +#include "pan_props.h" + #include "vk_log.h" static void * @@ -118,9 +120,8 @@ panvk_AllocateMemory(VkDevice _device, }; if (!(device->kmod.vm->flags & PAN_KMOD_VM_FLAG_AUTO_VA)) { - op.va.start = - panvk_as_alloc(device, op.va.size, - op.va.size > 0x200000 ? 0x200000 : 0x1000); + op.va.start = panvk_as_alloc(device, op.va.size, + pan_choose_gpu_va_alignment(device->kmod.vm, op.va.size)); if (!op.va.start) { result = panvk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); goto err_put_bo; diff --git a/src/panfrost/vulkan/panvk_priv_bo.c b/src/panfrost/vulkan/panvk_priv_bo.c index 86f5ba9e81b..06b619b7207 100644 --- a/src/panfrost/vulkan/panvk_priv_bo.c +++ b/src/panfrost/vulkan/panvk_priv_bo.c @@ -12,6 +12,7 @@ #include "panvk_priv_bo.h" #include "kmod/pan_kmod.h" +#include "pan_props.h" #include "genxml/decode.h" @@ -59,8 +60,8 @@ panvk_priv_bo_create(struct panvk_device *dev, uint64_t size, uint32_t flags, }; if (!(dev->kmod.vm->flags & PAN_KMOD_VM_FLAG_AUTO_VA)) { - op.va.start = panvk_as_alloc(dev, - op.va.size, op.va.size > 0x200000 ? 0x200000 : 0x1000); + op.va.start = panvk_as_alloc(dev, op.va.size, + pan_choose_gpu_va_alignment(dev->kmod.vm, op.va.size)); if (!op.va.start) { result = panvk_error(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY); goto err_munmap_bo;