Skip to content

Commit dc4e64e

Browse files
committed
feature: Implement wa uapi with i915
Related-To: HSD-22013059131 Signed-off-by: Maciej Plewka <[email protected]>
1 parent 7a9b77b commit dc4e64e

30 files changed

Lines changed: 274 additions & 9 deletions

shared/source/os_interface/linux/drm_neo.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "shared/source/os_interface/os_environment.h"
4848
#include "shared/source/os_interface/os_interface.h"
4949
#include "shared/source/os_interface/product_helper.h"
50+
#include "shared/source/release_helper/release_helper.h"
5051
#include "shared/source/utilities/api_intercept.h"
5152
#include "shared/source/utilities/cpu_info.h"
5253
#include "shared/source/utilities/directory.h"
@@ -406,13 +407,23 @@ int Drm::createDrmContext(uint32_t drmVmId, bool isDirectSubmissionRequested, bo
406407

407408
GemContextCreateExtSetParam extSetparam = {};
408409
GemContextCreateExtSetParam extSetparamLowLatency = {};
410+
GemContextCreateExtSetParam extSetparamSlmLimit = {};
411+
GemContextCreateExtSetParam *slmLimitPrev = nullptr;
412+
auto last = &extSetparam;
409413
if (drmVmId > 0) {
410414
extSetparam.base.name = ioctlHelper->getDrmParamValue(DrmParam::contextCreateExtSetparam);
411415
extSetparam.param.param = ioctlHelper->getDrmParamValue(DrmParam::contextParamVm);
412416
extSetparam.param.value = drmVmId;
413417
if (ioctlHelper->hasContextFreqHint()) {
414-
extSetparam.base.nextExtension = reinterpret_cast<uint64_t>(&extSetparamLowLatency.base);
418+
last->base.nextExtension = reinterpret_cast<uint64_t>(&extSetparamLowLatency.base);
415419
ioctlHelper->fillExtSetparamLowLatency(extSetparamLowLatency);
420+
last = &extSetparamLowLatency;
421+
}
422+
auto releaseHelper = rootDeviceEnvironment.getReleaseHelper();
423+
if (releaseHelper && releaseHelper->isSlmLimitationTo96KNeeded()) {
424+
slmLimitPrev = last;
425+
last->base.nextExtension = reinterpret_cast<uint64_t>(&extSetparamSlmLimit.base);
426+
ioctlHelper->setSlmLimitTo96KContextParam(extSetparamSlmLimit);
416427
}
417428
gcc.extensions = reinterpret_cast<uint64_t>(&extSetparam);
418429
gcc.flags |= ioctlHelper->getDrmParamValue(DrmParam::contextCreateFlagsUseExtensions);
@@ -430,6 +441,11 @@ int Drm::createDrmContext(uint32_t drmVmId, bool isDirectSubmissionRequested, bo
430441
}
431442
auto ioctlResult = ioctlHelper->ioctl(DrmIoctl::gemContextCreateExt, &gcc);
432443

444+
if (ioctlResult < 0 && slmLimitPrev != nullptr) {
445+
slmLimitPrev->base.nextExtension = extSetparamSlmLimit.base.nextExtension;
446+
ioctlResult = ioctlHelper->ioctl(DrmIoctl::gemContextCreateExt, &gcc);
447+
}
448+
433449
if (ioctlResult < 0) {
434450
PRINT_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, "%s", "WARNING: GemContextCreateExt ioctl failed. Not exposing this root device\n");
435451
return ioctlResult;

shared/source/os_interface/linux/ioctl_helper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ class IoctlHelper {
259259
virtual bool makeResidentBeforeLockNeeded() const { return false; }
260260
virtual bool hasContextFreqHint() { return false; }
261261
virtual void fillExtSetparamLowLatency(GemContextCreateExtSetParam &extSetparam) { return; }
262+
virtual void setSlmLimitTo96KContextParam(GemContextCreateExtSetParam &extSetparam) { return; }
262263
virtual bool isSmallBarConfigAllowed() const = 0;
263264
virtual bool overrideMaxSlicesSupported() const { return false; }
264265
virtual bool is2MBSizeAlignmentRequired(AllocationType allocationType) const { return false; }
@@ -310,6 +311,7 @@ class IoctlHelperI915 : public IoctlHelper {
310311
uint32_t getGtIdFromTileId(uint32_t tileId, uint16_t engineClass) const override { return tileId; }
311312
bool hasContextFreqHint() override;
312313
void fillExtSetparamLowLatency(GemContextCreateExtSetParam &extSetparam) override;
314+
void setSlmLimitTo96KContextParam(GemContextCreateExtSetParam &extSetparam) override;
313315
bool isSmallBarConfigAllowed() const override { return true; }
314316
bool retrieveMmapOffsetForBufferObject(BufferObject &bo, uint64_t flags, uint64_t &offset) override;
315317
bool overrideMaxSlicesSupported() const override { return true; }

shared/source/os_interface/linux/ioctl_helper_i915.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,13 @@ void IoctlHelperI915::fillExtSetparamLowLatency(GemContextCreateExtSetParam &ext
780780
return;
781781
}
782782

783+
void IoctlHelperI915::setSlmLimitTo96KContextParam(GemContextCreateExtSetParam &extSetparam) {
784+
extSetparam.base.name = getDrmParamValueBase(DrmParam::contextCreateExtSetparam);
785+
extSetparam.param.param = I915_CONTEXT_PARAM_WA_22013059131;
786+
extSetparam.param.value = 1;
787+
return;
788+
}
789+
783790
bool IoctlHelperI915::queryDeviceIdAndRevision(Drm &drm) {
784791

785792
HardwareInfo *hwInfo = drm.getRootDeviceEnvironment().getMutableHardwareInfo();

shared/source/release_helper/release_helper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class ReleaseHelper {
7474
virtual bool isStateCacheInvalidationWaRequired() const = 0;
7575
virtual bool isStateCacheInvalidationNoCsStallRequired() const = 0;
7676
virtual bool isAvailableSemaphore64() const = 0;
77+
virtual bool isSlmLimitationTo96KNeeded() const = 0;
7778
virtual bool isLatePreemptionStartSupportedHelper() const = 0;
7879

7980
protected:
@@ -126,6 +127,7 @@ class ReleaseHelperHw : public ReleaseHelper {
126127
bool isStateCacheInvalidationWaRequired() const override;
127128
bool isStateCacheInvalidationNoCsStallRequired() const override;
128129
bool isAvailableSemaphore64() const override;
130+
bool isSlmLimitationTo96KNeeded() const override;
129131
bool isLatePreemptionStartSupportedHelper() const override;
130132

131133
protected:

shared/source/release_helper/release_helper_1256.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,13 @@ bool ReleaseHelperHw<release>::isDummyBlitWaRequired() const {
1919
return true;
2020
}
2121

22+
template <>
23+
bool ReleaseHelperHw<release>::isSlmLimitationTo96KNeeded() const {
24+
return true;
25+
}
26+
2227
} // namespace NEO
2328
#include "shared/source/release_helper/release_helper_common_xe_hpg.inl"
24-
#include "shared/source/release_helper/release_helper_preferred_slm_xe_hpg_96k.inl"
29+
#include "shared/source/release_helper/release_helper_preferred_slm_xe_hpg_g11.inl"
2530

2631
template class NEO::ReleaseHelperHw<NEO::release>;

shared/source/release_helper/release_helper_base.inl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,11 @@ bool ReleaseHelperHw<releaseType>::isAvailableSemaphore64() const {
210210
return false;
211211
}
212212

213+
template <ReleaseType releaseType>
214+
bool ReleaseHelperHw<releaseType>::isSlmLimitationTo96KNeeded() const {
215+
return false;
216+
}
217+
213218
template <ReleaseType releaseType>
214219
bool ReleaseHelperHw<releaseType>::isLatePreemptionStartSupportedHelper() const {
215220
return false;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (C) 2026 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
namespace NEO {
9+
template <>
10+
const SizeToPreferredSlmValueArray &ReleaseHelperHw<release>::getSizeToPreferredSlmValue() const {
11+
using PREFERRED_SLM_ALLOCATION_SIZE = typename XeHpgCoreFamily::INTERFACE_DESCRIPTOR_DATA::PREFERRED_SLM_ALLOCATION_SIZE;
12+
static const SizeToPreferredSlmValueArray sizeToPreferredSlmValue96K = {{
13+
{0, PREFERRED_SLM_ALLOCATION_SIZE::PREFERRED_SLM_ALLOCATION_SIZE_0KB},
14+
{16 * MemoryConstants::kiloByte, PREFERRED_SLM_ALLOCATION_SIZE::PREFERRED_SLM_ALLOCATION_SIZE_16KB},
15+
{32 * MemoryConstants::kiloByte, PREFERRED_SLM_ALLOCATION_SIZE::PREFERRED_SLM_ALLOCATION_SIZE_32KB},
16+
{64 * MemoryConstants::kiloByte, PREFERRED_SLM_ALLOCATION_SIZE::PREFERRED_SLM_ALLOCATION_SIZE_64KB},
17+
{std::numeric_limits<uint32_t>::max(), PREFERRED_SLM_ALLOCATION_SIZE::PREFERRED_SLM_ALLOCATION_SIZE_96KB},
18+
}};
19+
static const SizeToPreferredSlmValueArray sizeToPreferredSlmValue128K = {{
20+
{0, PREFERRED_SLM_ALLOCATION_SIZE::PREFERRED_SLM_ALLOCATION_SIZE_0KB},
21+
{16 * MemoryConstants::kiloByte, PREFERRED_SLM_ALLOCATION_SIZE::PREFERRED_SLM_ALLOCATION_SIZE_16KB},
22+
{32 * MemoryConstants::kiloByte, PREFERRED_SLM_ALLOCATION_SIZE::PREFERRED_SLM_ALLOCATION_SIZE_32KB},
23+
{64 * MemoryConstants::kiloByte, PREFERRED_SLM_ALLOCATION_SIZE::PREFERRED_SLM_ALLOCATION_SIZE_64KB},
24+
{96 * MemoryConstants::kiloByte, PREFERRED_SLM_ALLOCATION_SIZE::PREFERRED_SLM_ALLOCATION_SIZE_96KB},
25+
{std::numeric_limits<uint32_t>::max(), PREFERRED_SLM_ALLOCATION_SIZE::PREFERRED_SLM_ALLOCATION_SIZE_128KB},
26+
}};
27+
return isSlmLimitationTo96KNeeded() ? sizeToPreferredSlmValue96K : sizeToPreferredSlmValue128K;
28+
}
29+
} // namespace NEO

shared/test/common/mocks/mock_release_helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class MockReleaseHelper : public ReleaseHelper {
3636
ADDMETHOD_CONST_NOBASE(getStackSizePerRay, uint32_t, {}, ());
3737
ADDMETHOD_CONST_NOBASE(isLocalOnlyAllowed, bool, {}, ());
3838
ADDMETHOD_CONST_NOBASE(isDummyBlitWaRequired, bool, false, ());
39+
ADDMETHOD_CONST_NOBASE(isSlmLimitationTo96KNeeded, bool, false, ());
3940
ADDMETHOD_CONST_NOBASE(isNumRtStacksPerDssFixedValue, bool, true, ());
4041
ADDMETHOD_CONST_NOBASE(isBlitImageAllowedForDepthFormat, bool, true, ());
4142
ADDMETHOD_CONST_NOBASE(getFtrXe2Compression, bool, false, ());

shared/test/unit_test/os_interface/linux/drm_tests.cpp

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "shared/test/common/mocks/linux/mock_os_context_linux.h"
3434
#include "shared/test/common/mocks/mock_execution_environment.h"
3535
#include "shared/test/common/mocks/mock_product_helper.h"
36+
#include "shared/test/common/mocks/mock_release_helper.h"
3637
#include "shared/test/common/os_interface/linux/drm_mock_memory_info.h"
3738
#include "shared/test/common/os_interface/linux/sys_calls_linux_ult.h"
3839
#include "shared/test/common/test_macros/hw_test.h"
@@ -2949,3 +2950,113 @@ TEST(DrmTest, givenSetupHardwareInfoWhenTopologyDataHasRegionCountThenFeatureTab
29492950

29502951
EXPECT_EQ(2u, hwInfo->featureTable.regionCount);
29512952
}
2953+
2954+
TEST(DrmTest, givenContextCreateFailsWhenSlmLimitExtensionIsPresentThenRetryWithoutIt) {
2955+
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
2956+
2957+
class DrmMockRetryContext : public DrmMock {
2958+
public:
2959+
using DrmMock::DrmMock;
2960+
int contextCreateCallCount = 0;
2961+
int failUntilCallCount = 0;
2962+
2963+
int ioctl(DrmIoctl request, void *arg) override {
2964+
if (request == DrmIoctl::gemContextCreateExt) {
2965+
contextCreateCallCount++;
2966+
if (contextCreateCallCount <= failUntilCallCount) {
2967+
return -1;
2968+
}
2969+
}
2970+
return DrmMock::ioctl(request, arg);
2971+
}
2972+
};
2973+
2974+
auto mockReleaseHelper = std::make_unique<MockReleaseHelper>();
2975+
mockReleaseHelper->isSlmLimitationTo96KNeededResult = true;
2976+
2977+
DrmMockRetryContext drm(*executionEnvironment->rootDeviceEnvironments[0]);
2978+
executionEnvironment->rootDeviceEnvironments[0]->releaseHelper = std::move(mockReleaseHelper);
2979+
2980+
// First call fails with SlmLimit, retry without SlmLimit succeeds
2981+
drm.failUntilCallCount = 1;
2982+
auto result = drm.createDrmContext(1, false, false);
2983+
EXPECT_GE(result, 0);
2984+
EXPECT_EQ(2, drm.contextCreateCallCount);
2985+
}
2986+
2987+
TEST(DrmTest, givenContextCreateFailsWithAndWithoutSlmLimitThenReturnsError) {
2988+
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
2989+
2990+
class DrmMockAlwaysFail : public DrmMock {
2991+
public:
2992+
using DrmMock::DrmMock;
2993+
int contextCreateCallCount = 0;
2994+
2995+
int ioctl(DrmIoctl request, void *arg) override {
2996+
if (request == DrmIoctl::gemContextCreateExt) {
2997+
contextCreateCallCount++;
2998+
return -1;
2999+
}
3000+
return DrmMock::ioctl(request, arg);
3001+
}
3002+
};
3003+
3004+
auto mockReleaseHelper = std::make_unique<MockReleaseHelper>();
3005+
mockReleaseHelper->isSlmLimitationTo96KNeededResult = true;
3006+
3007+
DrmMockAlwaysFail drm(*executionEnvironment->rootDeviceEnvironments[0]);
3008+
executionEnvironment->rootDeviceEnvironments[0]->releaseHelper = std::move(mockReleaseHelper);
3009+
3010+
auto result = drm.createDrmContext(1, false, false);
3011+
EXPECT_EQ(-1, result);
3012+
EXPECT_EQ(2, drm.contextCreateCallCount); // initial + 1 retry without SlmLimit
3013+
}
3014+
3015+
TEST(DrmTest, givenContextCreateSucceedsOnFirstTryThenNoRetry) {
3016+
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
3017+
DrmMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
3018+
3019+
auto mockReleaseHelper = std::make_unique<MockReleaseHelper>();
3020+
mockReleaseHelper->isSlmLimitationTo96KNeededResult = true;
3021+
executionEnvironment->rootDeviceEnvironments[0]->releaseHelper = std::move(mockReleaseHelper);
3022+
3023+
drm.storedRetVal = 0;
3024+
auto result = drm.createDrmContext(1, false, false);
3025+
EXPECT_GE(result, 0);
3026+
EXPECT_EQ(1, drm.ioctlCount.contextCreate.load());
3027+
}
3028+
3029+
TEST(DrmTest, givenNoSlmLimitExtensionWhenContextCreateFailsThenNoRetryAndReturnError) {
3030+
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
3031+
3032+
class DrmMockAlwaysFail : public DrmMock {
3033+
public:
3034+
using DrmMock::DrmMock;
3035+
3036+
int ioctl(DrmIoctl request, void *arg) override {
3037+
if (request == DrmIoctl::gemContextCreateExt) {
3038+
ioctlCount.contextCreate++;
3039+
return -1;
3040+
}
3041+
return DrmMock::ioctl(request, arg);
3042+
}
3043+
};
3044+
3045+
DrmMockAlwaysFail drm(*executionEnvironment->rootDeviceEnvironments[0]);
3046+
// no release helper -> no SLM limit extension -> no retry possible
3047+
auto result = drm.createDrmContext(1, false, false);
3048+
EXPECT_EQ(-1, result);
3049+
EXPECT_EQ(1, drm.ioctlCount.contextCreate.load());
3050+
}
3051+
3052+
TEST(DrmTest, givenSetSlmLimitTo96KContextParamThenCorrectValuesAreSet) {
3053+
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
3054+
DrmMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
3055+
3056+
GemContextCreateExtSetParam extSetparam = {};
3057+
drm.ioctlHelper->setSlmLimitTo96KContextParam(extSetparam);
3058+
3059+
EXPECT_EQ(static_cast<uint32_t>(I915_CONTEXT_CREATE_EXT_SETPARAM), extSetparam.base.name);
3060+
EXPECT_EQ(static_cast<uint64_t>(I915_CONTEXT_PARAM_WA_22013059131), extSetparam.param.param);
3061+
EXPECT_EQ(1u, extSetparam.param.value);
3062+
}

shared/test/unit_test/release_helper/release_helper_12_55_tests.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,7 @@ TEST_F(ReleaseHelper1255Tests, whenIsSingleDispatchRequiredForMultiCCSCalledThen
140140
TEST_F(ReleaseHelper1255Tests, whenIsStateCacheInvalidationWaRequiredCalledThenFalseReturned) {
141141
whenIsStateCacheInvalidationWaRequiredCalledThenFalseReturned();
142142
}
143+
144+
TEST_F(ReleaseHelper1255Tests, whenIsSlmLimitationTo96KNeededCalledThenFalseReturned) {
145+
whenIsSlmLimitationTo96KNeededCalledThenFalseReturned();
146+
}

0 commit comments

Comments
 (0)