From 0270cd6a5b0ab770f6e90629dec8452061aa5093 Mon Sep 17 00:00:00 2001 From: Mateusz Jablonski Date: Fri, 15 Mar 2024 13:47:40 +0000 Subject: [PATCH] fix: respect gt id when getting engines for drm context under xe kmd Related-To: NEO-10496 Signed-off-by: Mateusz Jablonski --- shared/source/os_interface/linux/drm_neo.cpp | 1 + .../source/os_interface/linux/drm_wrappers.h | 1 + .../linux/drm_wrappers_checks.cpp | 4 +- .../linux/ioctl_helper_prelim.cpp | 8 +-- .../os_interface/linux/xe/ioctl_helper_xe.cpp | 35 +++++------- .../common/mocks/linux/debug_mock_drm_xe.h | 2 +- .../xe/ioctl_helper_xe_debugger_tests.cpp | 2 +- .../linux/xe/ioctl_helper_xe_tests.cpp | 57 ++++++++++++++++++- .../linux/xe/ioctl_helper_xe_tests.h | 1 + 9 files changed, 79 insertions(+), 32 deletions(-) diff --git a/shared/source/os_interface/linux/drm_neo.cpp b/shared/source/os_interface/linux/drm_neo.cpp index 36ceca0c19..b14ae2ba0b 100644 --- a/shared/source/os_interface/linux/drm_neo.cpp +++ b/shared/source/os_interface/linux/drm_neo.cpp @@ -1147,6 +1147,7 @@ unsigned int Drm::bindDrmContext(uint32_t drmContextId, uint32_t deviceIndex, au param.size = static_cast(ptrDiff(contextEngines.engines + numEnginesInContext, &contextEngines)); param.param = ioctlHelper->getDrmParamValue(DrmParam::contextParamEngines); param.value = castToUint64(&contextEngines); + param.gtId = deviceIndex; auto ioctlValue = ioctlHelper->ioctl(DrmIoctl::gemContextSetparam, ¶m); UNRECOVERABLE_IF(ioctlValue != 0); diff --git a/shared/source/os_interface/linux/drm_wrappers.h b/shared/source/os_interface/linux/drm_wrappers.h index a83eeafbde..2df83d8e82 100644 --- a/shared/source/os_interface/linux/drm_wrappers.h +++ b/shared/source/os_interface/linux/drm_wrappers.h @@ -119,6 +119,7 @@ struct GemContextParam { uint32_t size; uint64_t param; uint64_t value; + uint32_t gtId; }; struct DrmUserExtension { diff --git a/shared/source/os_interface/linux/drm_wrappers_checks.cpp b/shared/source/os_interface/linux/drm_wrappers_checks.cpp index 92bf35fcde..607a859ee9 100644 --- a/shared/source/os_interface/linux/drm_wrappers_checks.cpp +++ b/shared/source/os_interface/linux/drm_wrappers_checks.cpp @@ -85,7 +85,7 @@ static_assert(offsetof(GemSetDomain, handle) == offsetof(drm_i915_gem_set_domain static_assert(offsetof(GemSetDomain, readDomains) == offsetof(drm_i915_gem_set_domain, read_domains)); static_assert(offsetof(GemSetDomain, writeDomain) == offsetof(drm_i915_gem_set_domain, write_domain)); -static_assert(sizeof(GemContextParam) == sizeof(drm_i915_gem_context_param)); +static_assert(sizeof(GemContextParam) >= sizeof(drm_i915_gem_context_param)); static_assert(offsetof(GemContextParam, contextId) == offsetof(drm_i915_gem_context_param, ctx_id)); static_assert(offsetof(GemContextParam, size) == offsetof(drm_i915_gem_context_param, size)); static_assert(offsetof(GemContextParam, param) == offsetof(drm_i915_gem_context_param, param)); @@ -97,7 +97,7 @@ static_assert(offsetof(DrmUserExtension, name) == offsetof(i915_user_extension, static_assert(offsetof(DrmUserExtension, flags) == offsetof(i915_user_extension, flags)); static_assert(offsetof(DrmUserExtension, reserved) == offsetof(i915_user_extension, rsvd)); -static_assert(sizeof(GemContextCreateExtSetParam) == sizeof(drm_i915_gem_context_create_ext_setparam)); +static_assert(sizeof(GemContextCreateExtSetParam) >= sizeof(drm_i915_gem_context_create_ext_setparam)); static_assert(offsetof(GemContextCreateExtSetParam, base) == offsetof(drm_i915_gem_context_create_ext_setparam, base)); static_assert(offsetof(GemContextCreateExtSetParam, param) == offsetof(drm_i915_gem_context_create_ext_setparam, param)); diff --git a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp index e87b6ca8f7..9fdff6530b 100644 --- a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp @@ -807,10 +807,10 @@ int IoctlHelperPrelim20::unregisterUuid(uint32_t handle) { } bool IoctlHelperPrelim20::isContextDebugSupported() { - drm_i915_gem_context_param ctxParam = {}; + GemContextParam ctxParam = {}; ctxParam.size = 0; ctxParam.param = PRELIM_I915_CONTEXT_PARAM_DEBUG_FLAGS; - ctxParam.ctx_id = 0; + ctxParam.contextId = 0; ctxParam.value = 0; const auto retVal = IoctlHelper::ioctl(DrmIoctl::gemContextGetparam, &ctxParam); @@ -818,10 +818,10 @@ bool IoctlHelperPrelim20::isContextDebugSupported() { } int IoctlHelperPrelim20::setContextDebugFlag(uint32_t drmContextId) { - drm_i915_gem_context_param ctxParam = {}; + GemContextParam ctxParam = {}; ctxParam.size = 0; ctxParam.param = PRELIM_I915_CONTEXT_PARAM_DEBUG_FLAGS; - ctxParam.ctx_id = drmContextId; + ctxParam.contextId = drmContextId; ctxParam.value = PRELIM_I915_CONTEXT_PARAM_DEBUG_FLAG_SIP << 32 | PRELIM_I915_CONTEXT_PARAM_DEBUG_FLAG_SIP; return IoctlHelper::ioctl(DrmIoctl::gemContextSetparam, &ctxParam); 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 5d3392f9d2..c893191767 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp @@ -898,6 +898,12 @@ int IoctlHelperXe::getDrmParamValue(DrmParam drmParam) const { return DRM_XE_ENGINE_CLASS_COMPUTE; case DrmParam::engineClassInvalid: return -1; + case DrmParam::execDefault: + return DRM_XE_ENGINE_CLASS_COMPUTE; + case DrmParam::execBlt: + return DRM_XE_ENGINE_CLASS_COPY; + case DrmParam::execRender: + return DRM_XE_ENGINE_CLASS_RENDER; default: return getDrmParamValueBase(drmParam); @@ -1025,12 +1031,13 @@ int IoctlHelperXe::ioctl(DrmIoctl request, void *arg) { contextParamEngine.clear(); if (items < 11) { for (int i = 0; i < items; i++) { - drm_xe_engine_class_instance engine = { - contextEngine->engines[i].engineClass, - contextEngine->engines[i].engineInstance, - 0}; - if (engine.engine_class != 65535) + if (contextEngine->engines[i].engineClass != static_cast(getDrmParamValue(DrmParam::engineClassInvalid))) { + drm_xe_engine_class_instance engine = { + contextEngine->engines[i].engineClass, + contextEngine->engines[i].engineInstance, + static_cast(d->gtId)}; contextParamEngine.push_back(engine); + } } } if (contextParamEngine.size()) @@ -1177,24 +1184,10 @@ int IoctlHelperXe::createDrmContext(Drm &drm, OsContextLinux &osContext, uint32_ uint32_t drmContextId = 0; drm_xe_engine_class_instance *currentEngine = nullptr; std::vector engine; - int requestClass = 0; xeLog("createDrmContext VM=0x%x\n", drmVmId); - auto engineFlag = drm.bindDrmContext(drmContextId, deviceIndex, osContext.getEngineType(), osContext.isEngineInstanced()); - switch (engineFlag) { - case static_cast(DrmParam::execRender): - requestClass = DRM_XE_ENGINE_CLASS_RENDER; - break; - case static_cast(DrmParam::execBlt): - requestClass = DRM_XE_ENGINE_CLASS_COPY; - break; - case static_cast(DrmParam::execDefault): - requestClass = DRM_XE_ENGINE_CLASS_COMPUTE; - break; - default: - xeLog("unexpected engineFlag=0x%x\n", engineFlag); - UNRECOVERABLE_IF(true); - } + auto requestClass = drm.bindDrmContext(drmContextId, deviceIndex, osContext.getEngineType(), osContext.isEngineInstanced()); + size_t n = contextParamEngine.size(); create.vm_id = drmVmId; create.width = 1; diff --git a/shared/test/common/mocks/linux/debug_mock_drm_xe.h b/shared/test/common/mocks/linux/debug_mock_drm_xe.h index 6e801f078d..cbe39fb2dc 100644 --- a/shared/test/common/mocks/linux/debug_mock_drm_xe.h +++ b/shared/test/common/mocks/linux/debug_mock_drm_xe.h @@ -69,7 +69,7 @@ class DrmMockXeDebug : public DrmMockCustom { int errnoRetVal = 0; unsigned int bindDrmContext(uint32_t drmContextId, uint32_t deviceIndex, aub_stream::EngineType engineType, bool engineInstancedDevice) override { - return static_cast(DrmParam::execDefault); + return DRM_XE_ENGINE_CLASS_COMPUTE; } void setPciPath(const char *pciPath) { 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 d4826c6068..4307ebf65c 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 @@ -267,7 +267,7 @@ HWTEST_F(IoctlHelperXeTestFixture, GivenContextCreatedForCopyEngineWhenCreateDrm public: DrmMockXeDebugTest(RootDeviceEnvironment &rootDeviceEnvironment) : DrmMockXeDebug(rootDeviceEnvironment){}; unsigned int bindDrmContext(uint32_t drmContextId, uint32_t deviceIndex, aub_stream::EngineType engineType, bool engineInstancedDevice) override { - return static_cast(DrmParam::execBlt); + return DRM_XE_ENGINE_CLASS_COPY; } }; 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 3b2e3295a7..cfab26472e 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 @@ -321,9 +321,6 @@ TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingAnyMethodThenDummyValueIsRe EXPECT_EQ(0, xeIoctlHelper->setContextDebugFlag(0)); - // Default no translation: - verifyDrmGetParamValue(static_cast(DrmParam::execRender), DrmParam::execRender); - // test exception: verifyDrmGetParamValue(DRM_XE_MEM_REGION_CLASS_VRAM, DrmParam::memoryClassDevice); verifyDrmGetParamValue(DRM_XE_MEM_REGION_CLASS_SYSMEM, DrmParam::memoryClassSystem); verifyDrmGetParamValue(DRM_XE_ENGINE_CLASS_RENDER, DrmParam::engineClassRender); @@ -332,6 +329,9 @@ TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingAnyMethodThenDummyValueIsRe verifyDrmGetParamValue(DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE, DrmParam::engineClassVideoEnhance); verifyDrmGetParamValue(DRM_XE_ENGINE_CLASS_COMPUTE, DrmParam::engineClassCompute); verifyDrmGetParamValue(-1, DrmParam::engineClassInvalid); + verifyDrmGetParamValue(DRM_XE_ENGINE_CLASS_RENDER, DrmParam::execRender); + verifyDrmGetParamValue(DRM_XE_ENGINE_CLASS_COPY, DrmParam::execBlt); + verifyDrmGetParamValue(DRM_XE_ENGINE_CLASS_COMPUTE, DrmParam::execDefault); // Expect stringify verifyDrmParamString("ContextCreateExtSetparam", DrmParam::contextCreateExtSetparam); @@ -1741,6 +1741,57 @@ TEST(IoctlHelperXeTest, whenCallingVmBindThenPatIndexIsSet) { EXPECT_EQ(drm.vmBindInputs[0].bind.pat_index, expectedPatIndex); } +TEST(IoctlHelperXeTest, whenBindingDrmContextWithoutVirtualEnginesThenProperEnginesAreSelected) { + auto executionEnvironment = std::make_unique(); + DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]}; + + drm.ioctlHelper = std::make_unique(drm); + auto ioctlHelper = static_cast(drm.ioctlHelper.get()); + drm.queryEngineInfo(); + + unsigned int expectedValue = DRM_XE_ENGINE_CLASS_COMPUTE; + EXPECT_EQ(expectedValue, drm.bindDrmContext(0, 1, aub_stream::EngineType::ENGINE_CCS, true)); + + EXPECT_EQ(1u, ioctlHelper->contextParamEngine.size()); + auto expectedEngine = drm.getEngineInfo()->getEngineInstance(1, aub_stream::EngineType::ENGINE_CCS); + auto notExpectedEngine = drm.getEngineInfo()->getEngineInstance(0, aub_stream::EngineType::ENGINE_CCS); + EXPECT_NE(expectedEngine->engineInstance, notExpectedEngine->engineInstance); + EXPECT_EQ(expectedEngine->engineInstance, ioctlHelper->contextParamEngine[0].engine_instance); + EXPECT_EQ(expectedEngine->engineClass, ioctlHelper->contextParamEngine[0].engine_class); + EXPECT_EQ(1u, ioctlHelper->contextParamEngine[0].gt_id); +} + +TEST(IoctlHelperXeTest, whenBindingDrmContextWithVirtualEnginesThenProperEnginesAreSelected) { + auto executionEnvironment = std::make_unique(); + DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]}; + + drm.ioctlHelper = std::make_unique(drm); + auto ioctlHelper = static_cast(drm.ioctlHelper.get()); + drm.queryEngineInfo(); + executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo()->gtSystemInfo.CCSInfo.NumberOfCCSEnabled = 2; + + unsigned int expectedValue = DRM_XE_ENGINE_CLASS_COMPUTE; + EXPECT_EQ(expectedValue, drm.bindDrmContext(0, 1, aub_stream::EngineType::ENGINE_CCS, false)); + + EXPECT_EQ(2u, ioctlHelper->contextParamEngine.size()); + { + auto expectedEngine = drm.getEngineInfo()->getEngineInstance(1, aub_stream::EngineType::ENGINE_CCS); + auto notExpectedEngine = drm.getEngineInfo()->getEngineInstance(0, aub_stream::EngineType::ENGINE_CCS); + EXPECT_NE(expectedEngine->engineInstance, notExpectedEngine->engineInstance); + EXPECT_EQ(expectedEngine->engineInstance, ioctlHelper->contextParamEngine[0].engine_instance); + EXPECT_EQ(expectedEngine->engineClass, ioctlHelper->contextParamEngine[0].engine_class); + EXPECT_EQ(1u, ioctlHelper->contextParamEngine[0].gt_id); + } + { + auto expectedEngine = drm.getEngineInfo()->getEngineInstance(1, aub_stream::EngineType::ENGINE_CCS1); + auto notExpectedEngine = drm.getEngineInfo()->getEngineInstance(0, aub_stream::EngineType::ENGINE_CCS1); + EXPECT_NE(expectedEngine->engineInstance, notExpectedEngine->engineInstance); + EXPECT_EQ(expectedEngine->engineInstance, ioctlHelper->contextParamEngine[1].engine_instance); + EXPECT_EQ(expectedEngine->engineClass, ioctlHelper->contextParamEngine[1].engine_class); + EXPECT_EQ(1u, ioctlHelper->contextParamEngine[1].gt_id); + } +} + TEST(IoctlHelperXeTest, whenCallingGetResetStatsThenSuccessIsReturned) { auto executionEnvironment = std::make_unique(); DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]}; 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 6e74fcc1c0..8bd720996f 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 @@ -28,6 +28,7 @@ using namespace NEO; struct MockIoctlHelperXe : IoctlHelperXe { using IoctlHelperXe::bindInfo; + using IoctlHelperXe::contextParamEngine; using IoctlHelperXe::debugMetadata; using IoctlHelperXe::defaultEngine; using IoctlHelperXe::getFdFromVmExport;