performance: add low latency hint for i915

i915 has provided the low latency hint interface, it helps
improve the performance for light workload a lot.

Related-To: NEO-14250

Signed-off-by: Chuansheng Liu <chuansheng.liu@intel.com>
This commit is contained in:
Chuansheng Liu 2025-02-26 07:46:54 +00:00 committed by Compute-Runtime-Automation
parent 7d851dda87
commit 1876a43024
8 changed files with 56 additions and 3 deletions

View File

@ -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<uint64_t>(&extSetparamLowLatency.base);
ioctlHelper->fillExtSetparamLowLatency(extSetparamLowLatency);
}
gcc.extensions = reinterpret_cast<uint64_t>(&extSetparam);
gcc.flags |= ioctlHelper->getDrmParamValue(DrmParam::contextCreateFlagsUseExtensions);
}

View File

@ -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<MemoryRegion> translateToMemoryRegions(const std::vector<uint64_t> &regionInfo);

View File

@ -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 = &param;
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();

View File

@ -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<GemContextCreateExtSetParam *>(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<GemContextParam *>(receivedContextCreateSetParam.base.nextExtension + offset);
if (ext->param == I915_CONTEXT_PARAM_LOW_LATENCY) {
this->lowLatencyHintRequested = true;
}
}
receivedContextParamRequest = *reinterpret_cast<GemContextParam *>(&receivedContextCreateSetParam.param);
if (receivedContextCreateSetParam.param.param == I915_CONTEXT_PARAM_VM) {
this->requestSetVmId = receivedContextParamRequest.value;

View File

@ -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);

View File

@ -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) {

View File

@ -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);
}
}
}

View File

@ -2527,6 +2527,13 @@ TEST_F(IoctlHelperXeTest, givenXeIoctlHelperWhenIsTimestampsRefreshEnabledCalled
EXPECT_TRUE(xeIoctlHelper->isTimestampsRefreshEnabled());
}
TEST_F(IoctlHelperXeTest, givenXeIoctlHelperWhenHasContextFreqHintCalledThenReturnFalse) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
auto xeIoctlHelper = std::make_unique<IoctlHelperXe>(drm);
EXPECT_FALSE(xeIoctlHelper->hasContextFreqHint());
}
TEST_F(IoctlHelperXeTest, whenIoctlFailsOnQueryConfigSizeThenQueryDeviceIdAndRevisionFails) {
MockExecutionEnvironment executionEnvironment{};
std::unique_ptr<Drm> drm{Drm::create(std::make_unique<HwDeviceIdDrm>(0, ""), *executionEnvironment.rootDeviceEnvironments[0])};