anv: Calculate mmap mode based on alloc_flags

When anv_device_map_bo() is called from anv_device_alloc_bo() it gets
VkMemoryPropertyFlags set to 0 so it ends up with a write-combine
caching for integrated platforms with LLC, see 'if (!(property_flags &
VK_MEMORY_PROPERTY_HOST_CACHED_BIT)))'.

Current approach also has issues when mapping with anv_MapMemory2KHR()
as it would not have information to know that BO is a scanout.

It was also not properly calculating mmap mode for platforms with PAT
uAPI before "anv: Change default PAT entry to WC".

So here storing alloc_flags to anv_bo so there is no mismatches
between different code paths then using it to properly
calculate the mmap mode.

alloc_flags in anv_bo will also be used to calculate PAT index in
future patches.

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/26099>
This commit is contained in:
José Roberto de Souza
2023-09-07 14:34:10 -07:00
committed by Marge Bot
parent 58301c00da
commit 7bdfabb641
9 changed files with 71 additions and 29 deletions
+42 -4
View File
@@ -1423,6 +1423,39 @@ anv_bo_vma_alloc_or_close(struct anv_device *device,
return VK_SUCCESS;
}
enum intel_device_info_mmap_mode
anv_bo_get_mmap_mode(struct anv_device *device, struct anv_bo *bo)
{
enum anv_bo_alloc_flags alloc_flags = bo->alloc_flags;
if (device->info->has_set_pat_uapi)
return anv_device_get_pat_entry(device, alloc_flags)->mmap;
if (anv_physical_device_has_vram(device->physical)) {
if (alloc_flags & ANV_BO_ALLOC_NO_LOCAL_MEM)
return INTEL_DEVICE_INFO_MMAP_MODE_WB;
return INTEL_DEVICE_INFO_MMAP_MODE_WC;
}
/* gfx9 atom */
if (!device->info->has_llc) {
/* ANV_BO_ALLOC_SNOOPED means that user wants a cached and coherent memory
* but to achieve it without LLC in older platforms
* DRM_IOCTL_I915_GEM_SET_CACHING needs to be supported and set.
*/
if (alloc_flags & ANV_BO_ALLOC_SNOOPED)
return INTEL_DEVICE_INFO_MMAP_MODE_WB;
return INTEL_DEVICE_INFO_MMAP_MODE_WC;
}
if (alloc_flags & (ANV_BO_ALLOC_SCANOUT | ANV_BO_ALLOC_EXTERNAL))
return INTEL_DEVICE_INFO_MMAP_MODE_WC;
return INTEL_DEVICE_INFO_MMAP_MODE_WB;
}
VkResult
anv_device_alloc_bo(struct anv_device *device,
const char *name,
@@ -1480,6 +1513,7 @@ anv_device_alloc_bo(struct anv_device *device,
.size = size,
.actual_size = actual_size,
.flags = bo_flags,
.alloc_flags = alloc_flags,
.is_external = (alloc_flags & ANV_BO_ALLOC_EXTERNAL),
.has_client_visible_address =
(alloc_flags & ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS) != 0,
@@ -1488,8 +1522,7 @@ anv_device_alloc_bo(struct anv_device *device,
};
if (alloc_flags & ANV_BO_ALLOC_MAPPED) {
VkResult result = anv_device_map_bo(device, &new_bo, 0, size,
0 /* propertyFlags */, &new_bo.map);
VkResult result = anv_device_map_bo(device, &new_bo, 0, size, &new_bo.map);
if (unlikely(result != VK_SUCCESS)) {
device->kmd_backend->gem_close(device, &new_bo);
return result;
@@ -1526,13 +1559,12 @@ anv_device_map_bo(struct anv_device *device,
struct anv_bo *bo,
uint64_t offset,
size_t size,
VkMemoryPropertyFlags property_flags,
void **map_out)
{
assert(!bo->from_host_ptr);
assert(size > 0);
void *map = anv_gem_mmap(device, bo, offset, size, property_flags);
void *map = anv_gem_mmap(device, bo, offset, size);
if (unlikely(map == MAP_FAILED))
return vk_errorf(device, VK_ERROR_MEMORY_MAP_FAILED, "mmap failed: %m");
@@ -1617,6 +1649,8 @@ anv_device_import_bo_from_host_ptr(struct anv_device *device,
__sync_fetch_and_add(&bo->refcount, 1);
} else {
/* Makes sure that userptr gets WB mmap caching and right VM PAT index */
alloc_flags |= (ANV_BO_ALLOC_SNOOPED | ANV_BO_ALLOC_NO_LOCAL_MEM);
struct anv_bo new_bo = {
.name = "host-ptr",
.gem_handle = gem_handle,
@@ -1626,6 +1660,7 @@ anv_device_import_bo_from_host_ptr(struct anv_device *device,
.actual_size = size,
.map = host_ptr,
.flags = bo_flags,
.alloc_flags = alloc_flags,
.is_external = true,
.from_host_ptr = true,
.has_client_visible_address =
@@ -1707,12 +1742,15 @@ anv_device_import_bo(struct anv_device *device,
__sync_fetch_and_add(&bo->refcount, 1);
} else {
/* so imported bos get WB and correct PAT index */
alloc_flags |= (ANV_BO_ALLOC_SNOOPED | ANV_BO_ALLOC_NO_LOCAL_MEM);
struct anv_bo new_bo = {
.name = "imported",
.gem_handle = gem_handle,
.refcount = 1,
.offset = -1,
.is_external = true,
.alloc_flags = alloc_flags,
.has_client_visible_address =
(alloc_flags & ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS) != 0,
};
+1 -2
View File
@@ -4326,8 +4326,7 @@ VkResult anv_MapMemory2KHR(
map_size = align64(map_size, 4096);
void *map;
VkResult result = anv_device_map_bo(device, mem->bo, map_offset, map_size,
mem->type->propertyFlags, &map);
VkResult result = anv_device_map_bo(device, mem->bo, map_offset, map_size, &map);
if (result != VK_SUCCESS)
return result;
+2 -3
View File
@@ -36,10 +36,9 @@
void *
anv_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset,
uint64_t size, VkMemoryPropertyFlags property_flags)
uint64_t size)
{
void *map = device->kmd_backend->gem_mmap(device, bo, offset, size,
property_flags);
void *map = device->kmd_backend->gem_mmap(device, bo, offset, size);
if (map != MAP_FAILED)
VG(VALGRIND_MALLOCLIKE_BLOCK(map, size, 0, 1));
+3 -4
View File
@@ -52,7 +52,7 @@ stub_gem_create(struct anv_device *device,
static void *
stub_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset,
uint64_t size, VkMemoryPropertyFlags property_flags)
uint64_t size)
{
return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->gem_handle,
offset);
@@ -95,10 +95,9 @@ stub_bo_alloc_flags_to_bo_flags(struct anv_device *device,
void *
anv_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset,
uint64_t size, VkMemoryPropertyFlags property_flags)
uint64_t size)
{
void *map = device->kmd_backend->gem_mmap(device, bo, offset, size,
property_flags);
void *map = device->kmd_backend->gem_mmap(device, bo, offset, size);
if (map != MAP_FAILED)
VG(VALGRIND_MALLOCLIKE_BLOCK(map, size, 0, 1));
+1 -2
View File
@@ -66,8 +66,7 @@ struct anv_kmd_backend {
void (*gem_close)(struct anv_device *device, struct anv_bo *bo);
/* Returns MAP_FAILED on error */
void *(*gem_mmap)(struct anv_device *device, struct anv_bo *bo,
uint64_t offset, uint64_t size,
VkMemoryPropertyFlags property_flags);
uint64_t offset, uint64_t size);
/* Bind things however you want. */
int (*vm_bind)(struct anv_device *device, int num_binds,
struct anv_vm_bind *binds);
+6 -2
View File
@@ -455,6 +455,8 @@ struct anv_bo {
/** Flags to pass to the kernel through drm_i915_exec_object2::flags */
uint32_t flags;
enum anv_bo_alloc_flags alloc_flags;
/** True if this BO may be shared with other processes */
bool is_external:1;
@@ -478,6 +480,9 @@ anv_bo_ref(struct anv_bo *bo)
return bo;
}
enum intel_device_info_mmap_mode
anv_bo_get_mmap_mode(struct anv_device *device, struct anv_bo *bo);
struct anv_address {
struct anv_bo *bo;
int64_t offset;
@@ -1800,7 +1805,6 @@ VkResult anv_device_map_bo(struct anv_device *device,
struct anv_bo *bo,
uint64_t offset,
size_t size,
uint32_t gem_flags,
void **map_out);
void anv_device_unmap_bo(struct anv_device *device,
struct anv_bo *bo,
@@ -1859,7 +1863,7 @@ void anv_queue_trace(struct anv_queue *queue, const char *label,
void *
anv_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset,
uint64_t size, VkMemoryPropertyFlags property_flags);
uint64_t size);
void anv_gem_munmap(struct anv_device *device, void *p, uint64_t size);
int anv_gem_wait(struct anv_device *device, uint32_t gem_handle, int64_t *timeout_ns);
int anv_gem_set_tiling(struct anv_device *device, uint32_t gem_handle,
+1 -1
View File
@@ -597,7 +597,7 @@ anv_h265_decode_video(struct anv_cmd_buffer *cmd_buffer,
/* Slice parsing */
uint32_t last_slice = h265_pic_info->sliceSegmentCount - 1;
void *slice_map = anv_gem_mmap(cmd_buffer->device, src_buffer->address.bo,
src_buffer->address.offset, frame_info->srcBufferRange, 0);
src_buffer->address.offset, frame_info->srcBufferRange);
struct vk_video_h265_slice_params slice_params[h265_pic_info->sliceSegmentCount];
+14 -10
View File
@@ -164,18 +164,22 @@ i915_gem_mmap_legacy(struct anv_device *device, struct anv_bo *bo, uint64_t offs
}
static uint32_t
mmap_calc_flags(struct anv_device *device, struct anv_bo *bo,
VkMemoryPropertyFlags property_flags)
mmap_calc_flags(struct anv_device *device, struct anv_bo *bo)
{
if (device->info->has_local_mem)
return I915_MMAP_OFFSET_FIXED;
uint32_t flags = 0;
if (!device->info->has_llc &&
(property_flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
flags |= I915_MMAP_WC;
if (!(property_flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT))
flags |= I915_MMAP_WC;
uint32_t flags;
switch (anv_bo_get_mmap_mode(device, bo)) {
case INTEL_DEVICE_INFO_MMAP_MODE_WC:
flags = I915_MMAP_WC;
break;
case INTEL_DEVICE_INFO_MMAP_MODE_UC:
unreachable("Missing");
default:
/* no flags == WB */
flags = 0;
}
if (likely(device->physical->info.has_mmap_offset))
flags = (flags & I915_MMAP_WC) ? I915_MMAP_OFFSET_WC : I915_MMAP_OFFSET_WB;
@@ -184,9 +188,9 @@ mmap_calc_flags(struct anv_device *device, struct anv_bo *bo,
static void *
i915_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset,
uint64_t size, VkMemoryPropertyFlags property_flags)
uint64_t size)
{
const uint32_t flags = mmap_calc_flags(device, bo, property_flags);
const uint32_t flags = mmap_calc_flags(device, bo);
if (likely(device->physical->info.has_mmap_offset))
return i915_gem_mmap_offset(device, bo, size, flags);
+1 -1
View File
@@ -81,7 +81,7 @@ xe_gem_close(struct anv_device *device, struct anv_bo *bo)
static void *
xe_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset,
uint64_t size, VkMemoryPropertyFlags property_flags)
uint64_t size)
{
struct drm_xe_gem_mmap_offset args = {
.handle = bo->gem_handle,