diff --git a/opencl/test/unit_test/os_interface/linux/drm_tests.cpp b/opencl/test/unit_test/os_interface/linux/drm_tests.cpp index dfc0f96151..c9905df302 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_tests.cpp @@ -607,6 +607,7 @@ TEST(DrmTest, givenProgramDebuggingAndContextDebugAvailableWhenCreatingContextTh DrmMockNonFailing drmMock(*executionEnvironment->rootDeviceEnvironments[0]); drmMock.contextDebugSupported = true; + drmMock.callBaseCreateDrmContext = false; OsContextLinux osContext(drmMock, 5u, EngineDescriptorHelper::getDefaultDescriptor()); osContext.ensureContextInitialized(); @@ -632,6 +633,37 @@ TEST(DrmTest, givenProgramDebuggingAndContextDebugAvailableWhenCreatingContextFo EXPECT_EQ(static_cast(-1), drmMock.passedContextDebugId); } +TEST(DrmTest, givenNotEnabledDebuggingOrContextDebugUnsupportedWhenCreatingContextThenCooperativeFlagIsNotPassedToCreateDrmContext) { + auto executionEnvironment = std::make_unique(); + executionEnvironment->prepareRootDeviceEnvironments(1); + executionEnvironment->rootDeviceEnvironments[0]->setHwInfo(defaultHwInfo.get()); + executionEnvironment->calculateMaxOsContextCount(); + executionEnvironment->rootDeviceEnvironments[0]->osInterface = std::make_unique(); + + DrmMockNonFailing drmMock(*executionEnvironment->rootDeviceEnvironments[0]); + + drmMock.contextDebugSupported = true; + drmMock.callBaseCreateDrmContext = false; + drmMock.capturedCooperativeContextRequest = true; + + EXPECT_FALSE(executionEnvironment->isDebuggingEnabled()); + + OsContextLinux osContext(drmMock, 5u, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_RCS, EngineUsage::Regular})); + osContext.ensureContextInitialized(); + + EXPECT_FALSE(drmMock.capturedCooperativeContextRequest); + + executionEnvironment->setDebuggingEnabled(); + drmMock.contextDebugSupported = false; + drmMock.callBaseCreateDrmContext = false; + drmMock.capturedCooperativeContextRequest = true; + + OsContextLinux osContext2(drmMock, 5u, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_RCS, EngineUsage::Regular})); + osContext2.ensureContextInitialized(); + + EXPECT_FALSE(drmMock.capturedCooperativeContextRequest); +} + TEST(DrmTest, givenPrintIoctlDebugFlagSetWhenGettingTimestampFrequencyThenCaptureExpectedOutput) { DebugManagerStateRestore restore; DebugManager.flags.PrintIoctlEntries.set(true); diff --git a/shared/source/os_interface/linux/drm_neo.h b/shared/source/os_interface/linux/drm_neo.h index 1aa1c49e64..7ac027d787 100644 --- a/shared/source/os_interface/linux/drm_neo.h +++ b/shared/source/os_interface/linux/drm_neo.h @@ -112,7 +112,7 @@ class Drm : public DriverModel { int queryAdapterBDF(); int createDrmVirtualMemory(uint32_t &drmVmId); void destroyDrmVirtualMemory(uint32_t drmVmId); - uint32_t createDrmContext(uint32_t drmVmId, bool isDirectSubmissionRequested, bool isCooperativeContextRequested); + MOCKABLE_VIRTUAL uint32_t createDrmContext(uint32_t drmVmId, bool isDirectSubmissionRequested, bool isCooperativeContextRequested); void appendDrmContextFlags(drm_i915_gem_context_create_ext &gcc, bool isDirectSubmissionRequested); void destroyDrmContext(uint32_t drmContextId); int queryVmId(uint32_t drmContextId, uint32_t &vmId); diff --git a/shared/source/os_interface/linux/os_context_linux.cpp b/shared/source/os_interface/linux/os_context_linux.cpp index 50b8dad340..91b40ce73b 100644 --- a/shared/source/os_interface/linux/os_context_linux.cpp +++ b/shared/source/os_interface/linux/os_context_linux.cpp @@ -45,19 +45,24 @@ void OsContextLinux::initializeContext() { this->drmVmIds.resize(deviceBitfield.size(), 0); } + const auto numberOfCCS = drm.getRootDeviceEnvironment().getHardwareInfo()->gtSystemInfo.CCSInfo.NumberOfCCSEnabled; + const bool debuggableContext = drm.isContextDebugSupported() && drm.getRootDeviceEnvironment().executionEnvironment.isDebuggingEnabled() && !isInternalEngine(); + const bool debuggableContextCooperative = debuggableContext && numberOfCCS > 0; + for (auto deviceIndex = 0u; deviceIndex < deviceBitfield.size(); deviceIndex++) { if (deviceBitfield.test(deviceIndex)) { auto drmVmId = drm.getVirtualMemoryAddressSpace(deviceIndex); - auto drmContextId = drm.createDrmContext(drmVmId, drm.isVmBindAvailable(), isCooperativeEngine()); + auto drmContextId = drm.createDrmContext(drmVmId, drm.isVmBindAvailable(), isCooperativeEngine() || debuggableContextCooperative); if (drm.areNonPersistentContextsSupported()) { drm.setNonPersistentContext(drmContextId); } if (drm.getRootDeviceEnvironment().executionEnvironment.isDebuggingEnabled()) { drm.setUnrecoverableContext(drmContextId); - if (!isInternalEngine()) { - drm.setContextDebugFlag(drmContextId); - } + } + + if (debuggableContext) { + drm.setContextDebugFlag(drmContextId); } if (drm.isPreemptionSupported() && isLowPriority()) { diff --git a/shared/test/common/libult/linux/drm_mock.h b/shared/test/common/libult/linux/drm_mock.h index cba9a9127a..4526840eaa 100644 --- a/shared/test/common/libult/linux/drm_mock.h +++ b/shared/test/common/libult/linux/drm_mock.h @@ -122,6 +122,15 @@ class DrmMock : public Drm { queryPageFaultSupportCalled = true; } + uint32_t createDrmContext(uint32_t drmVmId, bool isDirectSubmissionRequested, bool isCooperativeContextRequested) override { + capturedCooperativeContextRequest = isCooperativeContextRequested; + if (callBaseCreateDrmContext) { + return Drm::createDrmContext(drmVmId, isDirectSubmissionRequested, isCooperativeContextRequested); + } + + return 0; + } + static const int mockFd = 33; bool failRetTopology = false; @@ -156,6 +165,10 @@ class DrmMock : public Drm { bool disableSomeTopology = false; bool allowDebugAttach = false; bool allowDebugAttachCallBase = false; + bool callBaseCreateDrmContext = true; + + bool capturedCooperativeContextRequest = false; + uint32_t passedContextDebugId = std::numeric_limits::max(); std::vector resetStatsToReturn{}; diff --git a/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp index bba4822043..35eb8bfa92 100644 --- a/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp @@ -6,8 +6,10 @@ */ #include "shared/source/os_interface/linux/ioctl_helper.h" +#include "shared/source/os_interface/linux/os_context_linux.h" #include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/helpers/default_hw_info.h" +#include "shared/test/common/helpers/engine_descriptor_helper.h" #include "shared/test/common/libult/linux/drm_mock.h" #include "shared/test/common/libult/linux/drm_query_mock.h" #include "shared/test/common/mocks/linux/mock_drm_allocation.h" @@ -394,3 +396,27 @@ TEST_F(IoctlHelperPrelimFixture, whenCreateDrmContextExtIsCalledThenIoctlIsCalle } } } + +TEST_F(IoctlHelperPrelimFixture, givenProgramDebuggingAndContextDebugSupportedWhenCreatingContextThenCooperativeFlagIsPassedToCreateDrmContextOnlyIfCCSEnginesArePresent) { + executionEnvironment->setDebuggingEnabled(); + drm->contextDebugSupported = true; + drm->callBaseCreateDrmContext = false; + + executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo()->platform.eProductFamily = defaultHwInfo->platform.eProductFamily; + + OsContextLinux osContext(*drm, 5u, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_RCS, EngineUsage::Regular})); + osContext.ensureContextInitialized(); + + EXPECT_NE(static_cast(-1), drm->passedContextDebugId); + if (executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo()->gtSystemInfo.CCSInfo.NumberOfCCSEnabled > 0) { + EXPECT_TRUE(drm->capturedCooperativeContextRequest); + } else { + EXPECT_FALSE(drm->capturedCooperativeContextRequest); + } + + OsContextLinux osContext2(*drm, 5u, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_RCS, EngineUsage::Cooperative})); + osContext2.ensureContextInitialized(); + + EXPECT_NE(static_cast(-1), drm->passedContextDebugId); + EXPECT_TRUE(drm->capturedCooperativeContextRequest); +} \ No newline at end of file