From 9babb23138ad2ff75f3dfd10ed7120ca731b5d52 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: (cherry picked from commit 0bcb82048cba02204f975077afab8dddfbc4b398) --- .pick_status.json | 2 +- src/broadcom/vulkan/v3dv_device.c | 8 ++++++-- src/broadcom/vulkan/v3dv_private.h | 5 +++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 3161dc3f216..0ec95afbd18 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -904,7 +904,7 @@ "description": "v3dv: avoid TFU reading unmapped pages beyond the end of the buffers", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "ca330f7f0464820a72d5a525a71276e9636dc611", "notes": null diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c index 09448f20f77..60aec07e2aa 100644 --- a/src/broadcom/vulkan/v3dv_device.c +++ b/src/broadcom/vulkan/v3dv_device.c @@ -2202,9 +2202,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 f95792aedc9..1ab0973da68 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;