From 0bcb82048cba02204f975077afab8dddfbc4b398 Mon Sep 17 00:00:00 2001 From: Jose Maria Casanova Crespo Date: Sat, 5 Apr 2025 03:43:24 +0200 Subject: [PATCH] v3dv: avoid TFU reading unmapped pages beyond the end of the buffers TFU units is doing a readahead of 64 bytes. This is causing invalid read MMU errors that can be observed at the nightly full Vulkan runs on Broadcom devices. 04:13:59.969: [ 85.623205] v3d 1002000000.v3d: MMU error from client TLB (3) at 0x4869000, pte invalid 04:14:05.408: [ 91.019321] v3d 1002000000.v3d: MMU error from client TLB (3) at 0x5209000, pte invalid 04:14:05.413: [ 91.031662] v3d 1002000000.v3d: MMU error from client TLB (3) at 0x7521000, pte invalid Although the log reports the TLB the real culprit is the TFU. A fix to the kernel was submitted to fix AXI ID on V3D 4.2 and 7.1 So doing an over-allocation of 64-bytes at v3dv_AllocateMemory is the simplest method to make these MMU errors itp disapear. Running ./deqp-vk for an hour, we can see that ~%40 of allocations would need an extra page (4096 bytes) to accomodate this 64 bytes padding. Fixes: ca330f7f046 ("v3dv: implement VK_EXT_memory_budget") Reviewed-by: Iago Toral Quiroga Part-of: --- src/broadcom/vulkan/v3dv_device.c | 8 ++++++-- src/broadcom/vulkan/v3dv_private.h | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c index 459500bf151..821aff205fd 100644 --- a/src/broadcom/vulkan/v3dv_device.c +++ b/src/broadcom/vulkan/v3dv_device.c @@ -2208,9 +2208,13 @@ v3dv_AllocateMemory(VkDevice _device, assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO); /* We always allocate device memory in multiples of a page, so round up - * requested size to that. + * requested size to that. We need to add a V3D_TFU_READHAEAD padding to + * avoid invalid reads done by the TFU unit after the end of the last page + * allocated. */ - const VkDeviceSize alloc_size = align64(pAllocateInfo->allocationSize, 4096); + + const VkDeviceSize alloc_size = align64(pAllocateInfo->allocationSize + + V3D_TFU_READAHEAD_SIZE, 4096); if (unlikely(alloc_size > MAX_MEMORY_ALLOCATION_SIZE)) return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 94cb7841dad..45bc2c989b6 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -591,6 +591,11 @@ struct v3dv_device { struct util_dynarray device_address_bo_list; /* Array of struct v3dv_bo * */ }; +/* TFU has readhead of 64 bytes. So to avoid the unit reading unmaped memory + * it is needed to overallocate buffers that could be read by the TFU + */ +#define V3D_TFU_READAHEAD_SIZE 64 + struct v3dv_device_memory { struct vk_device_memory vk;