diff --git a/shared/source/os_interface/linux/drm_neo.cpp b/shared/source/os_interface/linux/drm_neo.cpp index f5b96b6540..33082e70e6 100644 --- a/shared/source/os_interface/linux/drm_neo.cpp +++ b/shared/source/os_interface/linux/drm_neo.cpp @@ -374,11 +374,15 @@ int Drm::createDrmContext(uint32_t drmVmId, bool isDirectSubmissionRequested, bo } GemContextCreateExtSetParam extSetparam = {}; - + GemContextCreateExtSetParam extSetparamLowLatency = {}; if (drmVmId > 0) { extSetparam.base.name = ioctlHelper->getDrmParamValue(DrmParam::contextCreateExtSetparam); extSetparam.param.param = ioctlHelper->getDrmParamValue(DrmParam::contextParamVm); extSetparam.param.value = drmVmId; + if (ioctlHelper->hasContextFreqHint()) { + extSetparam.base.nextExtension = reinterpret_cast(&extSetparamLowLatency.base); + ioctlHelper->fillExtSetparamLowLatency(extSetparamLowLatency); + } gcc.extensions = reinterpret_cast(&extSetparam); gcc.flags |= ioctlHelper->getDrmParamValue(DrmParam::contextCreateFlagsUseExtensions); } diff --git a/shared/source/os_interface/linux/ioctl_helper.h b/shared/source/os_interface/linux/ioctl_helper.h index 9139d661d8..b913dad2f4 100644 --- a/shared/source/os_interface/linux/ioctl_helper.h +++ b/shared/source/os_interface/linux/ioctl_helper.h @@ -238,6 +238,8 @@ class IoctlHelper { virtual uint32_t getNumProcesses() const { return 1; } virtual bool makeResidentBeforeLockNeeded() const { return false; } + virtual bool hasContextFreqHint() { return false; } + virtual void fillExtSetparamLowLatency(GemContextCreateExtSetParam &extSetparam) { return; } protected: Drm &drm; @@ -274,6 +276,8 @@ class IoctlHelperI915 : public IoctlHelper { bool setGpuCpuTimes(TimeStampData *pGpuCpuTime, OSTime *osTime) override; void insertEngineToContextParams(ContextParamEngines<> &contextParamEngines, uint32_t engineId, const EngineClassInstance *engineClassInstance, uint32_t tileId, bool hasVirtualEngines) override; int getTileIdFromGtId(int gtId) const override { return -1; } + bool hasContextFreqHint() override; + void fillExtSetparamLowLatency(GemContextCreateExtSetParam &extSetparam) override; protected: virtual std::vector translateToMemoryRegions(const std::vector ®ionInfo); diff --git a/shared/source/os_interface/linux/ioctl_helper_i915.cpp b/shared/source/os_interface/linux/ioctl_helper_i915.cpp index 91ee74d99a..5c53ed0894 100644 --- a/shared/source/os_interface/linux/ioctl_helper_i915.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_i915.cpp @@ -678,6 +678,28 @@ bool IoctlHelperI915::isPreemptionSupported() { return retVal == 0 && (schedulerCap & I915_SCHEDULER_CAP_PREEMPTION); } +bool IoctlHelperI915::hasContextFreqHint() { + int param{}; + GetParam getParam{}; + getParam.param = I915_PARAM_HAS_CONTEXT_FREQ_HINT; + getParam.value = ¶m; + + int retVal = ioctl(DrmIoctl::getparam, &getParam); + if (debugManager.flags.PrintIoctlEntries.get()) { + printf("DRM_IOCTL_I915_GETPARAM: param: I915_PARAM_HAS_CONTEXT_FREQ_HINT, output value: %d, retCode:% d\n", + *getParam.value, + retVal); + } + return retVal == 0 && (param == 1); +} + +void IoctlHelperI915::fillExtSetparamLowLatency(GemContextCreateExtSetParam &extSetparam) { + extSetparam.base.name = getDrmParamValue(DrmParam::contextCreateExtSetparam); + extSetparam.param.param = I915_CONTEXT_PARAM_LOW_LATENCY; + extSetparam.param.value = 1; + return; +} + bool IoctlHelperI915::queryDeviceIdAndRevision(Drm &drm) { HardwareInfo *hwInfo = drm.getRootDeviceEnvironment().getMutableHardwareInfo(); diff --git a/shared/test/common/libult/linux/drm_mock.cpp b/shared/test/common/libult/linux/drm_mock.cpp index 439b44091c..b6298b528c 100644 --- a/shared/test/common/libult/linux/drm_mock.cpp +++ b/shared/test/common/libult/linux/drm_mock.cpp @@ -114,6 +114,10 @@ int DrmMock::ioctl(DrmIoctl request, void *arg) { *gp->value = this->storedOaTimestampFrequency; return this->storedRetVal; } + if (gp->param == I915_PARAM_HAS_CONTEXT_FREQ_HINT) { + *gp->value = this->storedRetValForHasContextFreqHint; + return this->storedRetVal; + } } if ((request == DrmIoctl::gemContextCreateExt) && (arg != nullptr)) { @@ -127,6 +131,13 @@ int DrmMock::ioctl(DrmIoctl request, void *arg) { receivedContextCreateSetParam = *reinterpret_cast(create->extensions); if (receivedContextCreateSetParam.base.name == I915_CONTEXT_CREATE_EXT_SETPARAM) { receivedContextParamRequestCount++; + if (receivedContextCreateSetParam.base.nextExtension != 0) { + auto offset = offsetof(GemContextCreateExtSetParam, param); + auto ext = reinterpret_cast(receivedContextCreateSetParam.base.nextExtension + offset); + if (ext->param == I915_CONTEXT_PARAM_LOW_LATENCY) { + this->lowLatencyHintRequested = true; + } + } receivedContextParamRequest = *reinterpret_cast(&receivedContextCreateSetParam.param); if (receivedContextCreateSetParam.param.param == I915_CONTEXT_PARAM_VM) { this->requestSetVmId = receivedContextParamRequest.value; diff --git a/shared/test/common/libult/linux/drm_mock.h b/shared/test/common/libult/linux/drm_mock.h index 12a36a1e99..527c04fa57 100644 --- a/shared/test/common/libult/linux/drm_mock.h +++ b/shared/test/common/libult/linux/drm_mock.h @@ -223,6 +223,7 @@ class DrmMock : public Drm { int storedRetValForVmId = 1; int storedCsTimestampFrequency = 1000; int storedOaTimestampFrequency = 123456; + int storedRetValForHasContextFreqHint = 1; uint32_t mockProcessCount = 1; bool disableSomeTopology = false; bool allowDebugAttach = false; @@ -301,6 +302,7 @@ class DrmMock : public Drm { bool expectIoctlCallsOnDestruction = false; uint32_t expectedIoctlCallsOnDestruction = 0u; + bool lowLatencyHintRequested = false; virtual int handleRemainingRequests(DrmIoctl request, void *arg); diff --git a/shared/test/unit_test/os_interface/linux/drm_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_tests.cpp index e6804d461c..5fd6b03a3a 100644 --- a/shared/test/unit_test/os_interface/linux/drm_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_tests.cpp @@ -384,6 +384,9 @@ TEST(DrmTest, GivenDrmWhenAskedForContextThatIsSuccessThenTrueIsReturned) { DrmMock *pDrm = new DrmMock(*executionEnvironment->rootDeviceEnvironments[0]); pDrm->storedRetVal = 0; EXPECT_EQ(0, pDrm->createDrmContext(1, false, false)); + if (pDrm->ioctlHelper->hasContextFreqHint()) { + EXPECT_EQ(1u, pDrm->lowLatencyHintRequested); + } delete pDrm; } @@ -685,7 +688,7 @@ TEST(DrmTest, givenPerContextVMRequiredWhenCreatingOsContextsThenExplicitVmIsCre EXPECT_EQ(drmMock.latestCreatedVmId, drmVmIds[0]); EXPECT_EQ(1, drmMock.createDrmVmCalled); - EXPECT_EQ(0, drmMock.ioctlCount.contextGetParam); + EXPECT_EQ(1, drmMock.ioctlCount.contextGetParam); } TEST(DrmTest, givenPerContextVMRequiredWhenVmIdCreationFailsThenQueryVmIsCalled) { 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 aea3b42716..70e3bc7f5a 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 @@ -840,7 +840,7 @@ TEST_F(IoctlHelperPrelimFixture, whenCreateDrmContextIsCalledThenIoctlIsCalledOn drm->ioctlCallsCount = 0u; drm->createDrmContext(vmId, isDirectSubmissionRequested, isCooperativeContextRequested); - EXPECT_EQ(1u, drm->ioctlCallsCount); + EXPECT_EQ(vmId > 0 ? 2u : 1u, drm->ioctlCallsCount); } } } 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 21265b5f00..2d419cfea8 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 @@ -2527,6 +2527,13 @@ TEST_F(IoctlHelperXeTest, givenXeIoctlHelperWhenIsTimestampsRefreshEnabledCalled EXPECT_TRUE(xeIoctlHelper->isTimestampsRefreshEnabled()); } +TEST_F(IoctlHelperXeTest, givenXeIoctlHelperWhenHasContextFreqHintCalledThenReturnFalse) { + auto executionEnvironment = std::make_unique(); + DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; + auto xeIoctlHelper = std::make_unique(drm); + EXPECT_FALSE(xeIoctlHelper->hasContextFreqHint()); +} + TEST_F(IoctlHelperXeTest, whenIoctlFailsOnQueryConfigSizeThenQueryDeviceIdAndRevisionFails) { MockExecutionEnvironment executionEnvironment{}; std::unique_ptr drm{Drm::create(std::make_unique(0, ""), *executionEnvironment.rootDeviceEnvironments[0])};