From b1299f42ff9790dd1bbb5169a3d9357734e5fba9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Tue, 11 Apr 2023 08:36:42 -0700 Subject: [PATCH] anv: Fix vm bind of imported buffers MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Imported buffers may be created in a device with different memory alignment and this can cause vm bind to fail because bo size can be smaller than the calculated vm bind range using the importer device memory alignment. So here adding actual_size to anv_bo, this will be set with the actual size of the bo allocated by kmd for bos allocate in the current device. For other bo the lseek or the Vulkan API size will be used. Signed-off-by: José Roberto de Souza Reviewed-by: Lionel Landwerlin Part-of: --- src/intel/vulkan/anv_allocator.c | 7 ++++++- src/intel/vulkan/anv_gem_stubs.c | 4 +++- src/intel/vulkan/anv_kmd_backend.h | 3 ++- src/intel/vulkan/anv_private.h | 5 +++++ src/intel/vulkan/i915/anv_kmd_backend.c | 6 +++++- src/intel/vulkan/xe/anv_kmd_backend.c | 6 ++++-- 6 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/intel/vulkan/anv_allocator.c b/src/intel/vulkan/anv_allocator.c index 515a2c1..f35b3e6 100644 --- a/src/intel/vulkan/anv_allocator.c +++ b/src/intel/vulkan/anv_allocator.c @@ -1485,10 +1485,12 @@ anv_device_alloc_bo(struct anv_device *device, regions[nregions++] = device->physical->sys.region; } + uint64_t actual_size; uint32_t gem_handle = device->kmd_backend->gem_create(device, regions, nregions, size + ccs_size, - alloc_flags); + alloc_flags, + &actual_size); if (gem_handle == 0) return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); @@ -1499,6 +1501,7 @@ anv_device_alloc_bo(struct anv_device *device, .offset = -1, .size = size, ._ccs_size = ccs_size, + .actual_size = actual_size, .flags = bo_flags, .is_external = (alloc_flags & ANV_BO_ALLOC_EXTERNAL), .has_client_visible_address = @@ -1666,6 +1669,7 @@ anv_device_import_bo_from_host_ptr(struct anv_device *device, .refcount = 1, .offset = -1, .size = size, + .actual_size = size, .map = host_ptr, .flags = bo_flags, .is_external = true, @@ -1791,6 +1795,7 @@ anv_device_import_bo(struct anv_device *device, .refcount = 1, .offset = -1, .size = size, + .actual_size = size, .flags = bo_flags, .is_external = true, .has_client_visible_address = diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c index e9e5814..0cf2bc3 100644 --- a/src/intel/vulkan/anv_gem_stubs.c +++ b/src/intel/vulkan/anv_gem_stubs.c @@ -37,7 +37,8 @@ static uint32_t stub_gem_create(struct anv_device *device, const struct intel_memory_class_instance **regions, uint16_t num_regions, uint64_t size, - enum anv_bo_alloc_flags alloc_flags) + enum anv_bo_alloc_flags alloc_flags, + uint64_t *actual_size) { int fd = os_create_anonymous_file(size, "fake bo"); if (fd == -1) @@ -45,6 +46,7 @@ stub_gem_create(struct anv_device *device, assert(fd != 0); + *actual_size = size; return fd; } diff --git a/src/intel/vulkan/anv_kmd_backend.h b/src/intel/vulkan/anv_kmd_backend.h index f4bff78..76c5f2f 100644 --- a/src/intel/vulkan/anv_kmd_backend.h +++ b/src/intel/vulkan/anv_kmd_backend.h @@ -47,7 +47,8 @@ struct anv_kmd_backend { uint32_t (*gem_create)(struct anv_device *device, const struct intel_memory_class_instance **regions, uint16_t num_regions, uint64_t size, - enum anv_bo_alloc_flags alloc_flags); + enum anv_bo_alloc_flags alloc_flags, + uint64_t *actual_size); void (*gem_close)(struct anv_device *device, uint32_t handle); /* Returns MAP_FAILED on error */ void *(*gem_mmap)(struct anv_device *device, struct anv_bo *bo, diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index bec5456..ff424053 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -506,6 +506,11 @@ struct anv_bo { */ uint32_t _ccs_size; + /* The actual size of bo allocated by kmd, basically: + * align(size + _ccs_size, mem_alignment) + */ + uint64_t actual_size; + /** Flags to pass to the kernel through drm_i915_exec_object2::flags */ uint32_t flags; diff --git a/src/intel/vulkan/i915/anv_kmd_backend.c b/src/intel/vulkan/i915/anv_kmd_backend.c index 0546958..82917a8 100644 --- a/src/intel/vulkan/i915/anv_kmd_backend.c +++ b/src/intel/vulkan/i915/anv_kmd_backend.c @@ -33,7 +33,8 @@ static uint32_t i915_gem_create(struct anv_device *device, const struct intel_memory_class_instance **regions, uint16_t num_regions, uint64_t size, - enum anv_bo_alloc_flags alloc_flags) + enum anv_bo_alloc_flags alloc_flags, + uint64_t *actual_size) { if (unlikely(!device->info->mem.use_class_instance)) { assert(num_regions == 1 && @@ -44,6 +45,8 @@ i915_gem_create(struct anv_device *device, }; if (intel_ioctl(device->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create)) return 0; + + *actual_size = gem_create.size; return gem_create.handle; } @@ -75,6 +78,7 @@ i915_gem_create(struct anv_device *device, if (intel_ioctl(device->fd, DRM_IOCTL_I915_GEM_CREATE_EXT, &gem_create)) return 0; + *actual_size = gem_create.size; return gem_create.handle; } diff --git a/src/intel/vulkan/xe/anv_kmd_backend.c b/src/intel/vulkan/xe/anv_kmd_backend.c index 2053c81..46c4939 100644 --- a/src/intel/vulkan/xe/anv_kmd_backend.c +++ b/src/intel/vulkan/xe/anv_kmd_backend.c @@ -34,7 +34,8 @@ static uint32_t xe_gem_create(struct anv_device *device, const struct intel_memory_class_instance **regions, uint16_t regions_count, uint64_t size, - enum anv_bo_alloc_flags alloc_flags) + enum anv_bo_alloc_flags alloc_flags, + uint64_t *actual_size) { struct drm_xe_gem_create gem_create = { /* From xe_drm.h: If a VM is specified, this BO must: @@ -51,6 +52,7 @@ xe_gem_create(struct anv_device *device, if (intel_ioctl(device->fd, DRM_IOCTL_XE_GEM_CREATE, &gem_create)) return 0; + *actual_size = gem_create.size; return gem_create.handle; } @@ -95,7 +97,7 @@ xe_gem_vm_bind_op(struct anv_device *device, struct anv_bo *bo, uint32_t op) .num_binds = 1, .bind.obj = op == XE_VM_BIND_OP_UNMAP ? 0 : bo->gem_handle, .bind.obj_offset = 0, - .bind.range = align64(bo->size + bo->_ccs_size, device->info->mem_alignment), + .bind.range = bo->actual_size, .bind.addr = intel_48b_address(bo->offset), .bind.op = op, .num_syncs = 1, -- 2.7.4