anv: Fix vm bind of imported buffers

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 <jose.souza@intel.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22219>
This commit is contained in:
José Roberto de Souza 2023-04-11 08:36:42 -07:00 committed by Marge Bot
parent 87978c3933
commit b1299f42ff
6 changed files with 25 additions and 6 deletions

View file

@ -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 =

View file

@ -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;
}

View file

@ -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,

View file

@ -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;

View file

@ -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;
}

View file

@ -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,