From df9545093448271469088b5ddb4927785220cd8c Mon Sep 17 00:00:00 2001 From: "Hoppe, Mateusz" Date: Wed, 5 Nov 2025 13:55:51 +0100 Subject: [PATCH] feature: multi queue context creation using xe uAPI Signed-off-by: Hoppe, Mateusz --- .../os_interface/linux/xe/ioctl_helper_xe.cpp | 54 +++++++++++++++++-- .../xe/ioctl_helper_xe_debugger_tests.cpp | 2 +- third_party/uapi/drm-next/xe/.version | 1 + third_party/uapi/drm-next/xe/xe_drm.h | 40 ++++++++++++++ 4 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 third_party/uapi/drm-next/xe/.version diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp index e83d8de1edf72..e3fa79adb3054 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp @@ -1899,7 +1899,11 @@ void IoctlHelperXe::setContextProperties(const OsContextLinux &osContext, uint32 auto &ext = *reinterpret_cast *>(extProperties); + xeLog(" -> IoctlHelperXe::%s\n", __FUNCTION__); + if (osContext.isLowPriority()) { + UNRECOVERABLE_IF(extIndexInOut >= maxContextSetProperties); + xeLog(" -> low priority ctx, DRM_XE_EXEC_QUEUE_SET_PROPERTY_PRIORITY value = 0\n"); ext[extIndexInOut].base.name = DRM_XE_EXEC_QUEUE_EXTENSION_SET_PROPERTY; ext[extIndexInOut].property = DRM_XE_EXEC_QUEUE_SET_PROPERTY_PRIORITY; ext[extIndexInOut].value = 0; @@ -1908,20 +1912,60 @@ void IoctlHelperXe::setContextProperties(const OsContextLinux &osContext, uint32 } extIndexInOut++; } -} -bool IoctlHelperXe::isPrimaryContext(const OsContextLinux &osContext, uint32_t deviceIndex) { - return (nullptr == osContext.getPrimaryContext()); + if (osContext.isPartOfContextGroup()) { + UNRECOVERABLE_IF(extIndexInOut >= maxContextSetProperties); + ext[extIndexInOut].base.name = DRM_XE_EXEC_QUEUE_EXTENSION_SET_PROPERTY; + ext[extIndexInOut].property = DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_GROUP; + if (extIndexInOut > 0) { + ext[extIndexInOut - 1].base.next_extension = castToUint64(&ext[extIndexInOut]); + } + + auto currentContextIndex = osContext.getDrmContextIds().size(); + + const bool isPrimary = isPrimaryContext(osContext, deviceIndex); + + if (isPrimary) { + xeLog(" -> multi group create\n"); + ext[extIndexInOut].value = getPrimaryContextProperties(); + } else { + xeLog(" -> multi group secondary queue\n"); + // For MultiTile, match currently created context index with the primary context index + ext[extIndexInOut].value = getPrimaryContextId(osContext, deviceIndex, currentContextIndex); + } + + extIndexInOut++; + if (osContext.isRootDevice()) { + setContextPropertiesForRootDeviceContext(osContext, deviceIndex, extProperties, extIndexInOut); + } + + uint32_t priorityValue = 0; + if (osContext.isHighPriority()) { + priorityValue = 2; + } + + UNRECOVERABLE_IF(extIndexInOut >= maxContextSetProperties); + ext[extIndexInOut - 1].base.next_extension = castToUint64(&ext[extIndexInOut]); + ext[extIndexInOut].base.name = DRM_XE_EXEC_QUEUE_EXTENSION_SET_PROPERTY; + ext[extIndexInOut].property = DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_QUEUE_PRIORITY; + ext[extIndexInOut].value = priorityValue; + xeLog(" -> DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_QUEUE_PRIORITY value = %d\n", ext[extIndexInOut].value); + extIndexInOut++; + } } uint32_t IoctlHelperXe::getPrimaryContextId(const OsContextLinux &osContext, uint32_t deviceIndex, size_t contextIndex) { auto osContextLinuxPrimary = static_cast(osContext.getPrimaryContext()); UNRECOVERABLE_IF(nullptr == osContextLinuxPrimary); + return osContextLinuxPrimary->getDrmContextIds()[contextIndex]; } - uint64_t IoctlHelperXe::getPrimaryContextProperties() const { - return 0; + return DRM_XE_MULTI_GROUP_CREATE; +} + +bool IoctlHelperXe::isPrimaryContext(const OsContextLinux &osContext, uint32_t deviceIndex) { + return (nullptr == osContext.getPrimaryContext()); } unsigned int IoctlHelperXe::getIoctlRequestValue(DrmIoctl ioctlRequest) const { diff --git a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_debugger_tests.cpp b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_debugger_tests.cpp index c74e0292f67b2..9b7c1b893b061 100644 --- a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_debugger_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_debugger_tests.cpp @@ -183,7 +183,7 @@ HWTEST_F(IoctlHelperXeTestFixture, GivenDebuggingEnabledWhenCreateDrmContextFrom EXPECT_EQ(ext.property, static_cast(EuDebugParam::execQueueSetPropertyEuDebug)); EXPECT_EQ(ext.value, static_cast(EuDebugParam::execQueueSetPropertyValueEnable)); - EXPECT_EQ(ext.base.next_extension, 0ULL); + EXPECT_NE(ext.base.next_extension, 0ULL); osContext2.setPrimaryContext(&osContext); drm->receivedContextCreateSetParam = {}; diff --git a/third_party/uapi/drm-next/xe/.version b/third_party/uapi/drm-next/xe/.version new file mode 100644 index 0000000000000..147c0cf01d76c --- /dev/null +++ b/third_party/uapi/drm-next/xe/.version @@ -0,0 +1 @@ +patch: https://patchwork.freedesktop.org/series/156865/ \ No newline at end of file diff --git a/third_party/uapi/drm-next/xe/xe_drm.h b/third_party/uapi/drm-next/xe/xe_drm.h index 5c2d63abf4135..49f5fcdfcb38b 100644 --- a/third_party/uapi/drm-next/xe/xe_drm.h +++ b/third_party/uapi/drm-next/xe/xe_drm.h @@ -106,6 +106,7 @@ extern "C" { #define DRM_XE_OBSERVATION 0x0b #define DRM_XE_MADVISE 0x0c #define DRM_XE_VM_QUERY_MEM_RANGE_ATTRS 0x0d +#define DRM_XE_EXEC_QUEUE_SET_PROPERTY 0x0e /* Must be kept compact -- no holes */ @@ -123,6 +124,7 @@ extern "C" { #define DRM_IOCTL_XE_OBSERVATION DRM_IOW(DRM_COMMAND_BASE + DRM_XE_OBSERVATION, struct drm_xe_observation_param) #define DRM_IOCTL_XE_MADVISE DRM_IOW(DRM_COMMAND_BASE + DRM_XE_MADVISE, struct drm_xe_madvise) #define DRM_IOCTL_XE_VM_QUERY_MEM_RANGE_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_VM_QUERY_MEM_RANGE_ATTRS, struct drm_xe_vm_query_mem_range_attr) +#define DRM_IOCTL_XE_EXEC_QUEUE_SET_PROPERTY DRM_IOW(DRM_COMMAND_BASE + DRM_XE_EXEC_QUEUE_SET_PROPERTY, struct drm_xe_exec_queue_set_property) /** * DOC: Xe IOCTL Extensions @@ -1252,6 +1254,18 @@ struct drm_xe_vm_bind { * Given that going into a power-saving state kills PXP HWDRM sessions, * runtime PM will be blocked while queues of this type are alive. * All PXP queues will be killed if a PXP invalidation event occurs. + * - %DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_GROUP - Create a multi-queue group + * or add secondary queues to a multi-queue group. + * If the extension's 'value' field has %DRM_XE_MULTI_GROUP_CREATE flag set, + * then a new multi-queue group is created with this queue as the primary queue + * (Q0). Otherwise, the queue gets added to the multi-queue group whose primary + * queue id is specified in the 'value' field. + * If the extension's 'value' field has %DRM_XE_MULTI_GROUP_KEEP_ACTIVE flag + * set, then the multi-queue group is kept active after the primary queue is + * destroyed. + * + * - %DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_QUEUE_PRIORITY - Set the queue + * priority within the multi-queue group. * * The example below shows how to use @drm_xe_exec_queue_create to create * a simple exec_queue (no parallel submission) of class @@ -1292,6 +1306,10 @@ struct drm_xe_exec_queue_create { #define DRM_XE_EXEC_QUEUE_SET_PROPERTY_PRIORITY 0 #define DRM_XE_EXEC_QUEUE_SET_PROPERTY_TIMESLICE 1 #define DRM_XE_EXEC_QUEUE_SET_PROPERTY_PXP_TYPE 2 +#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_GROUP 3 +#define DRM_XE_MULTI_GROUP_CREATE (1ull << 63) +#define DRM_XE_MULTI_GROUP_KEEP_ACTIVE (1ull << 62) +#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_QUEUE_PRIORITY 4 /** @extensions: Pointer to the first extension struct, if any */ __u64 extensions; @@ -2273,6 +2291,28 @@ struct drm_xe_vm_query_mem_range_attr { }; +/** + * struct drm_xe_exec_queue_set_property - exec queue set property + * + * Sets execution queue properties dynamically. + */ +struct drm_xe_exec_queue_set_property { + /** @extensions: Pointer to the first extension struct, if any */ + __u64 extensions; + + /** @exec_queue_id: Exec queue ID */ + __u32 exec_queue_id; + + /** @property: property to set */ + __u32 property; + + /** @value: property value */ + __u64 value; + + /** @reserved: Reserved */ + __u64 reserved[2]; +}; + #if defined(__cplusplus) } #endif