1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
From b0528bcab16cfc78c4e54e22203a48e8ae19c6cd Mon Sep 17 00:00:00 2001
From: Zhou Qiankang <wszqkzqk@qq.com>
Date: Tue, 16 Sep 2025 14:03:48 +0800
Subject: [PATCH] anv: Use os_get_page_size for mmap offset alignment to work
with page size other than 4K
Instead of hardcoding 4096-byte page size in bo mapping/unmapping logic,
use os_get_page_size() to determine the correct alignment for munmap()
offset adjustments and address assertions.
Signed-off-by: Zhou Qiankang <wszqkzqk@qq.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37389>
---
src/intel/vulkan/anv_allocator.c | 12 +++++++-----
src/intel/vulkan/anv_physical_device.c | 3 +++
src/intel/vulkan/anv_private.h | 2 ++
3 files changed, 12 insertions(+), 5 deletions(-)
--- a/src/intel/vulkan/anv_allocator.c
+++ b/src/intel/vulkan/anv_allocator.c
@@ -1811,8 +1811,9 @@ anv_device_map_bo(struct anv_device *dev
if (real != bo) {
offset += (bo->offset - real->offset);
+ const uint64_t page_size = device->physical->page_size;
/* KMD rounds munmap() to whole pages, so here doing some adjustments */
- const uint64_t munmap_offset = ROUND_DOWN_TO(offset, 4096);
+ const uint64_t munmap_offset = ROUND_DOWN_TO(offset, page_size);
if (munmap_offset != offset) {
offset_adjustment = offset - munmap_offset;
size += offset_adjustment;
@@ -1822,7 +1823,7 @@ anv_device_map_bo(struct anv_device *dev
placed_addr -= offset_adjustment;
}
- assert((offset & (4096 - 1)) == 0);
+ assert((offset & (page_size - 1)) == 0);
}
void *map = device->kmd_backend->gem_mmap(device, bo, offset, size, placed_addr);
@@ -1850,14 +1851,15 @@ anv_device_unmap_bo(struct anv_device *d
struct anv_bo *real = anv_bo_get_real(bo);
if (real != bo) {
+ const uint64_t page_size = device->physical->page_size;
uint64_t slab_offset = bo->offset - real->offset;
- if (ROUND_DOWN_TO(slab_offset, 4096) != slab_offset) {
- slab_offset -= ROUND_DOWN_TO(slab_offset, 4096);
+ if (ROUND_DOWN_TO(slab_offset, page_size) != slab_offset) {
+ slab_offset -= ROUND_DOWN_TO(slab_offset, page_size);
map -= slab_offset;
map_size += slab_offset;
}
- assert(((uintptr_t)map & (4096 - 1)) == 0);
+ assert(((uintptr_t)map & (page_size - 1)) == 0);
}
if (replace) {
--- a/src/intel/vulkan/anv_physical_device.c
+++ b/src/intel/vulkan/anv_physical_device.c
@@ -18,6 +18,7 @@
#include "util/disk_cache.h"
#include "util/mesa-sha1.h"
+#include "util/os_misc.h"
#include <xf86drm.h>
#include <fcntl.h>
@@ -2756,6 +2757,8 @@ anv_physical_device_try_create(struct vk
if (result != VK_SUCCESS)
goto fail_compiler;
+ os_get_page_size(&device->page_size);
+
anv_physical_device_init_va_ranges(device);
anv_physical_device_init_disk_cache(device);
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1093,6 +1093,8 @@ struct anv_physical_device {
/** True if we can use timeline semaphores through execbuf */
bool has_exec_timeline;
+ uint64_t page_size;
+
/** True if we can read the GPU timestamp register
*
* When running in a virtual context, the timestamp register is unreadable
|