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 a8773d9180..1368c81f2f 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp @@ -137,9 +137,13 @@ bool IoctlHelperXe::initialize() { xeLog("DRM_XE_QUERY_CONFIG_VA_BITS\t\t%#llx\n", config->info[DRM_XE_QUERY_CONFIG_VA_BITS]); + xeLog("DRM_XE_QUERY_CONFIG_MAX_EXEC_QUEUE_PRIORITY\t\t%#llx\n", + config->info[DRM_XE_QUERY_CONFIG_MAX_EXEC_QUEUE_PRIORITY]); + chipsetId = config->info[DRM_XE_QUERY_CONFIG_REV_AND_DEVICE_ID] & 0xffff; revId = static_cast((config->info[DRM_XE_QUERY_CONFIG_REV_AND_DEVICE_ID] >> 16) & 0xff); hasVram = config->info[DRM_XE_QUERY_CONFIG_FLAGS] & DRM_XE_QUERY_CONFIG_FLAG_HAS_VRAM ? 1 : 0; + maxExecQueuePriority = config->info[DRM_XE_QUERY_CONFIG_MAX_EXEC_QUEUE_PRIORITY] & 0xffff; memset(&queryConfig, 0, sizeof(queryConfig)); queryConfig.query = DRM_XE_DEVICE_QUERY_HWCONFIG; diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe.h b/shared/source/os_interface/linux/xe/ioctl_helper_xe.h index 305ed670b5..16af11fe16 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.h +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.h @@ -178,6 +178,7 @@ class IoctlHelperXe : public IoctlHelper { int revId = 0; int defaultAlignment = 0; int hasVram = 0; + int maxExecQueuePriority = 0; uint32_t xeVmId = 0; int xeFileHandle = 0; std::mutex xeLock; diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe_context.cpp b/shared/source/os_interface/linux/xe/ioctl_helper_xe_context.cpp index 8f08b98a54..ccd3774c6a 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe_context.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe_context.cpp @@ -5,12 +5,26 @@ * */ +#include "shared/source/helpers/ptr_math.h" +#include "shared/source/os_interface/linux/os_context_linux.h" #include "shared/source/os_interface/linux/xe/ioctl_helper_xe.h" #include "drm/xe_drm.h" namespace NEO { void IoctlHelperXe::setContextProperties(const OsContextLinux &osContext, void *extProperties, uint32_t &extIndexInOut) { + + auto &ext = *reinterpret_cast *>(extProperties); + + if (osContext.isLowPriority()) { + 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; + if (extIndexInOut > 0) { + ext[extIndexInOut - 1].base.next_extension = castToUint64(&ext[extIndexInOut]); + } + extIndexInOut++; + } } } // namespace NEO \ No newline at end of file diff --git a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp index 7f07101280..5adbbce278 100644 --- a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp @@ -7,6 +7,9 @@ #include "shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.h" +#include "shared/source/os_interface/linux/os_context_linux.h" +#include "shared/test/common/helpers/engine_descriptor_helper.h" + using namespace NEO; TEST(IoctlHelperXeTest, givenXeDrmVersionsWhenGettingIoctlHelperThenValidIoctlHelperIsReturned) { @@ -1930,3 +1933,36 @@ TEST(IoctlHelperXeTest, givenMultipleBindInfosWhenVmBindIsCalledThenProperHandle ioctlHelper->bindInfo.clear(); } + +TEST(IoctlHelperXeTest, givenLowPriorityContextWhenSettingPropertiesThenCorrectIndexIsUsedAndReturend) { + auto executionEnvironment = std::make_unique(); + DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]}; + auto xeHelper = std::make_unique(drm); + auto mockXeHelper = xeHelper.get(); + drm.ioctlHelper = std::move(xeHelper); + + OsContextLinux osContext(drm, 0, 5u, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_CCS, EngineUsage::lowPriority})); + std::array extProperties{}; + uint32_t extIndex = 1; + mockXeHelper->setContextProperties(osContext, &extProperties, extIndex); + + EXPECT_EQ(reinterpret_cast(&extProperties[1]), extProperties[0].base.next_extension); + EXPECT_EQ(0u, extProperties[1].base.next_extension); + EXPECT_EQ(2u, extIndex); +} + +TEST(IoctlHelperXeTest, givenLowPriorityContextWhenCreatingDrmContextThenExtPropertyIsSetCorrectly) { + auto executionEnvironment = std::make_unique(); + DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]}; + + drm.ioctlHelper = std::make_unique(drm); + drm.queryEngineInfo(); + executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo()->gtSystemInfo.CCSInfo.NumberOfCCSEnabled = 1; + + OsContextLinux osContext(drm, 0, 5u, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_CCS, EngineUsage::lowPriority})); + osContext.ensureContextInitialized(); + + ASSERT_LE(1u, drm.execQueueProperties.size()); + EXPECT_EQ(static_cast(DRM_XE_EXEC_QUEUE_SET_PROPERTY_PRIORITY), drm.execQueueProperties[0].property); + EXPECT_EQ(0u, drm.execQueueProperties[0].value); +} diff --git a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.h b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.h index e49db4ca47..7aa869e61d 100644 --- a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.h +++ b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.h @@ -33,6 +33,8 @@ struct MockIoctlHelperXe : IoctlHelperXe { using IoctlHelperXe::defaultEngine; using IoctlHelperXe::getFdFromVmExport; using IoctlHelperXe::IoctlHelperXe; + using IoctlHelperXe::maxContextSetProperties; + using IoctlHelperXe::setContextProperties; using IoctlHelperXe::setDefaultEngine; using IoctlHelperXe::UserFenceExtension; using IoctlHelperXe::xeGetBindFlagsName; @@ -252,6 +254,27 @@ class DrmMockXe : public DrmMockCustom { waitUserFenceInputs.push_back(*waitUserFenceInput); } break; + case DrmIoctl::gemContextCreateExt: { + auto queueCreate = static_cast(arg); + + auto extension = queueCreate->extensions; + while (extension) { + auto ext = reinterpret_cast(extension); + if (ext->name == DRM_XE_EXEC_QUEUE_EXTENSION_SET_PROPERTY) { + auto setProperty = reinterpret_cast(ext); + execQueueProperties.push_back(*setProperty); + } + extension = ext->next_extension; + } + queueCreate->exec_queue_id = mockExecQueueId; + ret = 0; + } break; + case DrmIoctl::gemContextDestroy: { + auto queueDestroy = static_cast(arg); + if (queueDestroy->exec_queue_id == mockExecQueueId) { + ret = 0; + } + } break; case DrmIoctl::gemContextSetparam: case DrmIoctl::gemContextGetparam: @@ -290,6 +313,8 @@ class DrmMockXe : public DrmMockCustom { const uint16_t devId = 0xabc; uint64_t queryConfig[6]{}; // 1 qword for num params and 1 qwords per param + static constexpr uint32_t mockExecQueueId = 1234; + static_assert(sizeof(drm_xe_engine) == 4 * sizeof(uint64_t), ""); uint64_t queryEngines[45]{}; // 1 qword for num engines and 4 qwords per engine static_assert(sizeof(drm_xe_mem_region) == 11 * sizeof(uint64_t), ""); @@ -302,6 +327,8 @@ class DrmMockXe : public DrmMockCustom { StackVec waitUserFenceInputs; StackVec vmBindInputs; StackVec syncInputs; + StackVec execQueueProperties; + int waitUserFenceReturn = 0; uint32_t createParamsFlags = 0u; uint16_t createParamsCpuCaching = 0u;