mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 15:38:09 +02:00
v3d,v3dv: fix MMU error from hardware prefetch after ldunifa
ldunifa works exactly the same as ldunif: the hw will prefetch the
next 4 bytes after a read, so if a buffer is exactly a multiple of
a page size and a shader uses ldunifa to read exactly the last 4 bytes
the prefetch will read out of bounds and spam the error on the kernel
log. Avoid that by allocating extra bytes in this scenario.
Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25752>
(cherry picked from commit 82bef62c17)
This commit is contained in:
parent
8986b7f9ae
commit
8a50c841cf
3 changed files with 24 additions and 2 deletions
|
|
@ -224,7 +224,7 @@
|
||||||
"description": "v3d,v3dv: fix MMU error from hardware prefetch after ldunifa",
|
"description": "v3d,v3dv: fix MMU error from hardware prefetch after ldunifa",
|
||||||
"nominated": true,
|
"nominated": true,
|
||||||
"nomination_type": 0,
|
"nomination_type": 0,
|
||||||
"resolution": 0,
|
"resolution": 1,
|
||||||
"main_sha": null,
|
"main_sha": null,
|
||||||
"because_sha": null,
|
"because_sha": null,
|
||||||
"notes": null
|
"notes": null
|
||||||
|
|
|
||||||
|
|
@ -2766,6 +2766,18 @@ get_buffer_memory_requirements(struct v3dv_buffer *buffer,
|
||||||
.size = align64(buffer->size, buffer->alignment),
|
.size = align64(buffer->size, buffer->alignment),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* UBO and SSBO may be read using ldunifa, which prefetches the next
|
||||||
|
* 4 bytes after a read. If the buffer's size is exactly a multiple
|
||||||
|
* of a page size and the shader reads the last 4 bytes with ldunifa
|
||||||
|
* the prefetching would read out of bounds and cause an MMU error,
|
||||||
|
* so we allocate extra space to avoid kernel error spamming.
|
||||||
|
*/
|
||||||
|
bool can_ldunifa = buffer->usage &
|
||||||
|
(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
|
||||||
|
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
||||||
|
if (can_ldunifa && (buffer->size % 4096 == 0))
|
||||||
|
pMemoryRequirements->memoryRequirements.size += buffer->alignment;
|
||||||
|
|
||||||
vk_foreach_struct(ext, pMemoryRequirements->pNext) {
|
vk_foreach_struct(ext, pMemoryRequirements->pNext) {
|
||||||
switch (ext->sType) {
|
switch (ext->sType) {
|
||||||
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
|
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,17 @@ v3d_resource_bo_alloc(struct v3d_resource *rsc)
|
||||||
struct pipe_screen *pscreen = prsc->screen;
|
struct pipe_screen *pscreen = prsc->screen;
|
||||||
struct v3d_bo *bo;
|
struct v3d_bo *bo;
|
||||||
|
|
||||||
bo = v3d_bo_alloc(v3d_screen(pscreen), rsc->size, "resource");
|
/* Buffers may be read using ldunifa, which prefetches the next
|
||||||
|
* 4 bytes after a read. If the buffer's size is exactly a multiple
|
||||||
|
* of a page size and the shader reads the last 4 bytes with ldunifa
|
||||||
|
* the prefetching would read out of bounds and cause an MMU error,
|
||||||
|
* so we allocate extra space to avoid kernel error spamming.
|
||||||
|
*/
|
||||||
|
uint32_t size = rsc->size;
|
||||||
|
if (rsc->base.target == PIPE_BUFFER && (size % 4096 == 0))
|
||||||
|
size += 4;
|
||||||
|
|
||||||
|
bo = v3d_bo_alloc(v3d_screen(pscreen), size, "resource");
|
||||||
if (bo) {
|
if (bo) {
|
||||||
v3d_bo_unreference(&rsc->bo);
|
v3d_bo_unreference(&rsc->bo);
|
||||||
rsc->bo = bo;
|
rsc->bo = bo;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue