I915 小 BAR RFC 部分¶
从 DG2 开始,我们将支持设备本地内存(即 I915_MEMORY_CLASS_DEVICE)的可调整大小的 BAR,但在某些情况下,最终的 BAR 大小可能仍然小于总探测大小。在这种情况下,只有 I915_MEMORY_CLASS_DEVICE 的一部分可以被 CPU 访问(例如,前 256M),而其余部分只能通过 GPU 访问。
I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS 标志¶
新的 gem_create_ext 标志,用于告知内核 BO 将需要 CPU 访问。当将对象放置在 I915_MEMORY_CLASS_DEVICE 中时,这一点变得很重要,因为设备下方有一个小 BAR,这意味着只有其中一部分可以被 CPU 访问。如果没有此标志,内核将假定不需要 CPU 访问,并优先使用 I915_MEMORY_CLASS_DEVICE 的非 CPU 可见部分。
-
struct __drm_i915_gem_create_ext¶
现有的 gem_create 行为,增加了使用
struct i915_user_extension
的扩展支持。
定义:
struct __drm_i915_gem_create_ext {
__u64 size;
__u32 handle;
#define I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS (1 << 0);
__u32 flags;
#define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0;
#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1;
__u64 extensions;
};
成员
大小
请求的对象大小。
将返回对象分配的(页面对齐)大小。
请注意,对于某些设备,我们可能有更小的最小页面大小限制(大于 4K),例如设备本地内存。但是,一般来说,如果例如使用 I915_GEM_CREATE_EXT_MEMORY_REGIONS 扩展将对象放置在设备本地内存中,则此处最终大小应始终反映任何向上舍入。内核将始终选择一组可能位置的最大最小页面大小作为向上舍入大小时要使用的值。
句柄
返回对象的句柄。
对象句柄为非零。
标志
可选标志。
支持的值
I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS - 向内核发出信号,表示该对象需要通过 CPU 访问。
仅在将对象放置在 I915_MEMORY_CLASS_DEVICE 中时有效,并且仅在设备内存的某些子集可通过 CPU 直接可见/映射的配置(我们也称为小 BAR)上严格要求,例如在某些 DG2+ 系统上。请注意,这是非常不理想的,但是由于各种因素(如客户端 CPU、BIOS 等),我们可以预期在实际应用中会看到这种情况。有关如何确定此系统是否适用,请参阅
__drm_i915_memory_region_info.probed_cpu_visible_size
。请注意,必须有一个位置是 I915_MEMORY_CLASS_SYSTEM,以确保内核始终可以将分配溢出到系统内存,如果无法将对象分配到 I915_MEMORY_CLASS_DEVICE 的可映射部分。
另请注意,由于内核仅支持可以仅放置在 I915_MEMORY_CLASS_DEVICE 中的对象的平面 CCS,因此我们不支持 I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS 与平面 CCS 一起使用。
如果没有此提示,内核将假定此对象首选不可映射的 I915_MEMORY_CLASS_DEVICE。请注意,如果用户空间对该对象进行 CPU 故障,内核仍然可以将该对象迁移到可映射部分作为最后的手段,但这可能会很昂贵,因此理想情况下应避免这种情况。
在缺少相关小 BAR uAPI 支持的旧内核上(另请参阅
__drm_i915_memory_region_info.probed_cpu_visible_size
),使用该标志将导致错误,但假设我们也可以成功加载 i915 内核模块,则绝对不应该出现小 BAR 配置。在这种情况下,整个 I915_MEMORY_CLASS_DEVICE 区域都可以被 CPU 访问,因此对对象的放置位置没有任何限制。扩展
要应用于此对象的扩展链。
当我们需要支持几种不同的扩展,并且在创建对象时需要应用多个扩展时,这将很有用。请参阅
struct i915_user_extension
。如果我们不提供任何扩展,那么我们将获得相同的旧 gem_create 行为。
对于 I915_GEM_CREATE_EXT_MEMORY_REGIONS 的用法,请参阅
struct drm_i915_gem_create_ext_memory_regions
。对于 I915_GEM_CREATE_EXT_PROTECTED_CONTENT 的用法,请参阅
struct drm_i915_gem_create_ext_protected_content
。
描述
请注意,应在此处添加新的缓冲区标志,至少对于不可变的内容。以前我们会使用两个 ioctl,一个使用 gem_create 创建对象,另一个应用各种参数,但这会给被认为是不可变的参数带来一些歧义。此外,总的来说,我们正在逐步淘汰各种 SET/GET ioctl。
probed_cpu_visible_size 属性¶
新的 struct__drm_i915_memory_region 属性,用于返回特定区域的 CPU 可访问部分的全部大小。这应该仅适用于 I915_MEMORY_CLASS_DEVICE。我们还会报告 unallocated_cpu_visible_size,以及 unallocated_size。
Vulkan 将需要此属性,作为创建设置了 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT 的单独 VkMemoryHeap 的一部分,以表示 CPU 可见部分,其中需要知道堆的总大小。它还希望能够粗略估计如何潜在地分配内存。
-
struct __drm_i915_memory_region_info¶
描述驱动程序已知的一个区域。
定义:
struct __drm_i915_memory_region_info {
struct drm_i915_gem_memory_class_instance region;
__u32 rsvd0;
__u64 probed_size;
__u64 unallocated_size;
union {
__u64 rsvd1[8];
struct {
__u64 probed_cpu_visible_size;
__u64 unallocated_cpu_visible_size;
};
};
};
成员
区域
类:实例对编码
rsvd0
MBZ
probed_size
驱动程序探测的内存
请注意,此处绝对不应遇到零值,另请注意,当前没有任何区域类型会在此处返回 -1。但是对于将来的区域类型,这可能是一种可能性。这同样适用于其他大小字段。
unallocated_size
剩余内存的估计值
需要 CAP_PERFMON 或 CAP_SYS_ADMIN 才能获得可靠的会计。如果没有此权限(或者如果这是一个较旧的内核),则此处的值将始终等于 probed_size。请注意,这目前仅针对 I915_MEMORY_CLASS_DEVICE 区域进行跟踪(对于其他类型,此处的值将始终等于 probed_size)。
{未命名联合}
匿名
rsvd1
MBZ
{未命名结构}
匿名
probed_cpu_visible_size
驱动程序探测到的可被 CPU 访问的内存。
这始终会 <= probed_size,其余部分(如果有)将无法被 CPU 访问。
在没有小 BAR 的系统上,probed_size 将始终等于 probed_cpu_visible_size,因为所有内存都将可以被 CPU 访问。
请注意,这仅针对 I915_MEMORY_CLASS_DEVICE 区域进行跟踪(对于其他类型,此处的值将始终等于 probed_size)。
请注意,如果此处返回的值为零,则这必须是缺少相关小 BAR uAPI 支持的旧内核(包括 I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS),但是在这样的系统上,假设我们能够加载内核模块,则实际上不应该出现小 BAR 配置。因此,将其视为与 probed_cpu_visible_size == probed_size 相同是安全的。
unallocated_cpu_visible_size
剩余的 CPU 可见内存的估计值
请注意,这仅针对 I915_MEMORY_CLASS_DEVICE 区域进行跟踪(对于其他类型,此处的值将始终等于 probed_cpu_visible_size)。
需要 CAP_PERFMON 或 CAP_SYS_ADMIN 才能获得可靠的会计。如果没有此权限,此处的值将始终等于 probed_cpu_visible_size。请注意,这目前仅针对 I915_MEMORY_CLASS_DEVICE 区域进行跟踪(对于其他类型,此处的值也将始终等于 probed_cpu_visible_size)。
如果这是一个较旧的内核,则此处的值将为零,另请参阅 probed_cpu_visible_size。
描述
请注意,这同时使用了 struct drm_i915_query_item
和 struct drm_i915_query
。对于此新查询,我们在 drm_i915_query_item.query_id
处添加了新的查询 ID DRM_I915_QUERY_MEMORY_REGIONS。
错误捕获限制¶
对于错误捕获,我们有两个新的限制
1) 在小型 BAR 系统上,错误捕获是尽力而为的;如果页面在捕获时无法被 CPU 访问,则内核可以自由跳过尝试捕获它们。
2) 在独立显卡和较新的集成平台上,我们现在拒绝在可恢复的上下文中进行错误捕获。未来,当例如某些东西当前无法被 CPU 访问时,内核可能希望在错误捕获期间进行 blit 操作。